I’m trying to make it so it takes away money when buying an upgrade
Local script
local plr = game.Players.LocalPlayer
script.Parent.MouseButton1Up:Connect(function()
local up = script.Parent.Parent.Upgrade
local cost = script.Parent.Parent.Cost
if plr.leaderstats.Money.Value >= cost.Value then
game.ReplicatedStorage.Upgrade:FireServer(plr, up, cost)
end
end)
Server script
game.ReplicatedStorage.Upgrade.OnServerEvent:Connect(function(plr, up, cost)
if plr.leaderstats.Money then --if statement shows it's there
plr.leaderstats.Money.Value = plr.leaderstats.Money.Value - cost.Value --error
up.Value.Value = up.Value.Value + 1
end
end)
The if statement clearly shows that it’s there, but the next line shows that it’s nil
It’s because you’re sending the player as an argument on the client’s side, which is unnecessary since the player is a built-in argument on the server’s side. The server is registering this:
But you’re only picking up the first two values sent from the client, because the first argument on the server is already occupied – the first argument is the player who fired the server, an automatic argument.
To fix this, just remove the plr argument the client is sending.
Also, if the ValueObject was created by the client, it is not replicated to the server. So, the server does not know what that ValueObject, referred to as cost, is.
The costs should be stored on the server, and the client should only fire to the server what the name of the upgrade is. Then, from the server, you can validate the name and then subtract the cost of the upgrade with the given name from the client’s money. This will prevent exploiting.