#Better ways to do stat system?

1 messages · Page 1 of 1 (latest)

flint glade
#

Currently, I'm bugfixing my current system, but I would like to know of more ways to potentially fix the issues mine has. Note: I have done absolutely 0 research on better ways, I would just like to know what your all's best systems are. And how you approach them

#
local StatManager = {}

--A
local Class = script.Parent:FindFirstChild("Class")
local Race = script.Parent:FindFirstChild("Race")
local Level = script.Parent:FindFirstChild("Level")
--B
--Weapon
--Armor
--C
--Effect_Flat

--["Stat"] = {A, B, C, Effect}
local Defaults = {
    ["HP"] = {0,0,0,0},
    ["MP"] = {0,0,0,0},
    ["ATK"] = {0,0,0,0},
    ["AP"] = {0,0,0,0},
    ["DEF"] = {0,0,0,0},
    ["SPD"] = {0,0,0,0},
    ["VIT"] = {0,0,0,0},
    ["WIS"] = {0,0,0,0},
    ["CRT"] = {0,0,0,0},
    ["CRD"] = {0,0,0,0},
    ["FDEF"] = {0,0,0,0},
    ["WDEF"] = {0,0,0,0},
    ["EDEF"] = {0,0,0,0},
    ["ADEF"] = {0,0,0,0},
    ["FBST"] = {0,0,0,0},
    ["WBST"] = {0,0,0,0},
    ["EBST"] = {0,0,0,0},
    ["ABST"] = {0,0,0,0},
    ["JPOWER"] = {0,0,0,0},
    ["HEALIN"] = {0,0,0,0},
    ["HEALOUT"] = {0,0,0,0}}

local Defaults_Level = {
    ["HP"] = {1},
    ["MP"] = {1},
    ["ATK"] = {1},
    ["AP"] = {1},
    ["DEF"] = {1},
    ["SPD"] = {1},
    ["VIT"] = {1},
    ["WIS"] = {1}}

local All_Stats = {
    ["HP"] = {0},
    ["MP"] = {0},
    ["ATK"] = {0},
    ["AP"] = {0},
    ["DEF"] = {0},
    ["SPD"] = {0},
    ["VIT"] = {0},
    ["WIS"] = {0},
    ["CRT"] = {0},
    ["CRD"] = {0},
    ["FDEF"] = {0},
    ["WDEF"] = {0},
    ["EDEF"] = {0},
    ["ADEF"] = {0},
    ["FBST"] = {0},
    ["WBST"] = {0},
    ["EBST"] = {0},
    ["ABST"] = {0},
    ["JPOWER"] = {0},
    ["HEALIN"] = {0},
    ["HEALOUT"] = {0}
}```
#

local All_Stats = Defaults
local All_Stats_Base = {Base = {Defaults}}

function StatManager.ResetDefault()
    Defaults ={ ["HP"] = {0,0,0,0},    ["MP"] = {0,0,0,0},    ["ATK"] = {0,0,0,0},    ["AP"] = {0,0,0,0},    ["DEF"] = {0,0,0,0},    ["SPD"] = {0,0,0,0},    ["VIT"] = {0,0,0,0},    ["WIS"] = {0,0,0,0},    ["CRT"] = {0,0,0,0},    ["CRD"] = {0,0,0,0},    ["FDEF"] = {0,0,0,0},    ["WDEF"] = {0,0,0,0},    ["EDEF"] = {0,0,0,0},    ["ADEF"] = {0,0,0,0},    ["FBST"] = {0,0,0,0},    ["WBST"] = {0,0,0,0},    ["EBST"] = {0,0,0,0},    ["ABST"] = {0,0,0,0},    ["JPOWER"] = {0,0,0,0},    ["HEALIN"] = {0,0,0,0},    ["HEALOUT"] = {0,0,0,0}}
    Defaults_Level = {    ["HP"] = {1},        ["MP"] = {1},        ["ATK"] = {1},        ["AP"] = {1},        ["DEF"] = {1},        ["SPD"] = {1},        ["VIT"] = {1},        ["WIS"] = {1}}
    All_Stats_Base = Defaults
end

function StatManager.Level_Base_Stats()
    local Level_Effect = {}
    local Level = script.Parent:FindFirstChild("Level").Value
    --print(Level)
    --print(Defaults_Level)
    for i, v in pairs(Defaults_Level) do
        local stat = Defaults_Level[i][1]
        stat = stat*Level
        Defaults_Level[i][1] = stat

        Level_Effect = Defaults_Level
    end
end
#

function StatManager.Recal_Race()
    local Races = require(game.ServerScriptService.PlayerStat.Races)
    local Race = script.Parent:FindFirstChild("Race")
    local Player_Race_Stats = Races.Stats_Apply(Race.Value)
    local Player_Race_Scaling = Races.Stat_Scaling(Race.Value)
    local Level = script.Parent:FindFirstChild("Level").Value
    
    local function Scaling()
        for i, v in pairs(Player_Race_Scaling) do
            if i % 2 ~= 0 then
                local stat = tostring(v)
                local Scaling_Number = Player_Race_Scaling[i+1]
                
                Defaults[stat][1] = Defaults[stat][1] + (Scaling_Number * Level)
            end
        end
    end
    
    Scaling()
    
    for i, v in pairs(Player_Race_Stats) do
        if i % 2 == 1 then
            local Stat_Name = v
            local stat = tostring(v)
            local Stat_Increase = Player_Race_Stats[(i+1)]
            local Scaling_Number = Player_Race_Stats[i+1]
            local Base_Stat = Defaults[tostring(Stat_Name)][1]
            
            Base_Stat += Stat_Increase
            Defaults[tostring(Stat_Name)][1] = Base_Stat
        end
    end
end```
#

