MouseButton1Click is a Client-sided event therefore it can only be listened for and activated in LocalScripts. You can update leaderstats through the client but it will not update for anyone else. Instead, you should be updating the leaderstats values through a ServerScript. Best way to achieve this is by using RemoteEvents. If you are unfamiliar with RemoteEvents, I recommend you check out this post or this post on the Roblox Developer Hub. If you still need help, I can provide an example of how you would use them for your script.
ive never used a remote event, ive tryd so many times in the past, but never worked for me. so what if i were to make it so if the button gets clicked it just makes a part Anchored or something and the part will be in IDK in Lighting, and like if the button is clicked it turns Anchored off and in a normal script ill just put if the part Anchored = false then bla bla bla
In order to perform anything on the server, such as updating values, anchoring parts, or anything else, you will need to use RemoteEvents. They are something that are really essential to learn in programming on Roblox. The two posts I linked above are very helpful for people who are unfamiliar, but you could also find tutorials on YouTube if you’re still struggling.
This is how you would use remoteevents to tell the server to remove cash/add an area.
-- server script in serverscriptservice
local Players = game:GetService("Players")
local clickRemote = path.to.remote
local amount = 1 -- it's better to just make a variable than have a value for it
local playerStats = {}
local function debounce(func)
local running = false
return function(...)
if not running then
running = true
func(...)
running = false
end
end
end
Players.PlayerAdded:Connect(function(player)
playerStats[player] = player:WaitForChild("leaderstats")
end)
clickRemote.OnServerEvent:Connect(debounce(function(player, button)
if typeof(button) ~= "Instance" or not button:IsDescendantOf(player.PlayerGui) then
player:Kick()
end
local cash = playerStats[player].Cash
local areas = playerStats[player].Areas
if cash.Value >= amount then
cash.Value -= amount
areas.Value += 1
end
end))
-- client (localscript)
local clickRemote = path.to.remote
local button = script.Parent
button.MouseButton1Click:Connect(function()
clickRemote:FireServer(button) -- tiny bit of added security
end)
Exploiters can change values local to them, so that’s not a good idea.
You can listen for the MouseButton events (for some reason not Activated) through a server-script, though it’s not recommended.
@Flaming_Bird22 All you need is either one server-script handling everything for every player (you can listen to MouseButton1Click events from the server if you manage to reference the respective Gui button objects) and increment their values right there, or preferably have a LocalScript listening for client input, fire a RemoteEvent as suggested by others and increment the value on the server for it to replicate to all clients.
Do note that exploiters can take note of this and crash servers after causing code to run too frequently, use some sort of relative debounce to prevent that.
It’s better to create it in this script instead of waiting for it since you’re saving the leaderstats folder into a table in this script. If you create it somewhere else, then just combine that script with this one.
yahhh i dont think im that good of a scripter to combine scripts, trust me, you dont know how many times ive tryd, but if you want to do it, not saying im making you do it but if you want to do it then here is the leader stats scripted i used
local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("CashValueSaver")
local ds2 = datastore:GetDataStore("RebirthsValueSaver")
players.PlayerAdded:connect(function(player)
local folder = Instance.new("Folder")
folder.Name = "leaderstats"
folder.Parent = player
local currency1 = Instance.new("IntValue")
currency1.Name = "Cash"
currency1.Parent = player.leaderstats
currency1.Value = ds1:GetAsync(player.UserId) or 0
ds1:SetAsync(player.UserId, currency1.Value)
local currency2 = Instance.new("IntValue")
currency2.Name = "Areas"
currency2.Parent = player.leaderstats
currency2.Value = ds2:GetAsync(player.UserId) or 0
ds2:SetAsync(player.UserId, currency2.Value)
currency1.Changed:connect(function()
ds1:SetAsync(player.UserId, currency1.Value)
end)
currency2.Changed:connect(function()
ds2:SetAsync(player.UserId, currency2.Value)
end)
end)
all im trying to do is basicly make a door like the doors off of pet simulator were you have to pay to go into the next area, but i dont know how to do that so i just am doing 2 leaderstats and making it so if a player has that amount of areas or more areas they can go through
If this is a localscript, it can be exploited pretty easily.
You should be really careful what power you’re giving the client.
Besides, also do some sanity checks on the server before giving them anything (via the server).
When they click to change their stats by clicking on the button,
other players won’t be able to see it as the change is local (only affecting the player doing it).
You can use a RemoteEvent to solve this: RemoteEvent
Also. You shouldn’t use SetAsync() everytime their stats is changed, you will have throttling issues.
You should load their data when they join, and save when:
Leaving (PlayerRemoving)
Interval while wait(180) do SaveData() end
BindToClose
Another note
LuaU has something new you can use.
Instead of doing: Cash.Value = Cash.Value + 1,
you could do: Cash.Value += 1.
These also counts for: %, /, - and + (I believe that’s all of them).