I have this problem where the data wonโt save. It doesnโt print the error and Iโm clueless on how to solve this.
Itโs not saving the values inside the tables at all.
--// ๐๐๐๐๐๐
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")
local ServerData = {}
local SavingFor = {}
local function newData()
return {
Stats = {
Money = 0,
Gems = 0,
Diamonds = 0
},
Goals = {
Five = false,
Ten = false
},
}
end
local function loadData(player)
local data
local Success, Error = pcall(function() data = PlayerData:GetAsync("data:"..player.UserId) end)
if not Success then
warn("Could not get data for "..player.Name)
return
end
if not data then
data = newData()
end
ServerData[player] = data
end
local function saveData(player)
if not SavingFor[player] then
SavingFor[player] = true
if ServerData[player] then
local Success, Error = pcall(function() PlayerData:SetAsync("data:"..player.UserId, ServerData[player]) end)
if not Success then
warn("Data wasn't saved for "..player.Name..".")
return
end
ServerData[player] = nil
end
SavingFor[player] = nil
end
end
Players.PlayerAdded:Connect(function(player)
loadData(player)
ServerData[player].Stats.Money = ServerData[player].Stats.Money + 420
print("Added money!")
end)
Players.PlayerRemoving:Connect(function(player)
saveData(player)
print("Saved " .. player.Name .. "'s data!")
end)
game:BindToClose(function()
if RunService:IsStudio() then
print("Not saving data, in studio!")
return
end
for i,p in pairs(Players:GetChildren()) do
saveData(p)
end
end)
Could you try removing your condition statement in your saveData function that checks for SavingFor[player] and try again to see if you see anything different?
Also, Iโm not sure if this matters but for your BindToClose event, Iโve always just put a wait(10) in there. I donโt think itโs necessary to create a for loop to iterate over all the players additionally, so that might be a good quality of life change as well.
Hope this helps, and potentially fixes your issue.
Iโm really confused by that actually. Based on your code, it should only run once for each player when they leave the game. Are you calling this function remotely as well??
@C_Sharper@28Y8 I think the problem here is a logical fallacy in your code. I editted the save function logic, let me know if it works.
local function saveData(player)
if ServerData[player] and not SavingFor[player] then
SavingFor[player] = true
for i,v in pairs(ServerData[player]) do
for j,k in pairs(v) do
print(j,k)
end
end
local Success, Error = pcall(function()
PlayerData:SetAsync("data:"..player.UserId, ServerData[player])
ServerData[player] = nil
end)
if not Success then
warn("Data wasn't saved for "..player.Name..".")
return
end
end
SavingFor[player] = nil
end
This occurs because SetAsync has a 6-second cool down for writing requests to the same key. It happens because youโre attempting to save the data on player removal, as well as in the BindToClose function.
This is called Throttling. Throttling isnโt anything to worry about, as the request will eventually be handled in the queue itโs in. Though, sometimes you may exceed the limit of the queue, so requests would be dropped and not handled if it ever does
You should add some error throttling to your datastore functions because datastores can fail sometimes so you should make it retry calling SaveData, GetData or whatever your datastore call is. For example:
local Retries, MaxRetries = 0, 5
repeat
local Success = pcall(Datastore.SaveAsync, Datastore, player.UserId, Data)
Retries = Retries + 1
until Success or Retries == MaxRetries
May I suggest adding a 6-second cooldown between saves, because I mentioned that this will cause throttling and could cause the request queue to overflow and not save the requests. That is if your maximum number of retried is greater than 2.
Also, edit to your code:
local retries, maxRetries = 0, 5
repeat
local Success = pcall(saveData, player)
retries = retries + 1
wait(6)
until Success or retries == maxRetries