Data saving does not work when a player is disconnected?

For the past few weeks now I have been receiving reports of players loosing data and I have no idea why… Im unable to reproduce it, however one person said they disconnected and lost data. Does disconnecting like stop the server from saving data?

Heres my code (Pls have a run through my code if you can to make sure im not doing anything wrong thx! c:)

game.Players.PlayerRemoving:connect(function(plr)
	if game.ServerStorage.ShuttingDown.Value == false then
		if plr:FindFirstChild("ForceFieldOn") then
			local force = plr.ForceFieldOn.Value
			local cfram = plr.CharPos.Value
			local f6 = plr.OresF
			local f7 = plr.Weapons
			if force == false then
				for i,x in pairs(f6:GetChildren()) do
					if x.Value > 0 and x.Name ~= "Hover Craft Remains" then
						local value = x.Value
						local ore = game.ReplicatedStorage.OreDrops:FindFirstChild(x.Name)
						for i=0,value-1 do
							local clonedore = ore:Clone()
							clonedore.Parent = workspace
							script.OrePickUp:Clone().Parent = clonedore
							clonedore.CFrame = cfram
							clonedore.OrePickUp.Disabled = false
							game:GetService("Debris"):AddItem(clonedore,90)
						end
						x.Value = 0
					end
				end
				for i,x in pairs(f7:GetChildren()) do
					if x.Name ~= "Pickaxe" and x.Name ~= "Hover-Craft" then
						local store = game.ReplicatedStorage.Weapons:FindFirstChild(x.Name)
						local ores = store.Ores
						for v,q in pairs(ores:GetChildren()) do
							local value = q.Value*0.75
							value = math.floor(value)
							local ore = game.ReplicatedStorage.OreDrops:FindFirstChild(q.Name)
							for i=0,value-1 do
								local clonedore = ore:Clone()
								clonedore.Parent = workspace
								script.OrePickUp:Clone().Parent = clonedore
								clonedore.CFrame = cfram
								clonedore.OrePickUp.Disabled = false
								game:GetService("Debris"):AddItem(clonedore,90)
							end	
						end
						x:Destroy()
					end
				end
				game.ReplicatedStorage.NormalNotifaction:FireAllClients(""..plr.Name.." has died!")
			end
		end
		game.ReplicatedStorage.AlertAll:FireAllClients(""..plr.Name.." has left the game!",Color3.new(1,1,1))
		local car = nil
		for i,x in pairs(game.Workspace:GetChildren()) do
			if x.Name == "Car" then
				if x.Owner.Value == plr then
					car = x
				end
			end
		end
		if car ~= nil then
			car:Destroy()
		end
		local placed = {}
		local itemz = {}
		local base = nil
		local plrname = plr.Name
		local s60 = 0
		local num = 0
		for i,x in pairs(plr.Items:GetChildren()) do
			local tab = {
				ItemName = x.Name,
				Amount = x.Amount.Value,
				Level = x.Level.Value,
			}
			table.insert(itemz,tab)
		end
		for i,x in pairs(plr.TimeFrameSaves:GetChildren()) do
			s60 = s60 + x.Value
			num = num + 1
		end
		s60 = s60 / num
		for i,x in pairs(game.Workspace:GetChildren()) do
			if x:FindFirstChild("Owner") then
				if x.Owner.Value == plrname then
					base = x
				end
			end
		end
		local Orez = {}
		for i,x in pairs(plr.OresF:GetChildren()) do
			local tab = {
				OreName = x.Name,
				Amount = x.Value,
			}
			table.insert(Orez,tab)
		end
		local Codez = {}
		for i,x in pairs(plr.Codes:GetChildren()) do
			table.insert(Codez,x.Name)
		end
		base.Ores:ClearAllChildren()
		base.Owner.Value = ""
		local hotkeys = {}
		for i,x in pairs(plr.HotKeys:GetChildren()) do
			local tab = {
				NameVal = x.Name,
				HotKey = x.Value,
			}
			table.insert(hotkeys,tab)
		end
		local Weaponz = {}
		for i,x in pairs(plr.Weapons:GetChildren()) do
			local tab = {
				WeaponName = x.Name,
			}
			table.insert(Weaponz,tab)
		end
		for i,x in pairs(base.ItemHolder:GetChildren()) do
			
			local function encodeCFrame(cf)
	   			return {cf:components()}
			end

				
			local tab = {
				ItemName = x.Name,
				Pos = encodeCFrame(base.Baseplate.CFrame:toObjectSpace(x:GetPrimaryPartCFrame())),
			}
			table.insert(placed,tab)
		end
		local Upgrades = {}
		for i,x in pairs(plr.HoverCraftUpgrades:GetChildren()) do
			local newnewtab = {
				UpgradeName = x.Name,
				Level = x.Value,
			}
			table.insert(Upgrades,newnewtab)
		end
		local Cannonz = {}
		for i,x in pairs(plr.Cannons:GetChildren()) do
			table.insert(Cannonz,x.Name)
		end
		local LockedItemz = {}
		for i,x in pairs(plr.LockedItems:GetChildren()) do
			table.insert(LockedItemz,x.Name)
		end
		base.ItemHolder:ClearAllChildren()
		local plruser = plr.UserId
		local gems = plr.leaderstats.Gems.Value
		local time1 = plr.GoldMemberShipTime.Value
		local cash = plr.Money.Value
		local lifes = plr.leaderstats.Lifes.Value
		local cannon = plr.CurrentCannon.Value
		local limit = plr.OreLimit.Value
		local tab = {
			Cash = cash,
			Gems = gems,
			Placed = placed,
			Life = lifes,
			Membership = time1,
			PlayedBefore = true,
			PrevTime = os.time(),
			AvarageCash = s60,
			HotKeys = hotkeys,
			Ores = Orez,
			Weapons = Weaponz,
			HoverCraftUpgrades = Upgrades,
			CurrentCannon = cannon,
			Cannons = Cannonz,
			LockedItems = LockedItemz,
			OreLimit = limit,
		}
		maind:SetAsync(plruser,tab)
		itemd:SetAsync(plruser,itemz)
		codes:SetAsync(plruser,Codez)
	end
end)

Disconecting should not cause any data loss. Disconnection happens on the client’s end, not the server’s end, so the server shouldn’t be affected at all.

It could be that the server is having issues, though? Are you sure people are saying disconnected? A server being shutdown instantly could be the cause of the issue - which would be on Roblox’s end.

I think that is the case with roblox shutting down the game as I can not reproduce this bug myself and it happens very randomly.

1 Like

Also save data on BindToClose.

BindToClose is only used for the game shutting down via “Shut down game” button am a right?

Players are constantly loosing data and I have NO idea why…

You’re not wrapping your SetAsync calls in pcall to shield them from errors. If any of these fail, the subsequent SetAsyncs won’t go through.

You also have issues where you are not saving data consistently. If the first SetAsync works but the other two don’t, this player now has a different version of their save data in maind compared to itemd and codes. I don’t know if that matters, but that could be an issue if there are relations between these 3 data sources that need to be updated consistently.

Furthermore, you don’t seem to be saving any player data when ShuttingDown.Value == true. I don’t know what this means in your game though.

No. Also when a server does not have any players left.

does pcall stop all errors and allow the code to run away, becuase if it does not, it would not save data because of the error.

ShuttingDown.Value is nothing, just an old value I will get rid of pretty soon.

Becuase pcalls just tell you the errors and tell you if it was successful or not, they dont run the command bug free, so how would I make it so if there is an error it still works?