So I have an obby that saves a player’s stage everytime they reach a new stage.
Although there really isn’t anything wrong with doing that, players on easy levels that touch checkpoints really quickly are setting the datastore key too quickly and I get something similar to this.
My question is - is it good practice to save a player’s data everytime they touch a new stage?
if touch.Parent == checkpoints then
if (tonumber(touch.Name) and tonumber(touch.Name) > tonumber(stage.Value)) or touch.Name == "End" then
stage.Value = touch.Name
pcall(function()
obbyDS:SetAsync(plr.UserId .. "-obbyStageProgress", plr.leaderstats.Stage.Value)
Keep in mind I also :SetAsync() when they leave the game
I would just increment their stage value every time they reach a checkpoint and save that to the data store when they leave. It’s too many requests if you call :SetAsync() after every single checkpoint.
Incorrect, both have a cooldown of 6 seconds for saving data for the same key. If OP decides to save data for let’s say P1 and P2, he should be good since OP won’t be saving the data for the same key.
Using UpdateAsync is good practice, since it respects conflicting calls and is really useful. It gives you the user’s old data, and that way you can check if the user has the same data and cancel the save effectively.
However, both SetAsync and UpdateAsync have the same cooldown.
is it good practice to save a player’s data everytime they touch a new stage?
No, it is bad practice.
Just save the player’s data on leave and on server shutdown. In a rare case where Player Removing doesn’t fire, you would need to implement auto saving every few minutes.
while true do
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
pcall(function()
obbyDS:SetAsync(plr.UserId .. "-obbyStageProgress", plr.leaderstats.Stage.Value)
wait(5)
end
wait(120)
end