Hi,
I am creating a currency system where a localscript detects when the value has changed and fires a RemoteEvent. After this, the script in ServerScriptService then should save it to datastores.
It prints no errors however wont work.
Can I have some help?
Server Script (ServerScriptService):
local DataStore=game:GetService("DataStoreService") local CashStore=DataStore:GetDataStore("Currency") local UpdateNeeded=game.ReplicatedStorage.Events.CashUpdateNeeded UpdateNeeded.OnServerEvent:Connect(function(plr, CashValue) local Success, err=pcall(function() CashStore:SetAsync(plr, CashValue) end) if not Success then print(err) end end)
Local Script (StarterPlayerScripts):
local DataValues=game.Players.LocalPlayer:WaitForChild("DataValues") DataValues.Cash.Changed:connect(function() game.ReplicatedStorage.Events.CashUpdateNeeded:FireServer(game.Players.LocalPlayer.DataValues.Cash.Value) end)
There are a lot of things that need to be changed in this code. The most critical one being you are asking the client to send how much cash they have to save. ?????????
The second thing which needs to be changed is that the player should never decide when to save their data. This is a job solely for the server, yes they can ask the server to save their data but the server should decide if it should save the data. This also means that you should never save data when you have no control over how many requests are made. Another common error is to save player data in a Changed event.
Lastly SetAsync needs a string key and is commonly a prefix with the players user id to make sure the key is unique.
local keys = "usr_" .. tostring(player.UserId)
On the more posative side you have used pcall to catch any potentual errors while saving data but you would still need to retry this until it runs successfully or you stop the request after 3 failed attempts.
Note that you also need to use pcall when getting the data if you have not already done so.
In most cases you would simply save data when the player leaves the game or at key points in the game that you program.
Example only to show how it a save/load can be setup.
local DataStore=game:GetService("DataStoreService") local CashStore=DataStore:GetDataStore("Currency") local plrDataList = {} local prefix = "usr_" local function getData(key) local success, result = pcall(function() return CashStore:GetAsync(key) end) if success then return result else warn("Data store get request failed for key ", key) warn(result) -- your retry code ect... end end local function saveData(key, data) local success, result = pcall(function() CashStore:SetAsync(key, data) end) if success then print("saved data for key", key) return true else warn("Data store save request failed for key ", key) warn(result) -- your retry code ect... end end game.Players.PlayerAdded:Connect(function(plr) plrDataList[plr.UserId] = getData(prefix .. tostring(plr.UserId)) or 0 -- gets the player data or sets to 0 print("Player data is", plrDataList[plr.UserId] ) end) game.Players.PlayerRemoving:Connect(function(plr) saveData(prefix .. tostring(plr.UserId), plrDataList[plr.UserId]) plrDataList[plr.UserId] = nil -- remove data from table end) -- you should also save data on server close -- Roblox does not fire PlayerRemoving unpon server shutdown game:BindToClose(function() for i, v in pairs(plrDataList) do spawn(function() saveData(i, v) -- spawn a theread for each player data save end) end end)
This is only and example and is not fully suited for an active game as there is no retry attempts.
Hope this helps.