Save and Load Script – works 99.9%? of the time, but sometimes FAILS and players lose all data

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve?
    I need my SaveLoad code to be 100% all the time.

  2. What is the issue? This code Loads player data on game start, and Saves player data on game exit. It works great 99.9% of the time. However, a few players have reported on my Roblox Group that they have lost all data. This is very serious because players work very hard and sometime pay Robux to have items in the game.

  3. What solutions have you tried so far?
    I am studying every YouTube tutorial I can find. I think I’m doing things correctly. I wonder if I have a basic mistake that I just can’t see. I’ve considered that maybe I’m missing a pcall in a critical place or I need a WaitForChild in a critical place? I just don’t know.

The SaveLoad script sets up a lot of things for the player on game start, so this full script may seem LONG and cluttered. However, I don’t know where the offending part is, so I’m thinking that maybe it is helpful to see the whole thing? Thank you for your help.

-------------------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 BadgeService = game:GetService('BadgeService')

--------------------<<GAME PASS IDS>>------------------------
local UnlimitedLivesID = 22712458



------------Panchos Leaderboard------------------------
local dataStore = DataStoreService:GetOrderedDataStore("Wins")
--------------------------------------------------------


-------------------------------------------------------------------
--------------------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>>**********************")
	
	local otherData = Instance.new('Folder') 	--make the folder
	otherData.Name = 'otherData' 					--NAME the folder
	otherData.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') --Robux spent
	robuxSpent.Name = 'RobuxSpent'
	robuxSpent.Parent = saveData
		
	local petEquip = Instance.new('IntValue')	--Time
	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')	--Time
	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')
	totalDragons.Name = 'TotalDragons'
	totalDragons.Parent = saveData

	local typeTotal = Instance.new('IntValue')
	typeTotal.Name = 'TypeTotal'
	typeTotal.Parent = saveData
	
	local reSpawn = Instance.new('IntValue')
	reSpawn.Name = 'ReSpawn'
	reSpawn.Parent = saveData
	
	local haveEgg = Instance.new('IntValue')
	haveEgg.Name = 'HaveEgg'
	haveEgg.Parent = saveData
	
	local baby = Instance.new('IntValue')
	baby.Name = 'Baby'
	baby.Parent = saveData
	

		
print("******************************<<INT VALUES MADE>>*********************************")
	
	
	local WhatSal = Instance.new('IntValue')
	WhatSal.Name = 'WhatSal'
	WhatSal.Parent = otherData
	WhatSal.Value = 0
print("******************************<<What Sal Set to Zero>>*********************************")
-----------------------------------------------------------------------	
------------------------------------------------------------------------	
	
	
	local playerUserId = 'Player_'..player.UserId
	
	
------------------------------------------------------------------------------------
	--***********DEBUG Crazy DELETE ALL PLAYER DATA**********************
	--playerData:RemoveAsync(playerUserId)
	--print("****************<<Crazy Debug DATA ERASED>>*****************************")