function StatManager.Recal_Class()
    local Classes = require(game.ServerScriptService.PlayerStat.Classes)
    local Class = script.Parent:FindFirstChild("Class")
    
    local function Scaling()
        local Player_Class_Stats_Scaling = Classes.Stats_Scaling(Class.Value)
        local Level = script.Parent:FindFirstChild("Level").Value
        for i, v in pairs(Player_Class_Stats_Scaling) do
            local stat = tostring(i)
            local Scaling_Stats = Player_Class_Stats_Scaling[stat]
            Defaults[tostring(i)][1] = Defaults[tostring(i)][1] + (Scaling_Stats * Level)
        end
    end
    
    Scaling()
    
    local Player_Class_Stats = Classes.Stats(Class.Value)
    local Class_Effect = {}

    for i, v in pairs(Player_Class_Stats) do
        local Stat_Increase = v
        local Base_Stat = Defaults[tostring(i)][1]
        Base_Stat += Stat_Increase
        Defaults[tostring(i)][1] = Base_Stat
        Class_Effect = Defaults
    end
end```
#
function StatManager.Recal_Level()
    local Level = script.Parent:FindFirstChild("Level")
    local Level_Base = StatManager.Level_Base_Stats()
    local Level_Effect = {}
    for i, v in pairs(Defaults_Level) do
        local Stat_Increase = Defaults_Level[i][1]
        Defaults[i][1] = Defaults[i][1] + Stat_Increase
        local stat = tostring(i)
        print(stat .. " Changed from " .. Defaults[stat][1] .. " to " .. Defaults[stat][1] + Stat_Increase)
    end
end

function StatManager.Recalculate_Base()
    StatManager.ResetDefault()
    
    local race = StatManager.Recal_Race()
    local class = StatManager.Recal_Class()
    local level = StatManager.Recal_Level()

    All_Stats_Base = Defaults
    print(All_Stats_Base)
    return All_Stats_Base
end

#
function StatManager.Calculate_Base_Effect()
    for i, v in pairs(Defaults) do
        local stat = i
        local base = v[1]
        local equip = v[2]
        local flat = v[3]
        local multiplier = 1 + v[4]
        
        All_Stats[i] = (base + equip + flat) * (1 + multiplier)
    end
end

function StatManager.Player_Stats()
    StatManager.Calculate_Base_Effect()

    local plr_Name = script.Parent:FindFirstChild("Player_Name").Value
    local plr = game.Players:FindFirstChild(tostring(plr_Name))
    local chr = plr.Character
    
    --Stats
    local SPD = tonumber(All_Stats["SPD"])
    local HP = tonumber(All_Stats["HP"])
    local Jump_Power = tonumber(All_Stats["JPOWER"])
    
    --Update Player
    local Hmd = chr:FindFirstChild("Humanoid")
    Hmd.WalkSpeed = 10 + SPD
    
    Hmd.MaxHealth = 50 + (2.5 * HP)
    Hmd.JumpPower = 50 + (2.5 * Jump_Power)
    print(Defaults["ATK"])
    print(Defaults["AP"])
    return All_Stats
end
#

function StatManager.Add_Effect(stat, stat_Number, style)
    local styles = {
        [1] = function()
            Defaults[tostring(stat)][4] += stat_Number
        end,
        [2] = function()
            print(Defaults[tostring(stat)])
            Defaults[tostring(stat)][2] += stat_Number
        end,
    }
    print(stat, stat_Number, style)
    styles[style]()
    StatManager.Player_Stats()
end


return StatManager```
lime egret
#

I'd really try to hone in on readability or at the very least placing comments to help someone who hasn't read it before follow it logically

south flare
#

im trying to digest his code right now

#

but yes readability goes a long way

flint glade
#

xd

#

to be honest I read it very cleanly

#

but I could place comments here and there if it's too hard for you to read it

#

I'm pretty sure no one else is going to be reading my code for the most part since no one else is helping me with the scripting for the project

#

