Going about adding stats

This is just a question, how would you go about adding like stats? What i mean by this is adding stat levels like strength or agility or wisdom based on walking or hitting or talking or somthing.

Im just getting into lua and id like to figure out how to do this, any suggestions?

Since you are starting lua, you should start with simple things, like network variables. Basically, all a network variable is a variable that is stored with that player until he leaves. They don’t save and not the best for manipulating a lot at once, but you get the idea of stats. For example, you have someone join the server and spawn. Maybe have something like:
[lua]
function GM:InitialSpawn( ply )
ply:SetNWInt(“HandtoHand”, 1) //sets a variable “HandtoHand” to 1
end
[/lua]
All this does is when a player first spawns in the server, it sets the HandtoHand variable of that player to 1.
So then maybe have a weapon that if it hits a person, it would increase that variable. Then have the damage done be dependent on that variable.
Maybe something like:
[lua]
function SWEP:PrimaryAttack()
local h2hskill = self.Owner():GetNWInt(“HandtoHand”) //sets the local variable h2hskill to the player’s value, for convenience
self.Owner():SetNWInt(“HandtoHand”, h2hskill + 1) //adds 1 to the value
print(“Your Hand to Hand level is now “… self.Owner():GetNWInt(“HandtoHand”)…”.”) // prints the value to the owner
end
[/lua]
Like I said, might not be the best option in the long run for storage and such, but you get the idea.

Thank you, this gives me something to work with. Your probably right, that i should move towards more basic lua but ill refer to this in the future.

No.
NWVars are the worst thing you can do.

How would you go about doing something like this? With sql? im not sure how lua interacts with sql but i know how php does and its quite simple.

I always hear NWVars is the worst thing. But what is our alternative?
I would really like to learn the “Better” way.

NWVars are updated to every single client in the server. I don’t think every single client needs to know about one guy’s stat.

Put in player’s table (ply.HandToHand = 1)
Usermessage!

Don’t know if that’s considered THE appropriate way though.

[lua]local Player = FindMetaTable(“Player”)
local initialStats = {
Strength = 10,
Dexterity = 10,
Charisma = 0,
Intelligence = 20
}

if SERVER then
– table with weak keys so stat tables are garbage collected
local stats = setmetatable({}, {__mode=‘k’})
function Player:SetStat(sName, iValue)
stats[self][sName] = iValue
umsg.Start(“StatUpdate”, self)
umsg.String(sName)
– depends on your maximum value for a stat
– Char gives -128 to 127
umsg.Char(iValue)
umsg.End()
end
function Player:GetStat(sName)
return stats[self][sName]
end

hook.Add("InitialSpawn", function(pl)
    stats[pl] = table.Copy(initialStats)
end)

else – client
local stats = table.Copy(initialStats)
usermessage.Hook(“StatUpdate”, function(um)
stats[um:ReadString()] = um:ReadChar()
end)
function Player:GetStat(sName)
if self ~= LocalPlayer() then
error("Can only GetStat of LocalPlayer
", 2)
end
return stats[sName]
end
function Player:SetStat()
error("Stats cannot be set Clientside
", 2)
end
end[/lua]
Strictly speaking GetStat on the client doesn’t have to go in the Player metatable, however it seems neater to me.
This implementation also protects the stat tables from meddling.
There’s also other stuff you could do, like having Stat objects with stuff like a Stat ID, so you don’t have to send strings to the Client. This will then need a lookup function so you can get the Stat object back from the ID.
Instead of a Stat being a string with an associated value, the Stat will be an object with many attributes, such as a maximum value, a minimum value, a name string and a description string.
You could then verify whether the stat changes are valid, first a Stat like that has to exist and second its value has to be within its valid range.

Wow, I think I see why people use NWVars instead. its going to take me while to hook something like that up to a MySQL.

Thanks for the revolution!

I’ve probably overcomplicated it.
[lua]local Player = FindMetaTable(“Player”)
local initialStats = {
Strength = 10,
Dexterity = 10,
Charisma = 0,
Intelligence = 20
}

if SERVER then
function Player:SetStat(sName, iValue)
self[sName] = iValue
umsg.Start(“StatUpdate”, self)
umsg.String(sName)
– depends on your maximum value for a stat
– Char gives -128 to 127
umsg.Char(iValue)
umsg.End()
end

hook.Add("InitialSpawn", function(pl)
    for k,v in pairs(initialStats) do
        pl[k] = v
    end
end)

else – client
usermessage.Hook(“StatUpdate”, function(um)
LocalPlayer()[um:ReadString()] = um:ReadChar()
end)
end[/lua]
This will work the same provided you’re ok with doing Player.Strength instead of Player:GetStat(“Strength”).
The SetStat function is necessary though as you want to update the values of stats clientside when they change rather than periodically.
Networked Variables are probably a lot easier to start with however.
There is a handy function you might find useful if you’d prefer to do Player:GetStrength() rather than Player:GetNetworkedInt(“Strength”).
**[G.AccessorFuncNW

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=G.AccessorFuncNW)**
Example:
[lua]
AccessorFuncNW(FindMetaTable(“Player”), “strength”, “Strength”, 0, FORCE_NUMBER)
– now you can do stuff like this
LocalPlayer():GetStrength()
[/lua]

Hmm, I will have to mess with this. Anything that reduces the lag, Is a friend of mine!

Thanks for the explanation.

Thanks for the replys and all the help guys, i really appreciate it!