Is this method able to prevent 100% data loss? Can you see any pitfalls?

In all of my games, I have a mechanism for saving/loading data that prevents data loss and overwriting with a simple check. It is a “DataLoaded” value. Here’s how it works.

Players.PlayerAdded:Connect(function(plr)
      local DL = makeStat({Class = "BoolValue", Name = "DataLoaded", Parent = plr, Value = false})
      
      local success, plrData = getData(playerKey) --[[ insert mechanism that checks 
  5 times in a pcall to retrieve the player's data and indicates if it's the player's 
first time, and if there is no data when there should be, success returns false]]
      if success then
             -- load the data
             DL.Value = true
      elseif not success then
             -- if the data wasn't found, you can kick the player telling them to rejoin or give the player a notification that data may not be saved.
      end
end)
Players.PlayerRemoving(function(plr)
      if plr.DataLoaded.Value == true then
             -- save the data safely.
      end
end)


It’s a very simple mechanism where data can only overwrite if the previous saved data is accurate to the player’s history in the game, and doesn’t completely reset it to the default stats. Can you see any problems with this? I have never gotten a data loss report ever - without having to use DataStore2 and other boilerplate complicated module methods.

3 Likes

This should thoroughly protect against total data wipes, but players could still lose a play session if the server crashes or Roblox goes down because then PlayerRemoving wouldn’t get a chance to fire.

3 Likes

If DL.Value is never true, the player data won’t save as implemented by you and that would cause the data to remain always nil which will result in data not loading since DL.Value will only be true if the data loads successfully.

The data store won’t SetAsync() at all unless the pcall function is successful, and otherwise the player will be kicked/warned that data won’t save without tampering with the data store for that specific player at all. The only pitfall so far that I see is that only the current play session could be potentially lost, which can be mitigated by making auto saves every few minutes and by binding data saving to server shutdown.

1 Like

Outside the pcall function there is a plrData variable which is set outside of the pcall. The main focus of the post is emphasizing the DL variable, but in the pcall it will manually return successful/unsuccessful based off of whether or not plrData is nil or not.

repeat success, message = pcall(function() plrData = DataStore:GetAsync(key) end) if not success then attempts = attempts+1 end wait(duration) until attempts >= maxAttempts or success
3 Likes