-
What do you want to achieve? Save data reset. How to stop this from happening?
-
What is the issue? I get complaints on my Roblox page from players who have all their save data wiped. Normally everything works great. All my tests have never been able to replicate the problem. However, I get daily new complaints of players loosing all data.
-
What solutions have you tried so far? I have been working tirelessly to solve this. The tricky part is checking if the player is NEW with no data vs. a player who did not load data correctly and therefore has no data. So, before I load data or set new values for a new player, I quintuple check (5 times) in .5 second intervals, to make sure there is no data (lines 209-218.) I also switched to using UpdateAsync from GetAsync (lines 206, 213 for load, and line 55 for save). Before I save, I check one of the values that should not be nil, just to make sure there really is some data (line 48). Additionally at the few key moments in the game (buy item, get item) I have a bindable event trigger the save data function. Finally, on player exit, I quintuple check (5 times) that the save data worked. (lines 599-605)
Before, people would also complain about loosing just some data – as if the data would revert to a previous save. However, after I switched to update async, the “some data” / previous save, players have stopped. However I still have players complaining about loosing all data.
I’m including my entire save/load script. The most important parts are (Make the table, lines 21-36) (Save data, lines 39-66) and (Check if new player, lines 199 – 226). The other parts of the script relate to equipping items, checking game pass, counting dragons and dragon types, and sending data to the leaderboard.
-------------------SAVE and LOAD DATA script----------------------
print("<<LOAD DATA STARTED>>")
local DataStoreService = game:GetService('DataStoreService')
local playerData = DataStoreService:GetDataStore('PlayerData')
local MarketplaceService = game:GetService("MarketplaceService")
local SaveAttempts = 5
local AutosaveInterval = 120
--------------------<<GAME PASS IDS>>-------------------------
local UnlimitedLivesID = 22712458
------------Panchos Leaderboard------------------------
local dataStore = DataStoreService:GetOrderedDataStore("Wins")
--------------------------------------------------------
---------------------------------------------------------------------------
----------------------------MAKE THE TABLE-----------------------------------
---------------------------------------------------------------------------
local function create_table(player)
local player_stats = {}
for _, stat in pairs(player.saveData:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
print("<<TABLE MADE>>")
return player_stats
end
-------------------------------------------------------------------
--------------------SAVE DATA--------------------------------------
-------------------------------------------------------------------
local function SaveData(player)
local player_stats = create_table(player) --call MAKE THE TABLE
local success, err = pcall(function()
-- only in Baby Dragon Hot springs
if not player.saveData.TotalDragons.Value then
warn("<<Player's data is missing>>")
return -- don't save if data is missing
end
local playerUserId = 'Player_'..player.UserId
--playerData:SetAsync(playerUserId, player_stats)
playerData:UpdateAsync(playerUserId, function(OldData)
return player_stats
end)
print("*****************************************************************************")
print("********************<<Saved data for " ..player.Name.. ".>>******************")
print("*****************************************************************************")
print(player_stats)
end)
return success, err
end
-------------------------------------------------------------------
--------------------PLAYER JOINS - LOAD DATA-----------------------
-------------------------------------------------------------------
local function onPlayerJoin(player)
local saveData = Instance.new('Folder') --make the folder
saveData.Name = 'saveData' --NAME the folder
saveData.Parent = player --parent the folder
print("<<saveData FOLDER MADE>>")
----------------------------------------------------------------------
--------------------Make the Values for SaveData----------------------
----------------------------------------------------------------------
--Dragons
local dragonWhiteAmount = Instance.new('IntValue') --WHITE
dragonWhiteAmount.Name = 'DragonWhiteAmount'
dragonWhiteAmount.Parent = saveData
local dragonPinkAmount = Instance.new('IntValue') --Pink
dragonPinkAmount.Name = 'DragonPinkAmount'
dragonPinkAmount.Parent = saveData
local dragonBlackAmount = Instance.new('IntValue') --BLACK
dragonBlackAmount.Name = 'DragonBlackAmount'
dragonBlackAmount.Parent = saveData
local dragonBlueAmount = Instance.new('IntValue') --Blue
dragonBlueAmount.Name = 'DragonBlueAmount'
dragonBlueAmount.Parent = saveData
local dragonRedAmount = Instance.new('IntValue') --Red
dragonRedAmount.Name = 'DragonRedAmount'
dragonRedAmount.Parent = saveData
local dragonYellowAmount = Instance.new('IntValue') --Yellow
dragonYellowAmount.Name = 'DragonYellowAmount'
dragonYellowAmount.Parent = saveData
local dragonGreenAmount = Instance.new('IntValue') --Green
dragonGreenAmount.Name = 'DragonGreenAmount'
dragonGreenAmount.Parent = saveData
local dragonOrangeAmount = Instance.new('IntValue') --Orange
dragonOrangeAmount.Name = 'DragonOrangeAmount'
dragonOrangeAmount.Parent = saveData
local dragonPurpleAmount = Instance.new('IntValue') --Purple
dragonPurpleAmount.Name = 'DragonPurpleAmount'
dragonPurpleAmount.Parent = saveData
--Wings
local whiteWings = Instance.new('IntValue') --0 none, 1 have them
whiteWings.Name = 'WhiteWings'
whiteWings.Parent = saveData
local blueWings = Instance.new('IntValue') --0 none, 1 have them
blueWings.Name = 'BlueWings'
blueWings.Parent = saveData
local redWings = Instance.new('IntValue') --0 none, 1 have them
redWings.Name = 'RedWings'
redWings.Parent = saveData
local greenWings = Instance.new('IntValue') --0 none, 1 have them
greenWings.Name = 'GreenWings'
greenWings.Parent = saveData
local yellowWings = Instance.new('IntValue') --0 none, 1 have them
yellowWings.Name = 'YellowWings'
yellowWings.Parent = saveData
local pinkWings = Instance.new('IntValue') --0 none, 1 have them
pinkWings.Name = 'PinkWings'
pinkWings.Parent = saveData
local blackWings = Instance.new('IntValue') --0 none, 1 have them
blackWings.Name = 'BlackWings'
blackWings.Parent = saveData
local rainbowWings = Instance.new('IntValue') --0 none, 1 have them
rainbowWings.Name = 'RainbowWings'
rainbowWings.Parent = saveData
--Other
local robuxSpent = Instance.new('IntValue') --This is how much Robux the player spent, not really used for anything.
robuxSpent.Name = 'RobuxSpent'
robuxSpent.Parent = saveData
local petEquip = Instance.new('IntValue') --This remembers what baby dragon you had flying with you last.
petEquip.Name = 'PetEquip'
petEquip.Parent = saveData
-- 1=White, 2=Pink, 3=Black, 4=Blue, 5=Red, 6=Green, 7=Orange, 8=Purple, 9=Orange
local wingEquip = Instance.new('IntValue') --This remembers what wings you were wearingin last.
wingEquip.Name = 'WingEquip'
wingEquip.Parent = saveData
-- 0=None 1=White, 2=Blue, 3=Red, 4=Green, 5=Orange, 6=Pink, 7=Black, 8=Rainbow
local totalDragons = Instance.new('IntValue') --This is a count of all your dragons.
totalDragons.Name = 'TotalDragons'
totalDragons.Parent = saveData
local typeTotal = Instance.new('IntValue') --This is a count of how many dragon types you have
typeTotal.Name = 'TypeTotal'
typeTotal.Parent = saveData
local reSpawn = Instance.new('IntValue') --This is how many times you respawned. Useful for Lobby and HotSprings.
reSpawn.Name = 'ReSpawn'
reSpawn.Parent = saveData
local haveEgg = Instance.new('IntValue') --This tells what egg type you have. 0 = no egg.
haveEgg.Name = 'HaveEgg'
haveEgg.Parent = saveData
local baby = Instance.new('IntValue') --This tells what baby you hatched last. Useful for Lobby and HotSprings.
baby.Name = 'Baby'
baby.Parent = saveData
print("<<INT VALUES MADE>>")
-----------------------------------------------------------------------
------------------------------------------------------------------------
local playerUserId = 'Player_'..player.UserId
local data
local success, errormessage = pcall(function() -- load data
--data = playerData:GetAsync(playerUserId)
playerData:UpdateAsync(playerUserId, function(LoadedData)
data = LoadedData
end)
if not data or not data["HaveEgg"] then
for i = 1, SaveAttempts do
print("No data found, retying...")
wait(.5)
playerData:UpdateAsync(playerUserId, function(LoadedData)
data = LoadedData
end)
if data and data["HaveEgg"] then
break
end
end
end
end)
if success then
if data ~= nil then --****************This is a Returing Player who has Save Data******************************
print("<<DATA DETECTED READY TO LOAD>>")
--LOAD DRAGONS
dragonWhiteAmount.Value = data['DragonWhiteAmount'] or 0
dragonPinkAmount.Value = data['DragonPinkAmount'] or 0
dragonBlackAmount.Value = data['DragonBlackAmount'] or 0
dragonBlueAmount.Value = data['DragonBlueAmount'] or 0
dragonRedAmount.Value = data['DragonRedAmount'] or 0
dragonYellowAmount.Value = data['DragonYellowAmount'] or 0
dragonGreenAmount.Value = data['DragonGreenAmount'] or 0
dragonOrangeAmount.Value = data['DragonOrangeAmount'] or 0
dragonPurpleAmount.Value = data['DragonPurpleAmount'] or 0
--LOAD WINGS
whiteWings.Value = data['WhiteWings'] or 0
blueWings.Value = data['BlueWings'] or 0
redWings.Value = data['RedWings'] or 0
greenWings.Value = data['GreenWings'] or 0
yellowWings.Value = data['YellowWings'] or 0
pinkWings.Value = data['PinkWings'] or 0
blackWings.Value = data['BlackWings'] or 0
rainbowWings.Value = data['RainbowWings'] or 0
--LOAD OTHER THINGS
robuxSpent.Value = data['RobuxSpent'] or 0
petEquip.Value = data['PetEquip'] or 0
wingEquip.Value = data['WingEquip'] or 0
reSpawn.Value = 0
haveEgg.Value = data['HaveEgg'] or 0
baby.Value = data['Baby'] or 0
print("<<ALL VALUES LOADED>>")
---------------------CACULATE TOTAL DRAGONS---------------------------
totalDragons.Value = dragonWhiteAmount.Value + dragonPinkAmount.Value + dragonBlackAmount.Value +
dragonBlueAmount.Value + dragonRedAmount.Value + dragonYellowAmount.Value +
dragonGreenAmount.Value + dragonOrangeAmount.Value + dragonPurpleAmount.Value
print("totalDragons.Value is: " .. totalDragons.Value)
---------------------CACULATE TYPE TOTAL-----------------------------
typeTotal.Value = 0
if dragonWhiteAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonPinkAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonBlackAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonBlueAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonRedAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonGreenAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonYellowAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonOrangeAmount.Value > 0 then
typeTotal.Value += 1
end
if dragonPurpleAmount.Value > 0 then
typeTotal.Value += 1
end
print("typeTotal.Value is: " .. typeTotal.Value)
--------------------------------------------------------------------------------
---------------<<NO DATA, set default values Only in LOBBY!>>------------------
--------------------------------------------------------------------------------
else
print("<<NO DATA DETECTED - NEW GAME>>")
dragonWhiteAmount.Value = 0
dragonPinkAmount.Value = 0
dragonBlackAmount.Value = 0
dragonBlueAmount.Value = 0
dragonRedAmount.Value = 0
dragonYellowAmount.Value = 0
dragonGreenAmount.Value = 0
dragonOrangeAmount.Value = 0
dragonPurpleAmount.Value = 0
robuxSpent.Value = 0
whiteWings.Value = 0
blueWings.Value = 0
redWings.Value = 0
greenWings.Value = 0
yellowWings.Value = 0
pinkWings.Value = 0
blackWings.Value = 0
rainbowWings.Value = 0
petEquip.Value = 0
wingEquip.Value = 0
totalDragons.Value = 0
typeTotal.Value = 0
reSpawn.Value = 0
haveEgg.Value = 0
baby.Value = 0
print("<<DATA SET TO ZERO>>")
end
end
print("<<LOAD DATA ENDED>>")
---------------------------------------------------------------------------
----------------------------EQUIP PLAYER-----------------------------------
---------------------------------------------------------------------------
--FIRST MAKE SURE YOU HAVE A PLAYER CHARACTER LOADED
--local humanoid = player.Character:FindFirstChildOfClass("Humanoid")
local character = player.Character or
player.CharacterAdded:wait()
local humanoid
while not humanoid do
humanoid =
character:FindFirstChildOfClass("Humanoid")
if not humanoid then
character.ChildAdded:wait()
end
end
---------------------UnlimitedLives Gamepass-------------------------
local hasPass = false
local sucess, message = pcall(function()
hasPass = MarketplaceService:UserOwnsGamePassAsync(player.UserId, UnlimitedLivesID)
end)
if hasPass == true then
local item = game.ReplicatedStorage.Items:FindFirstChild("UnlimitedLives"):Clone()
item.Parent = player.Backpack
saveData:SetAttribute("HasLives", true)
player.PlayerGui:WaitForChild("buyGui").Enabled = false
else
player.PlayerGui:WaitForChild("buyGui").Enabled = true
end
--[[ --This version did not work, why?
local hasPass = false
local sucess, message = pcall(function()
hasPass = player.saveData:GetAttribute("HasLives")
end)
if hasPass == true then
local item = game.ReplicatedStorage.Items:WaitForChild("UnlimitedLives"):Clone()
item.Parent = player.Backpack
print("*************************Unlimited Lives Loaded*************************")
player.PlayerGui:WaitForChild("buyGui").Enabled = false
else
player.PlayerGui:WaitForChild("buyGui").Enabled = true
end
]]
-------------------------------WINGS----------------------------------
if whiteWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("WhiteWings"):Clone()
item.Parent = player.Backpack
end
if blueWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("BlueWings"):Clone()
item.Parent = player.Backpack
end
if redWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("RedWings"):Clone()
item.Parent = player.Backpack
end
if greenWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("GreenWings"):Clone()
item.Parent = player.Backpack
end
if yellowWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("YellowWings"):Clone()
item.Parent = player.Backpack
end
if pinkWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("PinkWings"):Clone()
item.Parent = player.Backpack
end
if blackWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("BlackWings"):Clone()
item.Parent = player.Backpack
end
if rainbowWings.Value == 1 then
local item = game.ReplicatedStorage.Items:FindFirstChild("RainbowWings"):Clone()
item.Parent = player.Backpack
end
-------------------------------EQUIP WINGS----------------------------------
-----------------------------------------------------------------------------
-- 0=None 1=White, 2=Blue, 3=Red, 4=Green, 5=Yellow, 6=Pink, 7=Black, 8=Rainbow
print("****************About to equip wings*********************")
if wingEquip.Value == 1 then
print("****************WHITE WINGS Detected*********************")
local tool = player.Backpack:FindFirstChild("WhiteWings")
humanoid:EquipTool(tool)
print("****************WHITE WINGS Equiped*********************")
elseif wingEquip.Value == 2 then
local tool = player.Backpack:FindFirstChild("BlueWings")
humanoid:EquipTool(tool)
elseif wingEquip.Value == 3 then
local tool = player.Backpack:FindFirstChild("RedWings")
humanoid:EquipTool(tool)
elseif wingEquip.Value == 4 then
local tool = player.Backpack:FindFirstChild("GreenWings")
humanoid:EquipTool(tool)
elseif wingEquip.Value == 5 then
local tool = player.Backpack:FindFirstChild("YellowWings")
humanoid:EquipTool(tool)
elseif wingEquip.Value == 6 then
local tool = player.Backpack:FindFirstChild("PinkWings")
humanoid:EquipTool(tool)
elseif wingEquip.Value== 7 then
local tool = player.Backpack:FindFirstChild("BlackWings")
humanoid:EquipTool(tool)
elseif wingEquip.Value == 8 then
local tool = player.Backpack:FindFirstChild("RainbowWings")
humanoid:EquipTool(tool)
end
-----------------------------------------------------------
---------------------PANCHOS LEADERBOARD-------------------
-------------------------LOBBY ONLY------------------------
-----------------------------------------------------------
local success, err = pcall(function()
dataStore: SetAsync(player.UserId, totalDragons.Value)
print("<<Saved PANCHOS LEADERBOARD data for " ..player.Name.. ".>>")
print("<<totalDragons.Value is for leaderboard is " ..totalDragons.Value.. ".>>")
end)
if not success then
print("<<FAILED to save PANCHOS LEADERBOARD data for " ..player.Name.. ".>>")
warn(err)
end
------------------------------------------------------------
------------------------------------------------------------
--[[
--------------------------------------------------------------------------
---------------------CREATE PET AND SET PLAYER BUTTONS--------------------
---------------------------RESCUE MISSION ONLY----------------------------
--------------------------------------------------------------------------
if player.saveData.TotalDragons.Value >= 1 then -- If I have a dragon,
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local spawnPetEvent = ReplicatedStorage.Remotes:WaitForChild('spawnPetEvent')
spawnPetEvent:Fire(player) --spawn dragon
player.PlayerGui.openMyDragonsGui.Enabled = true --give menu to see.
print("**********************Can open My Dragons****************************")
else
player.PlayerGui.openMyDragonsGui.Enabled = false
print("**********************Can NOT open My Dragons****************************")
end
player.PlayerGui.inviteGui.Enabled = false
print("**********************INVITE CLOSED****************************")
]]
-------------------------------EQUIP Egg----------------------------------
-- 0 = None 1 = Easy, 2 = Hard, 3 = Impossible
----------------------------------------------------------------------------
--Lobby
player.saveData.HaveEgg.Value = 0
--Testing
--player.saveData.HaveEgg.Value = 2
--[[
print("****************About to equip Egg*********************")
if player.saveData.HaveEgg.Value == 1 then
local Egg = game.ReplicatedStorage.EggEasy
local clonedItem = Egg:Clone ()
clonedItem.Handle. Anchored = false
humanoid: AddAccessory (clonedItem)
print("****************Easy Egg Equipped*********************")
elseif player.saveData.HaveEgg.Value == 2 then
local Egg = game.ReplicatedStorage.EggHard
local clonedItem = Egg:Clone ()
clonedItem.Handle. Anchored = false
humanoid: AddAccessory (clonedItem)
print("****************Hard Egg Equipped*********************")
elseif player.saveData.HaveEgg.Value == 3 then
local Egg = game.ReplicatedStorage.EggImpossible
local clonedItem = Egg:Clone ()
clonedItem.Handle. Anchored = false
humanoid: AddAccessory (clonedItem)
print("****************Impossible Egg Equipped*********************")
end
-------------------------------------------------------------------------
-------------------------------------------------------------------------
]]
--[[
-- autosave
while wait(AutosaveInterval) do -- autosave
SaveData(player)
end
]]
end
---------------------------------------------------------------------------
----------------------------PLAYER EXITS - SAVE DATA-----------------------
---------------------------------------------------------------------------
local function onPlayerExit(player) -- saving until no errors
local success, err = SaveData(player)
if not success then
print("<<FAILED to save onPlayerExit data for " ..player.Name.. ".>>")
warn(err)
for i = 1, SaveAttempts do
wait(.5)
local success, err = SaveData(player)
if success then
break
else
warn(err)
end
end
end
end
--------------------------------------------------------------
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
----------------------<<REMOTE SAVE>>------------------------
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local SaveGameBE = ReplicatedStorage.Remotes:WaitForChild('SaveGameBE')
SaveGameBE.Event:Connect(SaveData)