Jump to content

[TUTORIAL] Add a skillset / skilltree to a modded character.


Lyraedan
 Share

Recommended Posts

Hello, I'm going to show and provide code on how to setup a skilltree / skillset for your modded character in Don't Starve Together.

I'll try and make this as simple as possible.
Prerequisites

Spoiler

You'll need some prerequisite software

  • Some kind of LUA IDE
    • You use this to program your mod. Notepad++, VS Code etc
  • Texture at Atlas Packer: 
    • You use this to generate the atlas for the skilltree and icons
  • TexTool: https://github.com/zxcvbnm3057/dont-starve-tools
    • Used to view and create .tex files
  • Image editing software
    • I personally use Paint.Net but Gimp and others would work also.

This tutorial is assuming you have basic experience with these pieces of software

 

Registering the skilltree

Spoiler

To get a skilltree to register its relatively straight forward, place this code in your modmain.lua somewhere before "AddModCharacter"

-- Skilltree
local SkillTreeDefs = require("prefabs/skilltree_defs")

-- Replace "luke" with your character prefab name
local CreateSkillTree = function()
	print("Creating a skilltree for Luke")
	local BuildSkillsData = require("prefabs/skilltree_luke") -- Load in the skilltree

    if BuildSkillsData then
        local data = BuildSkillsData(SkillTreeDefs.FN)

        if data then
            SkillTreeDefs.CreateSkillTreeFor("luke", data.SKILLS)
            SkillTreeDefs.SKILLTREE_ORDERS["luke"] = data.ORDERS
			print("Created Lukes skilltree")
        end
    end
end
CreateSkillTree();

-- Skilltree end

in this example we are using my character "luke" you'd replace that with your characters prefab name, also I'm going to attach both lukes,  wilsons and woodies skilltrees to this post so you can see and get an idea on how skilltrees work.

If there was any misconfiguration with your skilltree an error will throw during CreateSkillTreeFor that starts with "FIX ME:..."

If all the passes complete you'll see your console log of "Created x's skilltree" in logs.

 

Importing the skilltree into your character prefab

Spoiler

Now, head into your character prefab script.

Inside your assets definition add a new line to import your skilltree. In my case for Luke

local assets = {
  	-- Other assets
	Asset("SCRIPT", "scripts/prefabs/skilltree_luke.lua")
}

 

 

Creating your skilltree file

Spoiler

Look at how Wilson and Woodie configure their skilltrees.

In your own skill tree You define the "tabs" of the skilltree in the Skills definition and the orders are defined as "{ group, { x, y }}"

local ORDERS =
{
    {"intimidating",           { -214+18   , 176 + 30 }},
    {"unintimidating",         { -62       , 176 + 30 }}
}

--------------------------------------------------------------------------------------------------

local function BuildSkillsData(SkillTreeFns)
    local skills = 
    {
        luke_intimidating_1 = {
            title = "Intimidating",
            desc = "Makes Luke intimidating to creatures.",
            icon = "wilson_alchemy_1",
            pos = {-62,176},
            group = "intimidating",
            tags = {"intimidating"},
            onactivate = function(inst, fromload)
                    inst:AddTag("luke_skill_intimidating")
                end,
            root = true,
            connects = {
                "luke_intimidating_2"
            },
        },

        luke_intimidating_2 = {
            title = "Murderous Aura",
            desc = "Accumalate more fear from kills",
            icon = "wilson_alchemy_gem_1",
            pos = {-62, 176-52},
            group = "intimidating",
            tags = {"intimidating"},
            onactivate = function(inst, fromload)
                inst:AddTag("luke_skill_murderousaura")
            end,
        },

        luke_unintimidating_1 = {
            title = "Unintimidating",
            desc = "Makes Luke even less intimidating",
            icon = "wilson_torch_time_1",
            pos = {-214,176},
            group = "unintimidating",
            tags = {"unintimidating"},
            onactivate = function(inst, fromload)
                inst:AddTag("luke_skill_unintimidating")
                end,
            root = true,
            connects = {
                "luke_unintimidating_2"
            }
        },

        luke_unintimidating_2 = {
            title = "Safe Aura",
            desc = "Luke gains reduced fear from kills",
            icon = "wilson_torch_time_2",
            pos = {-214, 176-38},
            group = "unintimidating",
            tags = {"unintimidating"},
            onactivate = function(inst, fromload)
                inst:AddTag("luke_skill_safeaura")
            end
        },
    }

    return {
        SKILLS = skills,
        ORDERS = ORDERS,
    }
end

--------------------------------------------------------------------------------------------------

return BuildSkillsData

That is an example that I've made for my character Luke, there are more tags such as connects and locks that can be found in Wilson and Woodie respectively.

 

Checking if a skill is active inside your character prefab

Spoiler

Because we created a skilltree earlier our character receives a skilltreeupdater component that we can use to check if skills are active.

If you want to check if a skill is activated on your character prefab inside its prefab script you can do

-- In this example we are checking if luke_intimidating_1 is active
if inst.components.skilltreeupdater:IsActivated("luke_intimidating_1") then
	-- Do stuff here
