Don’t use SetAsync() alot. I’d only use SetAsync() if they don’t have data. Other than that I’d reccomend to use UpdateAsync() and you should really only use it ever 30-60 seconds and if the player leaves.
Try to use this:
game.Players.PlayerRemoving:Connect(function(Player)
local success, errormessage = pcall(function()
obbyDS:SetAsync(plr.UserId .. "-obbyStageProgress", plr.leaderstats.Stage.Value)
end)
if not success then
local count = 1
repeat
warn("[ERROR]: Error- saving " .. Player.Name .. "'s data failed.\nAttempt: " .. tostring(count) .. "\nError Message: " .. errormessage)
success, errormessage = pcall(function()
count += 1
obbyDS:SetAsync(plr.UserId .. "-obbyStageProgress", plr.leaderstats.Stage.Value)
end)
wait(5)
until success or count >= 5
end
Thank you everyone for the help. I’ve gone ahead and did a few things
@zachariapopcorn - I’ve actually added a button which saves data and has a cooldown of 2 minutes so players can only save their stage after 2 minutes
@SilentsReplacement - I added an autosave which saves everyone’s data every 2 minutes as well
And I also kept Player Removing to save when they leave, and removed SetAsync after each checkpoint.
I recommend rather using :UpdateAsync()
. And if your checkpoints are close to each other, it’s a bad idea, it can break DataStores and delay saves and loads, which can cause data loss. Unless you’re using the DataStore2 module, it’s a bad idea.
Using simply :UpdateAsync()
and keeping track if the server is shutting down is simply enough.
You can save every player’s data when the game is shutting down by using game:BindToClose(function()
and saving each player’s data manually there by looping through them.
I recommend just save it when the player leaves. If you want, people are recommending to also save it every few minutes. Also, use UpdateAsync. It helps prevents data loss.