DataStore saving more than supposed to on game:BindToClose(function()

I’ve recently noticed that once i shutdown the game data saves more than supposed to, It works perfectly fine when the player is leaving etc. How would i fix this or Find an alternate method for saving on game shutdown.

/BindToClose Script\

game:BindToClose(function()

for _, player in pairs(Players:GetPlayers()) do
	print(player.Name)
	sub(function()
		SaveData(player)
	end)
	wait()
end

wait(5)
end)

/Player Leaving Script\

Players.PlayerRemoving:Connect(function(plr)
if isShutdown then return end

SaveData(plr)
end)

/Main Script\

local function SaveData(plr)
if RunService:IsStudio() then return end

print(plr.Name.." DataSaved")

local MaxRetries = 3

local Stats = PlayersData:FindFirstChild(plr.UserId)

if not Stats then return end
if not Stats:FindFirstChild("Ready") then return end

local DataTable = {}

for i,v in pairs(Stats:GetChildren()) do
	if not v:IsA("Folder") and v.Name ~= "Ready" and v.Name ~= "Bypass" and v.Name ~= "AEBypass" then
		DataTable[v.Name] = v.Value
	end
end

local QuestTable = {}
for i,v in pairs(Stats.Quest:GetChildren()) do
	QuestTable[v.Name] = v.Value
end
DataTable["Quest"] = QuestTable

local ItemsTable = {}
for i,v in pairs(Stats.Items:GetChildren()) do
	table.insert(ItemsTable, v.Name)
end
DataTable["Items"] = ItemsTable

for i = 1, MaxRetries do
	local success, err = pcall(function()
		DataStore:UpdateAsync("Player-"..plr.UserId, function()
			return DataTable
		end)
	end)
	
	if success then
		break
	end
end

end

So first, why are you using a BindToClose and a PlayerRemoving (PlayerRemoving because superior in this case) then, you’re saving every player’s data when one player leaves the game. You could simply just save the player (who left)'s data with the PlayerRemoving.

Why do you have a sub function?

Just in case the server shuts down

kick the players on the closing function that should fix it

game:BindToClose(function()

for _, player in pairs(Players:GetPlayers()) do
	print(player.Name)
	player:Kick()
	wait()
end

wait(5)
end)
1 Like

You can try using UpdateAsync on bind to close, then check if the old data is the same thing as the data you are going to save. example:

local DSS = game:GetService("DataStoreService")
local myData = DSS:GetGlobalDataStore("Hello")
local removePlayer(player)
     -- I will only show the update async, secure methods are with you.
     myData:UpdateAsync("PlayerData"..player.UserId, function(oldData)
             -- Lets say I want to save "points" thats inside leaderstats so we do this
             if oldData == player.leaderstats.points.Value then
                   return nil
                   -- Prevents updating.
             end
             return player.leaderstats.points.Value
     end)
end
game:BindToClose(function()
 for i,v in pairs(game.Players:GetPlayers()) do
      removePlayer(v)
end
end)

There is no reason the server would shutdown without firing PlayerRemoving but firing BindToClose. Or the other way around.