My leaderstats script is only changing Cash value for client and not server

I wrote this script with functions to increase, decrease and save player’s cash and everything worked except cash on leaderstats only appear visible for client and not server (Only one player who earned the cash can see his cash on the leaderboard meanwhile for other’s his cash value is 0)
Here is the script located inside ServerScriptService:

local Players             = game:GetService("Players")
local RS                  = game:GetService("ReplicatedStorage")
local Workspace           = game:GetService("Workspace")
local moneyRS             = RS:WaitForChild("Server"):WaitForChild("Money")
local moneyRE1            = moneyRS:WaitForChild("Increase")
local moneyRE2            = moneyRS:WaitForChild("Decrease")
local DataStore           = game:GetService("DataStoreService")
local DataCollect         = DataStore:GetDataStore("Data")

--

local function debug(error)
	if error ~= nil then
		warn(error)
	end
end

local function CreateStats(Player)
	if not Player:FindFirstChild("leaderstats") then
		local stats = Instance.new("Folder", Player)
		stats.Name = "leaderstats"
		local MoneyInt = Instance.new("IntValue", stats)
		MoneyInt.Name = "Money"
		local data

		local s, e = pcall(function()
			data = DataCollect:GetAsync(Player.UserId)
		end)
		if not s then debug("Failed to locate data, id: "..Player.UserId) end
		if data and data[1] then
			MoneyInt.Value = data[1]
		else
			MoneyInt.Value = 0
		end
	else
		debug("Player already has leaderstats.")
		if not Player:FindFirstChild("leaderstats"):FindFirstChild("Money") then
			local stats = Player:FindFirstChild("leaderstats"):FindFirstChild("Money")
			local MoneyInt = Instance.new("IntValue", stats)
			MoneyInt.Name = "Money"
			local data

			local s, e = pcall(function()
				data = DataCollect:GetAsync(Player.UserId)
			end)
			if not s then debug("Failed to locate data, id: "..Player.UserId) end
			if data and data[1] then
				MoneyInt.Value = data[1]
			else
				MoneyInt.Value = 0
			end
		else
			debug("Player already has Money.")
		end
	end
end

local function DecreaseMoney(Player, value)
	if Player:WaitForChild("leaderstats"):FindFirstChild("Money") then
		local MoneyInt = Player:WaitForChild("leaderstats"):WaitForChild("Money")
		MoneyInt.Value -= value
	end
end

local function IncreaseMoney(Player, value)
	if Player:WaitForChild("leaderstats"):FindFirstChild("Money") then
		local HungerInt = Player:WaitForChild("leaderstats"):WaitForChild("Money")
		HungerInt.Value += value
	end
end

local function SaveMoney(Player)
	local ValuesToSave = {
		Player:WaitForChild("leaderstats"):WaitForChild("Money").Value;
	}
	pcall(function()
		DataCollect:SetAsync(Player.UserId, ValuesToSave)
	end)
end

Players.PlayerAdded:Connect(function(Player)
	CreateStats(Player)
end)

Players.PlayerRemoving:Connect(function(Player)
	SaveMoney(Player)
end)

moneyRE1.OnServerEvent:Connect(function(Player, value)
	IncreaseMoney(Player, value)
end)
moneyRE2.OnServerEvent:Connect(function(Player, value)
	DecreaseMoney(Player, value)
end)

for _,Dump in pairs(game.Workspace.Dumpsters:GetChildren()) do
	Dump.Trash.Attachment.Search.Triggered:Connect(function(Player)
		local tool = script.money:Clone()
		tool.Parent = Player.Character
	end)
end

Please note that it’s not an localscript!

1 Like

For those who don’t understand it looks like all changes done to leaderstat are client sided and not serversided.

1 Like

Hello. If all the changes are client-sided they will only be visible to client. To make client side and server side communicate use Remote Events and Remove Functions.

1 Like

And I not suggest using that type of concept, where a client sends amount of money to be increased straightly to server, without any checks. Remember, hackers can call remote events.

Yes but this is not meant to be client sided since i said it’s not put inside an localscript? I also do use remotes if you saw

local RS                  = game:GetService("ReplicatedStorage")
local Workspace           = game:GetService("Workspace")
local moneyRS             = RS:WaitForChild("Server"):WaitForChild("Money")
local moneyRE1            = moneyRS:WaitForChild("Increase") --REMOTE
local moneyRE2            = moneyRS:WaitForChild("Decrease") --REMOTE

so im already doing exactly what you are saying.

Also no, this script creates leaderstats for everyone and they are visible to server and are working so not all changes seem to be client-sided so that’s why im currently confused

What is your problem? Is it just other players see 0 in the default roblox leaderboard

Yes and when the script that created the leaderstats change’s the value from 0 only one player can see it.

Im talking about the way you are using remote events. You push a packet from a local script to the server for granting money. If I we’re a hacker I would juse use moneyRE1:FireServer(math.huge)

2 Likes

Well is there an other way to do it then? I mean i could just delete the function but at the same time it would never explain why nothing is server-sided for now? I mean i could try not to use Remotes if that’s what you are saying but they were the easiest option. I could also try and add something against injecting script into the game or just an detection when player get’s a huge amount of cash added to his stats.

You are using them in a wrong way. You should even decrease / increase money from client. It should be all server sided. You don’t even need moneyRE1 and moneyRE2. What are you using events for?

Your understanding of client / server concept is wrong. I will give you an example of using remote events from my own game: I got a building system, when player clicks I make a remote call to server with following info. BlockName, BlockPosition. I check if there are blocks with the same name inside player’s inventory. And I do the check if BlockPosition is inside player’s plot

I got a local script inside a money giving tool and it would just fire the event with how much money i want player to get

So you want player to choose how much money he gets?

Not really i got a money tool and every time that player uses it the player get’s 1 dollar.
Here is the script (localScript)

local Tool              = script.Parent
local RS                = game:GetService("ReplicatedStorage")
local Player            = game:GetService("Players").LocalPlayer
cooldown                = false

local function debug(error)
	if error ~= nil then
		warn(error)
	end
end

Tool.Activated:Connect(function()
	if cooldown == false then
		cooldown = true
		game.ReplicatedStorage.Server.Money.Increase:FireServer(1)
		wait(3)
		cooldown = false
	else
		debug("Cooldown is active.")
	end
end)

Oh i found the problem, it was just that i didn’t use the remotes in a script and i just used
Player.Value += number (in a localscript) i know this error is dumb but atleast i found the problem

I marked your post as a solution so i don’t get attacked for solution farming but anyways thank you for helping!

1 Like

Hey, just to let you know that dev forum doesn’t increase your solution counter if you marked your own post as a solution.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.