Save player's data when they leave

In my game, I want a player’s data to be saved when they leave. I’ve looked at other devforum posts which say to use game:BindToClose(), which hasn’t worked for me. Here is my code:

game:BindToClose(function()
	for _,plr in pairs(game.Players:GetPlayers()) do
		local playerInfo = httpService:JSONDecode(MyDataStore:GetAsync(plr.UserId)) -- gets player's data

		if playerInfo then -- if the player has data saved, then...
			playerInfo[1]["Money"] = plr.leaderstats.Money.Value -- update the money value
			playerInfo[1]["LastPlayed"] = tick() -- update the last played value
			MyDataStore:SetAsync(httpService:JSONEncode(playerInfo)) -- set the saved information to the updated table
		end
	end
end)

Let me know if I’m using this wrong. Nothing prints anywhere inside of the function

Edit: I forgot to mention, I’m testing this in studio where I’m the only person in the game, that’s why I’m using BindToClose instead of Players.PlayerRemoving

1 Like

why use a for loop to get the players data when they leave

just use game.Players.LocalPlayer.UserId, mabye that solves the problem

This isn’t a local script, this is a server script. The loop will loop through every player in the game and individually save their data

1 Like

Hopefully you know that those 2 are different. And When using BindToClose, you do also need to pair it with PlayerRemoving… Its not really a one or other, but a This and That deal (You probably know. But if you didn’t now you do)

Also you have 30 seconds to Save everyones Data when using BindToClose. It’s recommended you wrap it in a function, and call coroutine.wrap()() for each player

As for your issue. I’m not sure myself. But I wanted to give these recommendations as they are quite important. I’m not sure why you are using a GetAsync() and SetAsync() instead of UpdateAsync() (I’m pretty sure UpdateAsync could work here really well) Yea idk.

I’ve seen that on the devforum, but I never learned UpdateAsync(). I watched a video by TheDevKing and he only taught SetAsync and GetAsync, but I’m sure UpdateAsync will be good to know too. I’ll look into learning that, thank you for the feedback

I’ve made saving systems which save when a player leaves the game, but I made it this exact same way and it was working in other games. How should I combine BindToClose with PlayerRemoving?

1 Like

(I felt lazy and someone else today needed help with BindToClose, so Ima copy and paste what I said, but it explains the relationship well enough even out of context):

"Have you Tried Adding a BindToClose() set up. What I am assuming is that is datastore UpdateAsync() is on player removing. But sometimes the server shuts down before PlayerRemoving Can be called. If you are using PlayerRemoving, Player removing is fired when a player leaves, while BindToClose fires once per game, when the server shuts down. Meaning that PlayerRemoving will likely be fired many times per server, while BindToClose only ever fires once per server, when roblox needs to shutdown the server. I recommend Adding BindToClose(). There is an issue is that also it sometimes can be Fired twice (Because of player removing, and BindToClose being called before they fully left). This can be fixed By Making a table of all the players who have saved their data, and once fully done, remove them from the list (in case of rejoining the same server).

Here is a basic Set up on BindToClose() for datastores with a debounce as mentioned above:

local ListOfPlayers = {}
local function SaveData(Player)
if table.find(ListOfPlayers, Player.Name) then return end
table.insert(ListOfPlayers, Player.Name)

--Code To Save Data

repeat task.wait() until game.Players:FindFirstChild(Player.Name) == nil
table.remove(ListOfPlayers, table.find(ListOfPlayers, Player.Name))
end

game:BindToClose(function()
	for i, v in game.Players:GetPlayers() do
			coroutine.wrap(SaveData)(v)
		end
	
end)

game.Players.PlayerRemoving:Connect(function(plr)
coroutine.wrap(SaveData)(plr)
end

"

That was from the Other post someone needed help with. If you want to learn more about UpdateAsync, roblox docs is a great place! Here is a link about UpdateAsync() and it does talk about the different between :SetAsync()

Edit: Added Removing in the code block

uh you should ( must ) use player removing , bind to close is for game shutdown . hope u understand.

edit : bruh nvm saw ur edit

1 Like