Datastore leaderstats currency to purchase jump boost

I’m trying to make it so the player can use a leaderstat currency to purchase a jump boost (which I would like to make permanent if I could) and when I put this in a local script it worked fine except for the datastore would restore the player’s currency value to before the purchase so I tried to fix it but it just plainly doesn’t work at all and I’m now stuck.

current script:

local price = 250
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")

script.Parent.MouseButton1Down:Connect(function(plr)
	if plr.leaderstats.Money.Value >= price then 
		plr.leaderstats.Money.Value -= price
		local playerUserId = "Player_" .. plr.UserId  --Gets player ID
		local data = playerData:GetAsync(playerUserId)  --Checks if player has stored data
		data['Money'] = plr.leaderstats.Money.Value 

		local hum = plr.Character:WaitForChild("Humanoid")
		hum.JumpPower += 30
	end
end)

I would appreciate any help thanks!

Hi,
DataStores work only on server, which means you need to use a RemoteEvent to pass the request to purchase something to the server, which validates the purchase and then saves it to DataStore.

I also recommend reading on how to verify data on the server, to prevent exploiters: Security Tactics and Cheat Mitigation | Documentation - Roblox Creator Hub

Thanks for replying!
I tried to implement something like what you described but I still retain the same problem of nothing happening at all.
I have put a remote event in replicatedstorage named “Purchase1”
The local script and normal script both have the same parent being the button the player presses to purchase the jump boost.

Here is the local script:

local RemoteEvent = game.ReplicatedStorage:WaitForChild("Purchase1") --Variable for the Remote Event in Replicated Storage
local price = 250
local plr = game.Players.LocalPlayer
RemoteEvent.OnClientEvent:Connect(function() --Code runs when the Remote Event is fired
	if plr.leaderstats.Money.Value >= price then 
		plr.leaderstats.Money.Value -= price
		local hum = plr.Character:WaitForChild("Humanoid")
		hum.JumpPower += 30
	end
end)

Here is the normal script:

local price = 250
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")
local RemoteEvent = game.ReplicatedStorage:WaitForChild("Purchase1") --Variable for Remote Event

script.Parent.MouseButton1Down:Connect(function(plr)
	RemoteEvent:FireClient(plr) --Fires the Remote Event
	wait(1)
	if plr.leaderstats.Money.Value >= price then 
		local playerUserId = "Player_" .. plr.UserId  --Gets player ID
		local data = playerData:GetAsync(playerUserId)  --Checks if player has stored data
		data['Money'] = plr.leaderstats.Money.Value 

	end
end)

Thanks again!

You’re changing the amount of money the player has on the client, so this will likely not work because of how the client-server replication works.

Ah yeah, I switched the stat changer to the server side but now it’s failing to trigger the remote event giving an error: “Unable to cast value to Object”

I might not be seeing this right, but it seems like you are firing the client from the client script? Your code says RemoteEvent:FireClient(), so tell me if I’m wrong

No, it’s the server script. When I said “normal script” I meant server script.