✓ Accepted answer
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)
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)
end
end
game.Players.PlayerAdded:Connect(function(plr)
plrDataList[plr.UserId] = getData(prefix .. tostring(plr.UserId)) or 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
end)
game:BindToClose(function()
for i, v in pairs(plrDataList) do
spawn(function()
saveData(i, v)
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.
7 comments
Can you edit your post and include the local script please?
Done.
You are trying to set something to an object not a string
The CashValue is an integer, sent from the LocalScript.
You need a key. Currently, you're setting the key as a Player instance, which is wrong. https://developer.roblox.com/api-reference/function/GlobalDataStore/SetAsync
Wow, I feel like an idiot now, thank you so much haha.
Glad to help. Be sure to use the exact same key when you're loading the player's data. It's recommended to have the player's UserId in the key.