BindToClose is working on studio but not in an actual server?

When tested in studio, everything prints and data saves as intended. When testing in server nothing saves if I’m the last person to leave. I cannot see if there’s any errors in the server because well I already left. What could be the reason for it to work on studio but not the server?

game:BindToClose(function()
	serverCLOSING = true
	-- if the current session is studio, do nothing
	--if RunService:IsStudio() then
	--	return
	--end

	print("saving player data")

	-- go through all players, saving their data
	print(Players:GetChildren())
	for _,player in ipairs(Players:GetChildren())do
		print(player)
		local playerName = player.Name
		local playerStats = game.ReplicatedStorage.PlayerStatStorage:WaitForChild(playerName)
		print(playerStats)
		if playerStats.IsRagdolled.Value == false and playerStats.IsExhausted.Value == false and playerStats.IsHeld.Value == false then
			print("SAVINGGGG")
			saveData(player,playerStats)
		end
		for _,property in ipairs(game.Workspace.BuyableProperty:GetChildren())do
			local playerStats = game.ReplicatedStorage.PlayerStatStorage:WaitForChild(playerName)
			local buildingSaved = playerStats.BuildingSaved
			if buildingSaved.Value == false and property["Mail Box"].OwnerName.Value == playerName then
				saveBuilding(playerName,player.UserId,property)
				buildingSaved.Value = true
			end
		end
		
	end
	
	wait(13)
	
	print("completed saving player data")
end)

Do you have a PlayerRemoved event instead of this? Try using that.

To build off of @ItzMeZeus_IGotHacked, when you shut down a play session in Studio, you shut the game down at the same time as your player gets booted. This is more akin to shutting down a game server than leaving it.

When all players leave a server, the server shuts down, but this doesn’t happen at the exact moment the last player leaves. As such, when your code runs, there are at that moment no more players on the server to have their data saved; consequently, the server considers its job done and moves on.

game:BindToClose() is really only useful in preventing data loss in the event of a server shutdown. Saving in all other circumstances should be done periodically and when the Players.PlayerRemoving event triggers.

@ItzMeZeus_IGotHacked
I save data periodically as well as when the player leaves.

@MysteriousVagabond
After what you said I tested and noticed that shutting down the server saves data. When it’s the last player leaving it doesn’t save. Something else I noticed is

game:BindToClose(function()

	print(Players:GetChildren())

This sometimes prints as an empty {} when testing on studio. What could be the cause of this? If this is sometimes {} that would also mean failure to save when the game shuts down sometimes.

The only thing I could think that would be causing that would be if all players manage to fully disconnect before :BindToClose() is called, but then, theoretically, that would mean your PlayerRemoving save logic should have processed everything for the players.

Perhaps something in the DataModel is becoming inaccessible when trying to save the last player in your PlayerRemoving logic? In this BindToClose() block, I see that you call WaitForChild without a timeout when looking for your players’ stats; if that object is destroyed by the time the code runs, the whole process will hang and nothing after that point (including the code for any other players in the queue) will run.