--------------------------------------------------------------------------------------
	
	
	local data
	local success, errormessage = pcall(function()
		data = playerData:GetAsync(playerUserId)
	end)
	
	if success then
	
		if data ~= nil then  --*********************Returing player to game**********************************
			
			print("****************************<<DATA DETECTED READY TO LOAD>>*******************************")
			
	--LOAD Dragon Data
			dragonWhiteAmount.Value = data['DragonWhiteAmount']
			print("******************************dragonWhiteAmount.Value loaded as: " .. dragonWhiteAmount.Value)
			dragonPinkAmount.Value = data['DragonPinkAmount']
			print("******************************dragonPinkAmount.Value loaded as: " .. dragonPinkAmount.Value)
			dragonBlackAmount.Value = data['DragonBlackAmount']
			print("******************************dragonBlackAmount.Value loaded as: " .. dragonBlackAmount.Value)
			dragonBlueAmount.Value = data['DragonBlueAmount']
			print("******************************dragonBlueAmount.Value loaded as: " .. dragonBlueAmount.Value)
			dragonRedAmount.Value = data['DragonRedAmount']
			print("******************************dragonRedAmount.Value loaded as: " .. dragonRedAmount.Value)
			dragonYellowAmount.Value = data['DragonYellowAmount']
			print("******************************dragonYellowAmount.Value loaded as: " .. dragonYellowAmount.Value)
			dragonGreenAmount.Value = data['DragonGreenAmount']
			print("******************************dragonGreenAmount.Value loaded as: " .. dragonGreenAmount.Value)
			dragonOrangeAmount.Value = data['DragonOrangeAmount']
			print("******************************dragonOrangeAmount.Value loaded as: " .. dragonOrangeAmount.Value)
			dragonPurpleAmount.Value = data['DragonPurpleAmount']
			print("******************************dragonPurpleAmount.Value loaded as: " .. dragonPurpleAmount.Value)
			
	--LOAD Other things
			
			whiteWings.Value = data['WhiteWings']
			blueWings.Value = data['BlueWings']
			redWings.Value = data['RedWings']
			greenWings.Value = data['GreenWings']
			yellowWings.Value = data['YellowWings']
			pinkWings.Value = data['PinkWings']
			blackWings.Value = data['BlackWings']
			rainbowWings.Value = data['RainbowWings']
	
			robuxSpent.Value = data['RobuxSpent']
			print("******************************robuxSpent.Value loaded as: " .. robuxSpent.Value)

			petEquip.Value = data['PetEquip']
			wingEquip.Value = data['WingEquip']
			
			totalDragons.Value = dragonWhiteAmount.Value + dragonPinkAmount.Value + dragonBlackAmount.Value +
				dragonBlueAmount.Value + dragonRedAmount.Value + dragonYellowAmount.Value + 
				dragonGreenAmount.Value + dragonOrangeAmount.Value + dragonPurpleAmount.Value
			
			print("******************************ON LOAD totalDragons.Value is: " .. totalDragons.Value)
			
			reSpawn.Value = 0
			
			haveEgg.Value = 0
			--haveEgg.Value = data['HaveEgg']
			
			baby.Value = data['Baby']
			
			print("******************************<<ALL VALUES LOADED>>*********************************")
			
	
			
			---------------------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)
					
			
		else --*******************************NO DATA, set default values!******************************
			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
			
			print("******************************DATA SET TO ZERO*********************************")
			
		end
	end
	
-----------------------------------------------------------
---------------------PANCHOS LEADERBOARD-------------------
	
	
	local success, err = pcall(function()
		
		dataStore: SetAsync(player.UserId, totalDragons.Value)
		print("*****************Saved PANCHOS LEADERBOARD data for " ..player.Name.. ". ********************")
		print("*****************totalDragons.Value is " ..totalDragons.Value.. ". ********************")
	end)

	if not success then
		print("*****************FAILED to save PANCHOS LEADERBOARD data for " ..player.Name.. ". ********************")
		warn(err)
	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
		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
	
end
	

---------------------------------------------------------------------------
----------------------------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


---------------------------------------------------------------------------
----------------------------PLAYER EXITS - SAVE DATA-----------------------
---------------------------------------------------------------------------

local function onPlayerExit(player)

	
	local player_stats = create_table(player) --call MAKE THE TABLE
	local success, err = pcall(function()
		local playerUserId = 'Player_'..player.UserId
		playerData:SetAsync(playerUserId, player_stats)
		print("*****************Saved onPlayerExit data for " ..player.Name.. ". ********************")
	end)
	
	if not success then
		print("*****************FAILED to save onPlayerExit data for " ..player.Name.. ". ********************")
		warn(err)
	end
	
end

-------------------------------Bind to close never worked, so I commented it out-------------------------------

--[[--BindToClose
game:BindToClose (function()  --Runs whenver the server is about to shut down/stop.
	print ("STOPPED!")
	
	for i, player in pairs(game.Players:GetPlayers()) do
		local player_stats = create_table(player) --call MAKE THE TABLE
		local success, err = pcall(function ()
			local playerUserId = 'Player_'..player.UserId
			playerData:SetAsync(playerUserId, player_stats)
			print("Saved BindToClose data for "..player.Name)
		end)
		
		if not success then
			warn ('BindToClose failed to save data for '..player.Name)
			
		end
	end
end)
]]

game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)

Have you tryied to inspect the DataStore versioning system?

Found this thread that pretty much solves that issue

1 Like

Thank you both!

@welololo. Thank you for all this information!!! I will spend a bit of time, slowly going over your notes so I can begin to learn how to implement. Thank you for explaining bind to close and that I do not need it in game. I will close this thread now, because it will be a while for me to implement and test all this information, because data stores are challenging for me to understand. Thank you so much!!