:(

south flare
#

just place a comment before every new function about what you want it to do

flint glade
south flare
#

also are these connected to datastore yet

flint glade
#

no

south flare
#

because having to have to save this stats will change how you will approach this system immensely

flint glade
#

Im only datastoring the player's classes they own, their active class, race, level, inventory, and what they have equipped

#

I'm recreating their stats when they join.

south flare
#

you know this system might benefit from metatables since you have many different player classes

#

brb

#

going to construct

flint glade
#

??

#

i just do it like this

#

why does the player ever need to know their own stats

#

the server should only present its information

south flare
#

i mean arent you saving the stats already in datastore

#

race level inventory etc.

#

anyways ill create a small system and present it to you

flint glade
#

The thing is, it's easier to save a small # of things in a datastore, than more, for an unnecessary amount of times I'd constantly refer to it

#

What would a metatable even do in this case.

south flare
#

yea youll be saving the same thing

#

with less headache

#

brb

flint glade
#

._ .

#

sounds like more of a headache to me, if im doing the exact same thing, but it's less readable

south flare
#

lemem cook brb

#

im starting with your defaults

#

ok before i continue is this pretty much how you want your stats to look like at its core

#

and why do you have defaults level for each of the stats

#

is this how you scale things

#

not based on the player's level

#

@flint glade

flint glade
#

dah hell

flint glade
south flare
#

then what is this

flint glade
#

I multiply that by the level to get the stat increase.

#

LevelxLevelStats + LevelxClassScaling + ClassBase + LevelxRaceScaling + RaceBase

south flare
#

ok then i just simply adjust my script to this

flint glade
#

uhhuh.

#

And what if you were to change your class, how do you accurately remove those stats without needing to require the same script twice.

#

You're recommending me methods that aren't faster, not more readable.

#

Actually I'd say it's generally the same thing

south flare
#

yes im not done yet im just trying to know what your initial defaults are atm

#

now we can cook

#

also isnt default not meant to be changed or removed. thats why you just refer to it when you need to give a player their default stats or reset their stats

flint glade
#

hence:

south flare
#

yes now we dont need allat. We just now need the equation and sht

#

brb

flint glade
#

??

#

So

#

I would need to add a function to add, and then a new function to remove the specific stat.

#

and call that repeatedly, the second the player changes in race, level, or class

#

?

south flare
#

no need

#

just set their stats to default

#

Player.Stats = Default.PlayerStats

flint glade
#

??

#

Nope

#

That's even more confusing

#

and has 0 readability to me

#

Not to mention, it would break a large amount of code, now, and in the future.

#

It seems to me like it's more or less not the better way to handle it, but rather, just your own method of doing stats :T

south flare
#

wym would break a large amount of code

flint glade
#

There's a reason why I separate stats into 4 pieces

south flare
#

look now the first part of your script is simplified to jsut this

#

wihout iterating each time

#

now lets say

#

we want to give player their new stats

#

brb

south flare
#

there youll still save the same amount

#

now when the player joins you just give them their calculatedStats or defaultStats

south flare
#

if you want to instead use a metatable to reuse the functions. This will allow you to not need to require each time you want to access the module script or default table.

flint glade
#

Im

#

probably gonna just

#

look at my code

#

and see if I can clean it myself

#

cause while I appreciate you trying to find an alternative way to doin it. I think what I'm doing helps fixes things as well

south flare
#

👍

lime egret
#

At the very least I think instead of just having numbers in indices you can setup your tables like dictionaries so they're easier to understand at a glance

flint glade
#

?

flint glade
#

i mean

#

ig

#

I will say that I kind of store everything in my head when it comes to code like that. I auto read with the dictionary, if that makes sense. Or the 'key'

lime egret
#

That's fair, but your head won't be reliable after you come back to read the code 2 years later

flint glade
#

funnily enough

#

no

#

I remember every single one of these game ideas, in detail.

#

hell, i even remember the work I did on the ones I did try and make

south flare
#

guess the bug will remain hidden.

flint glade
#

what bug

south flare
#

😛

#

anyways your tables is making simple system become more complex than it should be

#

with no added benefits

flint glade
#

Yours doesnt have any added benefits either?

south flare
#

the point is it shouldnt be harder than what it should be

#

but if it works for you then awesome. But if you are planning on getting help or working on a team then a sacrifice must be made

flint glade
#

I think if anything, it's more so that it's just hard for other people to read.

#

and I'm pretty sure that's just my unfortunate programming style.

#

I dont leave that many comments because I store what I write like a translation, rather than the language itself :P

south flare
#

i dont mind the comments so much if the code itself presents to be readable

#

but if so much magic going on then its just even more harder to follow the logic without the comment aswell

gusty depot
#

if u can i would try n use attributes inside of folders

#

so say theres like a wolf man character class or something

#

i would store all the attributes related to that inside of that folder that stores the wolf man character assets

#

trying to use attributes whereever possible

#

same goes with armor n what not

#

but i dont know if it will work for u..

#

i think trying to revolve almost all ur data on attributes is a nice way to keep things organized but it depends on ur usecases

flint glade
#

In the future when I make my NPCs I will probably use multiple attributes for their unique behaviours

gusty depot
flint glade
#

Sure

gusty depot
#

yeah having to look at a bunch of squiggly lines n numbers n commas n text thats colored behind a black screen