I’ve been problems with players losing their data for a while now and I still don’t really know / understand if it’s a saving or a loading problem, I’ve never changed my code and now that I’m revising it, I can’t really find anything blatantly wrong.
I tried but was unsuccessful at trying to replicate the data loss errors myself, so I still don’t know if it’s a loading problem or a saving problem.
Suspecting it was a loading problem, I tried wrapping the loading in a pcall() and not letting the player save if the Loading PCall returns an error so that its data cannot be overwritten, but nothing much changed.
Any ideas or overall help is greatly appreciated, thanks!
------CODE------
There’s a ModuleScript in the serverStorage that handles saving and loading.
Module Script Functions:
local Data = {}
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DataStoreName")
function Data.Load(plr: Player)
local plrKey = plr.UserId.."-levelData"
local plrData;
local Success, Error = pcall(function()
plrData = ds:GetAsync(plrKey)
end)
if Success then
if Data then
print("Level Data Loaded "..plr.UserId)
return plrData
else
warn("Level Data not found, the player is new")
return nil
-- No data was found, so it will return nil and the loading data Player added function will load an empty table (new player).
end
else
print(Error)
plr:SetAttribute("ShouldSaveData", false)
plr:Kick("Your data could not be loaded correctly. To prevent data loss you're going to get kicked out of the game, please try again by joining the game again!")
-- Tag this player that it shouldn't save data and kick them
end
end
function Data.Save(plr: Player)
local plrStats = plr.playerFolder
local plrLVL = plrStats.PLR_Level
local plrEXP = plrStats.PLR_XP
local plrKey = plr.UserId.."-levelData"
local plrData = {
LEVEL = plrLVL.Value;
EXP = plrEXP.Value;
}
--// Check if the player is eligible for data saving
if plr:GetAttribute("ShouldSaveData") == false then
warn("To prevent data overwrite, data CANNOT be saved as there were problems while loading it")
else
--// Main saving function
local success, errormessage = pcall(function()
ds:SetAsync(plrKey, plrData)
end)
if not success then
warn("Could not save Level Data! "..errormessage)
else
print("Level Data Saved!")
end
end
end
return Data
Loading Data:
game.Players.PlayerAdded:Connect(function(plr: Player)
PlayerStats.New(plr) --It creates a folder with the actual Value instances
--// Data Loading
local plrData = Data.Load(plr) --Function in the module
--// values check
local savedLvl;
local savedExp;
--// Player Level
if plrData ~= nil then
print("plrData is not an empty table ===> Player is not new")
savedLvl = plrData.LEVEL
else
print("plrData is an empty table ===> Player is new")
savedLvl = '0'
end
--// Player EXP
if plrData ~= nil then
print("plrData is not an empty table ===> Player is not new")
savedExp = plrData.EXP
else
print("plrData is an empty table ===> Player is new")
savedExp = 0
end
--// new chec
if plrData == nil then
plrData = {}
end
local plrStats = plr:WaitForChild("playerFolder")
local plrLVL = plrStats.PLR_Level
local plrEXP = plrStats.PLR_XP
plrLVL.Value = savedLvl
plrEXP.Value = savedExp
Saving Data:
game.Players.PlayerRemoving:Connect(function(plr: Player)
Data.Save(plr)
end)
game:BindToClose(function()
for _, plr in pairs(game.Players:GetPlayers()) do
Data.Save(plr)
end
end)