Hi there, our game Anomic currently has a small problem with data loss, I suspect that GetAsync() really rarely returns nil, so like the player never had data saved, without errors, therefore it updates their data once they leave the game and then everything is lost.
I personally think our code does not exhaust the Datastore at all, as it only calls GetAsync and SetAsync / UpdateAsync once per play session.
Here the way our system works.
function data:LoadData(self)
dataloaded[self] = false -- A bool to indicate if the player has their data loaded, if it is false, their data wont update
HadDataBefore[self] = false -- A bool to check if the player already had data before, to determine if to use SetAsync or UpdateAsync
-- Set a table for every player who joins the game
local success, err = pcall(function()
local saved = dataStore:GetAsync(self.UserId .. key)
if saved then
HadDataBefore[self] = true -- Set to true cuz player has data
-- Update their data in the table
end
end)
if err then
print("Failed to load/create player data, Name : " ..self.Name.. "Error " .. err)
events.PostEvent:Fire(self.Name, "Failed to load this player's data. Error : " ..err) -- Errors even reported to Discord webhook!
self:Kick() -- Kick the player so they dont play with broken stuff
return false
else
dataloaded[self] = true -- Set to true so we can save the player data again.
end
return true
end
-- Code to save data
function data:AutoSave(self)
if game.VIPServerId ~= "" and game.VIPServerOwnerId == 0 then return end -- Dont save data if player is in vip server without owner (For example server generated vip servers)
if dataloaded[self] == false then return end -- If the data firstly fails to load, return so the data doesnt break
local fetch = HadDataBefore[self] -- Here comes our bool again.
local success,err = pcall(function()
if fetch == false then -- no data prior to this call.
dataStore:SetAsync(self.UserId .. key, data[self])
else --Player has data prior, lets update it.
dataStore:UpdateAsync(self.UserId .. key, function(oldValue)
local newValue = oldValue or -- Data for new players
newValue = data[self]
print ("Saved Player data")
return newValue
end)
end
end)
if err then
print("Failed to save player data, player name : " .. self.Name .. "Error : ".. err)
return err
end
end
It works for other games too I assume (Because I never experienced loss of my own data in any other games), so what am I doing wrong / could I do better?