local function TableValues(Player)
local Player_stats = {}
for i, v in pairs(Player.leaderstats:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.ValuesFolder:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.Settings:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.Codes:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.DnaOwned:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.EquippedFolder:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.RanksOwned:GetChildren()) do
Player_stats[v.Name] = v.Value
end
for i, v in pairs(Player.ToolsOwned:GetChildren()) do
Player_stats[v.Name] = v.Value
end
return Player_stats
end
game.Players.PlayerRemoving:Connect(function(Player)
local Table = TableValues(Player)
local S, E = pcall(function()
PlayerData:SetAsync(Player.UserId, Table)
end)
if S then
print("DataStored")
else
warn(E)
end
end)
That was how i saved it, but now i will show you how i get the data
I do have a backup save that does the same. but it didn’t really work as i still get dataloss in my game. I get about 500 players each day so idk if this is normal i do use datastore 1
bro i told you it’s not that. Lmao why should a game with 100 active with datastores forget to turn em on? like bro i told you already it’s on. The game is storing alot of data, and it’s working it’s just some players experiencing dataloss
local function TableValues(Player: Instance)
local Player_stats = {}
local foldersToSaveFrom = {Player.leaderstats, Player.ValuesFolder, Player.Settings, Player.Codes, Player.DnaOwned, Player.EquippedFolder, Player.RanksOwned, Player.ToolsOwned}
for _, folder in foldersToSaveFrom do
for _, value in folder:GetChildren() do
Player_stats[value.Name] = value.Value
end
end
return Player_stats
end
I read once that :SetAsync is known for data losses, I would suggest using :UpdateAsync although its a little slower thanks to it reading data too and returning it through an argument but might do the job.
Edit: I had a similar problem before too and UpdateAsync somehow fixed it
Possible fix 2: add a delay between joining and saving, since you use values and if the player leaves before the values are recognised it can save default value data aka 0s or empty strings
You could add a cooldown how long you need to be on the server for it to save, did it for 10 seconds in the game I’m making
Use UpdateAsync instead of SetAsync, it’s more reliable as it simply updates a player’s value instead of overwriting it completely, so it reduces the chance of data loss. I noticed in my previous project data-loss occurred and I was using SetAsync
This might fail if the datastore is working but the data failed to be accessed for the player, you should check the E value after a success because you could be wiping out player data under conditions where the datastore is working but the players data fails to be accessed.
The most common reason behind the data loses in a working DataStore script, is attempting to save values which haven’t been loaded yet.
The servers and data stores experience plenty of issues, delays etc. so in certain circumstances the PlayerRemoving event will be called before all the values have been set which usually results in saving nil or an empty table to the data store.
To prevent this, you can use simply use a variable to make sure the values have loaded successfully:
local isLoaded = {}
Players.PlayerAdded:Connect(function(player)
-- load all the values here
isLoaded[player] = true
end)
Players.PlayerRemoving:Connect(function(player)
if (isLoaded[player]) then
-- save the data here
end
end)
local s,e = pcall(function()
DataStore:UpdateAsync(UserID, function(oldData)
local PreviousData = oldData
if PreviousData then
-- has previous data
else
-- doesn't have previous data
end
end)
end)
The ‘s’ means that UpdateAsync() worked and the function successfully returned, i.e. it was able to access the datastore. The error condition will be set if the players data failed to load so you should always check the ‘e’ in case ‘s’ told you the DataStore is working, but the ‘e’ will tell you if the data did/didn’t load.
What I recommend is wrapping your GetAsync request in a pcall, as that will give you more freedom to handle errors rather than just checking if your data is nil or not. Datastores don’t always work correctly, so maybe your data loss stems from the fact that you’re not correctly handling the potential errors associated with the retrieval of your player’s data. You mentioned you had a backup system in place, so you could send that if you believe it may be the source of your problem.
Example:
local data
local success, err = pcall(function()
data = yourDataStore:GetAsync(yourKey)
end)
if err then
retry()
end
Exactly what I was trying to say the success says the function worked, not if the data was able to be accessed, the error condition will tell you that.