Currency system.

I cannot find a good way to create a money system, could someone help?

This is the first currency system I used, it worked perfectly fine, but it used NWInt which is not efficient as it makes everything public and causes server lag.




local pm = FindMetaTable( "Player" )
	
	-- Saves and loads Credits
	function LoadStats( ply )
		ply:StatsLoad()
	end
	hook.Add("PlayerInitialSpawn", "LoadPlyStats", LoadStats)

	function SaveStats( ply )
		ply:StatsSave()
	end
	hook.Add("PlayerDisconnected", "SaveStats", SaveStats)

	function pm:StatsSave()
		self:SetPData( "Credits", self:GetNWInt( "Credits" ) )
	end

	function pm:StatsLoad()
		if self:GetPData( "Credits" ) == nil then 
			self:SetPData( "Credits", CreditShop_Config.STARTCREDITS ) 
		end
		
		local current = tonumber(self:GetPData( "Credits" ))
		self:SetCredits( current )
	end
	
	-- Custom functions
	
	function formatCredits( num ) -- Formats a number like this "10,000 Credits", saves space
	
		local num = string.Comma(num)
		local num = num .. " Credits"
	
		return num
	
	end
	
	function pm:AddCredits( amount ) -- Adds credits to a player's current amount, Use: pm:AddCredits( amount ).
		if amount > 0 then
			local current = tonumber(self:GetPData( "Credits" ))
			self:SetCredits( current + amount )
		end
	end
	
	function pm:SetCredits( amount ) -- Sets a players credits, Use: pm:SetCredits( amount ).
		self:SetPData( "Credits", tonumber(amount) )
		self:SetNWInt( "Credits", tonumber(amount) )
	end
	
	function pm:GetCredits() -- Gets a given player's credits
		local current = tonumber(self:GetPData( "Credits" ))
		return current
	end



This code is the latest currency system I am using, but it has some problems, firstly the money doesn’t save and secondly when you set someones credits the net message cant send enough of the number and therefore the person wont recieve the right amount of money.




local playerMeta = FindMetaTable("Player")

if (SERVER) then
	util.AddNetworkString("ply_SetCredits")
	
	function playerMeta:SetCredits(amount)
		net.Start("ply_SetCredits")
			net.WriteInt(amount, 16)
		net.Send(self)

		self.i_Credits = amount
	end

	function playerMeta:AddCredits(amount)
		self:SetCredits(self:GetCredits() + amount)
	end

	function playerMeta:TakeCredits(amount)
		self:AddCredits(-amount)
	end

	function playerMeta:SaveCredits()

		local fileexist = file.Exists( "Credits", "DATA" )
		if( fileexist == false ) then
			file.CreateDir("Credits")
		end
		
		local uniqueID = self:SteamID()
		local amount = self:GetCredits()

		file.Write("Credits/"..uniqueID..".txt", amount)
	end

	function playerMeta:RestoreCredits()
		local uniqueID = self:SteamID()
		local content = file.Read("Credits/"..uniqueID..".txt", "DATA")

		if (content) then
			local amount = tonumber(content)

			if (amount) then
				self:SetCredits(amount)
			end
		end
	end
else
	net.Receive("ply_SetCredits", function(length)
		local amount = net.ReadInt(16)

		LocalPlayer().i_Credits = amount
	end)
end

function playerMeta:GetCredits()
	return self.i_Credits or 0
end

-- Saves and loads Credits
function LoadCreditStats( ply )
	ply:RestoreCredits()
end
hook.Add("PlayerInitialSpawn", "LoadCreditStats", LoadCreditStats)

function SaveStats( ply )
	ply:SaveCredits()
end
hook.Add("PlayerDisconnected", "SaveStats", SaveStats)



Using NWVars for something like currency that consistently change is fine IMO

I can’t tell you what’s wrong in the code but I can tell you that the reason you can’t send a big number is that you are sending a 16 bit int which means 2^16=65536. If you set it to 32 bit the max will be like 2 billion or something.

Also, using LocalPlayer().Var has it’s problem. If you load the player’s currency when he joins LocalPlayer() won’t exist yet.(At least in my tests) You could just create a global clientside variable or bind it to the GM table.

I was told that when using a currency system in a server, using NWVars is bad as it broadcasts each players money to everyone on the server.

It’s not the best but for something like currency I would definitely go with NWVars. Learning it with the net library is also a good idea.

Ah ok, I have got the set credits thing done now thanks, but how can I get the money to load and save for the player?

Where exactly does it fail? Does it create files when you save it?

No, it doesnt create the folder, so I am guessing on the save func.

You have your answer. Put a print statement after createdir to see if that’s it.

just did that and there is nothing printed in console
The hook works though as I put one in there aswell.

Add me on steam.

sent

The problem was that he was testing his function in the PlayerDisconnect hook in singleplayer.