How can i make a Skill tree?

Hi! I’m vrs2210, I want to make my first ever RPG with a skill tree but I just can’t figure out how to do it, can anybody help me?

I’ve tried doing this my own way but it didn’t work at all.

6 Likes

I do not understand what you mean by ‘Skill tree’, do you have any example of what it is?

This is what im referring to.

2 Likes

I found a tutorial, check it out and see if it works for you

Otherwise, one way you can utilize an object-oriented programming structure(OOP) for a skill structure as this post suggests.

I prefer using @Kironte OOP template which you can structure a skill object like this:

-- Initialize Object Class
local Package = script:FindFirstAncestorOfClass("Folder")
local Object = require(Package.BaseRedirect)

local Skill = Object.new("Skill")

function Skill.new(Name,UnlockCost,Requirements)
	local obj = Skill:make()
    
    --Create a table to store what previous skill objects are required
    obj.Requirements = Requirements

    obj.UnlockCost = UnlockCost

    obj.Name = Name

    obj.IsUnlocked = false

	return obj
end

--Function for a skill object
--Checks through the objects within the Skill's Requirement table unlocked property
--If a single skill is not unlocked yet then the check fails
function Skill:CheckRequirementsAndUnlock()

    local allPreviousSkillsUnlocked = true

    for _ , PreviousSkillsRequired in pairs(self.Requirements) do

        if not PreviousSkillsRequired.IsUnlocked then
            allPreviousSkillsUnlocked = false
        end

    end

    if allPreviousSkillsUnlocked then

        --Do stuff now that it has been confirmed that the
-- previous skills are all unlocked

    end

end
return Skill

Overall, the question is pretty abstract and there are plenty of better ways to do a skill system it’s best to plan it out first what a skill object needs one by one like so:

Skill object will need:

  1. Prerequisite skills what skills you will need before unlocking this one

  2. Unlock conditions/costs

  3. Method to tell GUI that the skill is unlocked and change GUI as so

  4. Method to give the player the actual ability/stats bonus

And then you can spice it up by working with skill inheritance so you can make different types of skills like:

  1. Passive stats skill just gives flat out stat bonuses

  2. Active skills that handle the player actions in the world.

fundamentally skills trees are just an extensive boolean check. I don’t think I explained well so please ask me more questions on whatever I just wrote.

6 Likes

Thanks, this is just what i needed!

1 Like

Oh and one question, how do i use the Skill.new?

Good question, you can use the objects in a server script to tell the server how to handle skill objects and the associating logic.

First, you would need to require the module script, I would do it like so:

--Points to the module script in the workspace
local SkillPointer = ReplicatedStorage.Source.ObjectFolder.SkillObject
local SkillObject = require(SkillPointer)

Using the example script I gave I would initialize the first skill object which would be the start of a skill tree, let’s call it some weird name:

local Name = "XXx_SlayerHunting_xXX"
local HuntingSkill = SkillObject.new(Name)

Then you would create another skill that is up the skill tree lets call it beast slaying

local Name = "BeastSlayingSkill"
--Random units could represent exp in a game
local BeastSlayingUnlockExpCost = 10000
--Skills required before unlocking this new skill
local SkillsRequiredTable = {HuntingSkill}
local BeastSlayingSkill = SkillObject.new(Name,BeastSlayingUnlockCost,SkillsRequiredTable)

Then lets take an example usage of a skill tree usage in a GUI, where we unlock a button, this would be the pseudo-code required that uses an object-oriented style fancy thing

--Probably use a remote event
some gui on button press on the beast slaying skill unlock event do this(

--Event should return the player who is trying to unlock the skill
function(Player)

    --Player is the person who clicked the skill unlock button
    
    --Checks if the player has the previous skill object
    BeastSlayingSkill:CheckRequirementsAndUnlockForPlayer(Player)

    --Gives the player the skill
    BeastSlayingSkill:GivePlayerAbility(Player)
    
end)

Now that this general concept is written you can further improve and generalize it. I hope this helps with object-oriented programming.

Edit: Within the object for the unlock, you can implement a data store check,

I recommend looking at this tutorial, for ideas.

Edit: Hmm after some researching I found an skill tree libary GUI made using React, a java script libary for making UI.

Perhaps you can replicate it in Roblox using Roact instead?

5 Likes

I need help again, I know I didn’t replay for a while but that is because I was away for a while, but can you show another example of two skills instead of only one if that is fine?

Sure, here is the revamped skill object with some revamped and fixed logic checks to see if the previous skills are unlocked.

BTW, you can make your own object using metatables it’s up to you.

Revamped skill object using Kironte's OOP base class
-- Initialize Object Class
local Package = script:FindFirstAncestorOfClass("Folder")
local Object = require(Package.BaseRedirect)

local Skill = Object.new("Skill")

function Skill.new(Name, SkillRequirements)
	local obj = Skill:make()
    
    --Create a table to store what previous skill objects are required
    if SkillRequirements then
        obj.SkillRequirements = SkillRequirements
    else
        --empty table = no requirements
        obj.SkillRequirements = {}
    end

    obj.Name = Name

    obj.IsUnlocked = false

	return obj
end

--Function for a skill object
--Checks through the objects within the Skill's Requirement table unlocked property
--If a single skill is not unlocked yet then the check fails
function Skill:CheckRequirementsAndUnlock()

    local allPreviousSkillsUnlocked = true

    local neededSkillsToUnlock = {}

    for _ , PreviousSkillsRequired in pairs(self.SkillRequirements) do

        if not PreviousSkillsRequired.IsUnlocked then
            allPreviousSkillsUnlocked = false
            neededSkillsToUnlock[#neededSkillsToUnlock+1] = PreviousSkillsRequired
        end

    end

    if allPreviousSkillsUnlocked then
        print(self.Name.." is unlocked!")
        self.IsUnlocked = true
    else
        print("Sorry bud you are missing a requirement")
        for i,v in pairs(neededSkillsToUnlock) do
            print("Skill missing: "..v.Name)
        end
    end

end
return Skill
Server script to test the boolean logic
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local SkillPointer = ReplicatedStorage:FindFirstChild("Skill",true)

local Skill = require(SkillPointer)

--Construct the skills required and hence the skill tree

local swordSkill = Skill.new("SwordSkill")

local agilitySkill = Skill.new("agilitySkill")

local dualWieldingSkill = Skill.new("dualWieldingSkill",{agilitySkill,swordSkill})

--Manually ask the server to try unlocking it

print("I want this dual wielding skill: ")

dualWieldingSkill:CheckRequirementsAndUnlock()

print("")

print("OOF failed gotta unlock sword skill first: ")

swordSkill:CheckRequirementsAndUnlock()

dualWieldingSkill:CheckRequirementsAndUnlock()

print("")

print("OOF forgot to unlock agility skill: ")

agilitySkill:CheckRequirementsAndUnlock()

print("")

print("Fina can unlock dual wielding epic gamer style: ")

dualWieldingSkill:CheckRequirementsAndUnlock()

Resulting print statements using OOP

SkillTreeLogicPrint

To build upon this I believe one would need to make it player specific to see well who has unlocked this skill which would need to be an additional variable to check and see.

9 Likes

Thanks, this helped a lot :slight_smile:

Hey make sure to mark it as solved if this fixed your issue.

Also… shouldn’t this go into the building category? Haha… get it… cause it’s a skill tree…? Ehhh…

5 Likes

Bumping this but for a more indepth answer that is visually intuitive to see, I recommend looking at @nicemike40 solution for a different yet same problem, also uses OOP but more generalized as vertices and such:

3 Likes