Saving and executing values [Point me in the right direction]

I’ve been quite bored today, so i decided to jump in gmod and do something fun. I’ve basically made this NPC that gives you an AWP and sets it’s damage to something random (from 2000 to 5000). My question is, how would i go about saving that damage value and then when the player rejoins, he/she get’s that same awp with the same damage value back?


You could use PData, MySQL or files.

For PData:
PLAYER:SetPData() and PLAYER:GetPData()

For MySQL, use MySQLoo or tmysql4. Never used it myself.

For files:
file.Read() and file.Write() / file.Append()

Thanks a bunch for your reply. Which one would be the easiest for someone that is pretty new to lua?

PData tends to be pretty simple imo.

Alright. Got the saving of the damage working. Now i just need to figure out the part where it actually gives the player the awp with the same damage value back when he/she joins.

Edit Well, so I’m stuck at the part where it reads the value and then gives the awp. Could someone please take a look? This is my code:

Ok, WhenPlayerJoins, ( should be PlayerLoadout when they receive weapons, etc… ), Read the file, interpret the damage, tonumber it if need be. Next, for that specific weapon entity, set the primary damage. ( all needs to be done on server ). Then, as long as the bullet that is spawned by the base uses the damage from that variable, it’ll work.

Other stuff:

And, if you ever decide to not use PData but have already started using it:

Basic system to go through one table in the SQLite database and turn it into MySQL insert statements. There may be more tables, with different columns… I did one as an example, I’d recommend gathering all info and organizing it into a structure before generating the insert queries…

If you use FireFox, download SQLite Manager so you can manage your SQLite sv.db database for the server.

Using MySQL means you’ll need to get used to using callbacks as you won’t be able to return a value because the MySQL takes time to grab the data and return it, meaning the pointer has already moved on and a return would be pointless.

Anyway, using a file to save data, it may be easier for you to save using util.TableToJSON( ), then when you read it:

// The || "{ }" means if file can't be read, or file.txt is empty then use a string { } which is an empty JSON table. _table then becomes either empty table or populated table.
local _data = file.Read( "file.txt", "DATA" );
local _table = util.JSONToTable( ( !file.Read( "file.txt", "DATA" ) || string.Trim( _data ) == "" ) && _data || "{ }" );

// Incrementing filenames

… If you do use flatfile / txts, I’d recommend saving via steamid…

// All non alpha-numeric characters become _ - Josh 'Acecool' Moser
function text )
	text = string.gsub( text, "%W", "_" );
	return text;

Turns STEAM_0:1:1234 into STEAM_0_1_1234 making it stay essentially the same, easy to identify for each player, etc…

Thanks a bunch for your help.

Do tonumber( _data ) not tonumber( “_data” )

Oh gosh, that was a simple fix :stuck_out_tongue: Thanks for your reply. Now i just need to figure out so everyone doesn’t get the same AWP. Like so it creates different txt files for each player.

file.Write( “playerData_” … ply:UniqueID() ) ?

Shouldn’t this work?

file.Write( "playerData_" .. ply:UniqueID() .. ply:GetWeapon("weapon_real_cs_awp").Primary.Damage)

Also, doesn’t that just put their unique id inside the txt file?

No, file.Write takes 2 arguments, a name, and the contents. See here: needs to be done is: file.Write( “folder/playerData_” … ply:UniqueID(), ply:GetWeapon(“weapon_real_cs_awp”).Primary.Damage)

I put them in a folder so they don’t get mixed in with other files.

… is used to concancenate ( combine ) two strings.

I didn’t include the second argument, which would be the AWP’s damage value.

file.Write( filename, data )
file.Write( “playerData” … ply:UniqueID(), ply:GetWeapon( “weapon_real_cs_awp” ).Primary.Damage )


From the wiki:

file.Write( string fileName, string content )

So AceCool & HumbleTH’s saving methods just add the player’s ID to the file NAME, where the content is still


So you were quite close. It would actually be:

file.Write( "playerData_" .. ply:UniqueID(),  ply:GetWeapon("weapon_real_cs_awp").Primary.Damage)

Whoops. Late.

When i do this:

file.Write( "savedplayerdata.txt" .. ply:UniqueID(), ply:GetWeapon("weapon_real_cs_awp").Primary.Damage)

The file doesn’t even get created. How can i do so it makes one txt file for each player?

file.Write( "savedplayerdata" .. ply:UniqueID() .. ".txt", ply:GetWeapon("weapon_real_cs_awp").Primary.Damage)

file.Write( "examplefolder/" .. ply:UniqueID().. ".txt", ply:GetWeapon("weapon_real_cs_awp").Primary.Damage)

I recommend putting them in a separate folder so they are not mixed in with other data.

However, I would recommend using the SteamID instead of their UniqueID.

Yeah, UniqueID does take time to compute.

Alrighty! Was getting so confused. Now everything works like it should. Thanks a lot everyone!