Problem with leaderstats

Hello everyone,

I was recently working with leaderstats, but whenever I try to add points to my leaderstats the output I get is, “Attempt to index nil with leaderstats”

Heres my code

script.Parent.MouseButton1Click:Connect(function(player)

player.leaderstats.Cash.Value = player.leaderstats.Cash.Value + 1

end)

You don’t get player from MouseButton1Click I don’t know why so many people seem to think that.

Instead use:
local player = game.Players.LocalPlayer

If it’s a local script

Its a server script, If I use local script the server doesnt see the change in the value, I also tried to get the local player throught, LocalPlayers, But it still didnt work because it cant find the player.

Dont use localscripts because the other player wont see the changes.
Try this:

local player = script:FindFirstAncestorWhichIsA("Player")
script.Parent.MouseButton1Click:Connect(function()
    player.leaderstats.Cash.Value = player.leaderstats.Cash.Value + 1
end)
2 Likes

Just wanted to say that now you can just do player.leaderstats.Cash.Value += 1

Player input should always be handled on the client-side.
You can hook up a RemoteEvent if server communication / replication is needed.

The code you provided is inefficient.

Making that it will be vulnerable to be hacked.

  1. It can’t get hacked, the term you wanted to use is probably exploited.
  2. No, it cannot be exploited if you implement sanity checks.
1 Like

There are a few issues with this code so I’ll walk you through them.

Firstly, the moustButton1Click is an input, and as such should be handled on the client. However, the players cash value should be handled on the server, as to stop exploiters giving themselves infinite amounts of cash. To fix this, you’ll have to use RemoteEvents. You can read through them there, but in short, we’ll be using the FireServer and OnServerEvent Events.

Now, let’s start writing your code.

local remote = REMOTE_EVENT_HERE

Next, MouseButton1Click is an event in GUIs, so I assume you’re using a UI. Let’s define that and then fix the Event.

local REMOTE = REMOTE_EVENT_HERE
local UI_BUTTON = BUTTON_HERE

UI_BUTTON.MouseButton1Click:Connect(function()

   -- To be continued
   
end)

Now, we’re going to have to fire the server with the remote we referenced earlier. To do that, we’ll simply use the FireServer Method, as such:

local REMOTE = REMOTE_EVENT_HERE
local UI_BUTTON = BUTTON_HERE

UI_BUTTON.MouseButton1Click:Connect(function()

   REMOTE:FireServer()
   
end)

With this, we now need to go to a normal script and write some code on the server. Once you do that, we’ll define the remote again and this time we’ll use the other event mentioned earlier, OnServerEvent. This event fires every time the client uses FireServer. The first parameter provided in this event is the player, and any arguments following that are ones sent via the client.

local REMOTE = REMOTE_HERE

REMOTE.OnServerEvent:Connect(function(PLAYER)

   -- To be continued

end)

Now, we simply have to get the players leaderstats and increase the cash value. I’ll use the += operator as it looks better and is more efficient.

local REMOTE = REMOTE_HERE

REMOTE.OnServerEvent:Connect(function(PLAYER)
      player.leaderstats:WaitForChild("Cash").Value += 1
end)

And after all of that, your code should hopefully work. All though this is inefficient, prone to exploiting and could cause lag, for what you want it’ll be fine.

1 Like

Next, MouseButton1Click is an event in GUIs, so I assume you’re using a UI. Let’s define that and then fix the Event.

The right term would be GuiButton | Roblox Creator Documentation.

All though this is inefficient, prone to exploiting and could cause lag, for what you want it’ll be fine.

This is not inefficient, and won’t cause lag as long as you do sanity checks on the server-side to avoid spam.
Here’s an example:

local RemoteEvent = game:GetService('ReplicatedStorage').RemoteEvent
local Cooldown = 10
local Debounces = {}


local function OnServerEvent
(Player, ...)
	if (table.find(Debounces, Player.UserId)) 
	then return end
	-- Check if they are in the table, if not, return end.
	
	table.insert(Debounces, Player.UserId)
	-- Add them to the table.
	
	-- Give them the stats.

	task.wait(Cooldown)
	-- After giving them the stats, wait a certain amount of time before removing the player from the table
	
	table.remove(Debounces, table.find(Debounces, Player.UserId)) 
	-- Remove the player.
end


RemoteEvent.OnServerEvent:Connect(OnServerEvent)
2 Likes

I understand that it wont cause lag if I implemented sanity checks but in my code I didn’t which is why I said it would be prone to lag.