end

 

 

Setting up the skilltree widget

Spoiler

In order to setup the widget we have to override a function called GetSkillTreeBG which if left unchanged results in a nil result that crashes the game. Setting up the function like this allows the function to maintain its old functionality as well as check for your custom background. This also enables support with other mods.

Simply paste this above above the CreateSkillTree function in modmain and change "luke" to your characters name.

local OldGetSkilltreeBG = GLOBAL.GetSkilltreeBG
function GLOBAL.GetSkilltreeBG(imagename, ...)
    if imagename == "luke_background.tex" then
        return "images/luke_skilltree.xml"
    else
        return OldGetSkilltreeBG(imagename, ...)
    end
end

Credit: This GetSkilltreeBG function override was provided to me by the user @RandomBeta115 who kindly did some reaching out to the coder of the Cherry Forest mod @ADM  who very kindly gave RandomBeta permission to share it so many thanks to those two.

 

Importing the texture and atlas

Spoiler

After adding this code you can setup your skilltree graphic, right now I've taken and re-adapted Wilson's skilltree graphic (I'll attach it)

Then make sure you import the image and atlas in modmain.lua

Assets = {
	-- Your other assets
  	Asset( "IMAGE", "images/luke_skilltree.tex" ),
    Asset( "ATLAS", "images/luke_skilltree.xml" ),
}

Now when you look at your character on the character selection screen you can see the skillset button, clicking on that will show your skilltree and you can click to view each one. Heading into the game you can press the inspect button to view your skilltree there too.

 

Custom icons - WIP

Spoiler

Now onto the final step, custom icons for your skill tree.

Firstly I want to note that even though setting up icons this way works it may conflict with other mods doing the same thing OR default characters icons like Wilson, Woodie etc. It doesn't crash the game just their icons do not display. I will update this section with a workaround at a later time.

With that out the way, to do this establish how many skills you want on your tree and create an individual 64x64 image for each skills icon and place those in a folder.

Then using the Texture at Atlas Packer, select all your icon images and pack them under the name "skilltree_icons"

After this is complete place the .tex and .xml files in your mods "/images" directory.

Next import the icons in your modmain.lua

Assets = {
	-- Your other assets
	Asset( "IMAGE", "images/skilltree_icons.tex" ),
    Asset( "ATLAS", "images/skilltree_icons.xml" ),
}

Something to note is that sometimes the packer doesn't correctly name things inside your xml document so you'll need to open it up to ensure your skills element names match what you wish to call them and ensure the name ends in ".tex"

<Atlas>
	<Texture filename="skilltree_icons.tex" />
	<Elements>
		<Element name="skill_intimidating_1.tex" u1="0.001" u2="0.124" v2="0.999" v1="0.751" variant="i" />
		<Element name="skill_intimidating_10.tex" u1="0.001" u2="0.124" v2="0.249" v1="0.001" variant="i" />
		<Element name="skill_intimidating_11.tex" u1="0.126" u2="0.249" v2="0.499" v1="0.251" variant="i" />
		<Element name="skill_intimidating_12.tex" u1="0.251" u2="0.374" v2="0.499" v1="0.251" variant="i" />
		<Element name="skill_intimidating_2.tex" u1="0.126" u2="0.249" v2="0.999" v1="0.751" variant="i" />
		<Element name="skill_intimidating_3.tex" u1="0.001" u2="0.124" v2="0.749" v1="0.501" variant="i" />
		<Element name="skill_intimidating_4.tex" u1="0.126" u2="0.249" v2="0.749" v1="0.501" variant="i" />
		<Element name="skill_intimidating_5.tex" u1="0.251" u2="0.374" v2="0.999" v1="0.751" variant="i" />
		<Element name="skill_intimidating_6.tex" u1="0.251" u2="0.374" v2="0.749" v1="0.501" variant="i" />
		<Element name="skill_intimidating_7.tex" u1="0.376" u2="0.499" v2="0.999" v1="0.751" variant="i" />
		<Element name="skill_intimidating_8.tex" u1="0.376" u2="0.499" v2="0.749" v1="0.501" variant="i" />
		<Element name="skill_intimidating_9.tex" u1="0.001" u2="0.124" v2="0.499" v1="0.251" variant="i" />
		<Element name="skill_unintimidating_1.tex" u1="0.126" u2="0.249" v2="0.249" v1="0.001" variant="u" />
		<Element name="skill_unintimidating_10.tex" u1="0.501" u2="0.624" v2="0.499" v1="0.251" variant="u" />
		<Element name="skill_unintimidating_11.tex" u1="0.626" u2="0.749" v2="0.499" v1="0.251" variant="u" />
		<Element name="skill_unintimidating_12.tex" u1="0.501" u2="0.624" v2="0.249" v1="0.001" variant="u" />
		<Element name="skill_unintimidating_2.tex" u1="0.251" u2="0.374" v2="0.249" v1="0.001" variant="u" />
		<Element name="skill_unintimidating_3.tex" u1="0.376" u2="0.499" v2="0.499" v1="0.251" variant="u" />
		<Element name="skill_unintimidating_4.tex" u1="0.376" u2="0.499" v2="0.249" v1="0.001" variant="u" />
		<Element name="skill_unintimidating_5.tex" u1="0.501" u2="0.624" v2="0.999" v1="0.751" variant="u" />
		<Element name="skill_unintimidating_6.tex" u1="0.626" u2="0.749" v2="0.999" v1="0.751" variant="u" />
		<Element name="skill_unintimidating_7.tex" u1="0.501" u2="0.624" v2="0.749" v1="0.501" variant="u" />
		<Element name="skill_unintimidating_8.tex" u1="0.751" u2="0.874" v2="0.999" v1="0.751" variant="u" />
		<Element name="skill_unintimidating_9.tex" u1="0.626" u2="0.749" v2="0.749" v1="0.501" variant="u" />
	</Elements>
</Atlas>

Finally, open up your skilltree file and set the icon name so that it matches your icons element name (without .tex). Afterwards open up the game and if everything went well you're icons will be updated

image.png

 

Update (20/08/2023)

I've created a full custom skilltree for my character I'm just drawing his skill icons (I only have 5 done right now) after that is done I'll attach his files below and update any images. For now a modified version of wilsons is attached.

 

Update (07/12/2023)

I've attached a WIP version of the next update of my character mod. This example has a functional skilltree for anyone to compare against should they run into any issues. Here:.Luke_Skilltree_Example.zip

I've been very busy with life things but I will be updating this tutorial with the new Klei updates soon

skilltree_wilson.lua skilltree_woodie.lua

luke_skilltree.tex luke_skilltree.xml skilltree_luke.lua

skilltree_icons.tex skilltree_icons.xml

Edited by Lyraedan
Attached example
  • Like 10
  • Thanks 1
Link to comment
Share on other sites

Doing some testing... but it may seem that adding a custom Skill Set for a character, removes all icons for other Characters?

 

Sorry it seems you are well aware of the issue. Going to see if it is possible to just place hardcoded Icons with the Background to make fake icons.

 

Do you know how to add custom descriptions to the skill trees, and not hardcoded in the skilltree.lua itself, Rather use a speech folder for translations support.

Edited by JadeKnightblazer
Link to comment
Share on other sites

5 hours ago, JadeKnightblazer said:

Doing some testing... but it may seem that adding a custom Skill Set for a character, removes all icons for other Characters?

 

Sorry it seems you are well aware of the issue. Going to see if it is possible to just place hardcoded Icons with the Background to make fake icons.

 

Do you know how to add custom descriptions to the skill trees, and not hardcoded in the skilltree.lua itself, Rather use a speech folder for translations support.

Still looking for the way to cleanly solve the custom icon issue.

As for the custom descritpions. Assuming you mean the skill descriptions. They are defined in your custom skilltree document using the "desc" variable.

luke_intimidating_1 = {
            title = "Intimidating I",
            desc = "You gain sanity at maximum fear.",  -- Your custom description goes here
            icon = "skill_intimidating_1",
            pos = {intimidating_x, intimidating_y},
            group = "intimidating",
            tags = {"intimidating"},
            onactivate = function(inst, fromload)
                    
            end,
            root = true,
            connects = {
                "luke_intimidating_2",
            },
        },

        luke_intimidating_2 = {
            title = "Intimidating II",
            desc = "You deal much more damage at maximum fear",
            icon = "skill_intimidating_1",
            pos = {intimidating_x+60, intimidating_y},
            group = "intimidating",
            tags = {"intimidating"},
            onactivate = function(inst, fromload)
                
            end,
            connects = {
                "luke_intimidating_3"
            }
        },

        luke_intimidating_3 = {
            title = "Intimidating III",
            desc = "You gain a small amount of fear when you deal damage",
            icon = "skill_intimidating_1",
            pos = {intimidating_x+60, intimidating_y-40},
            group = "intimidating",
            tags = {"intimidating"},
            onactivate = function(inst, fromload)
                
            end
        },

Or do you mean a custom voiceline spoken by the character upon unlocking a skill?

Link to comment
Share on other sites

Meh.... still don't know the "Correct" solution to my problem, Since Global sends errors.

So I just created a new sdf_skilltree_strings.lua in my english folder, and added: require("speech/english/sdf_skilltree_strings") as a header to my skilltree_sdf prefab.

Which means I'll have to add a translation toggle to the skilltree_sdf prefab in conjunction with modmain.

Link to comment
Share on other sites

Oh and they fixed the icons issue,
using
RegisterSkilltreeIconsAtlas("images/character_skilltree_icons.xml", "icon.tex")
you can register your own skill icons
but it seems you have to do this for each of your icons

Link to comment
Share on other sites

Oooo, need to take a look.

For now I just finished my custom character Skill Set (used a bunch of icons from other Don't Starve characters, which worked well).

Thank you once again for posting the Tutorial!!!!!!!!  Have a look of what your knowledge provided---> https://steamcommunity.com/sharedfiles/filedetails/?id=2874781689

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...