DataStore not saving in PlayerRemoving

Your data might not be saving because the server is closing while its trying to process those lines of codes. I’ve had this issue before, and usually what solves it is this bit:

game:BindToClose(function()
    wait(5)
end)

That will wait 5 seconds before actually closing the server, I believe.

Edit: Just now noticed you came to that conclusion on your own.

8 Likes

Is API enabled for that game? Data stores require the API to be enabled.

Right well, you aren’t gonna be saving any data that way. I don’t think that will actually work, and if it does, you shouldn’t be using it as it has no error checks whatsoever.
Here’s a modified version of that script. Please tell me if it works.

local DataStoreService = game:GetService("DataStoreService")
local JogoStore = DataStoreService:GetDataStore("Jogo")
local Jogo = {} -- any data inside the dictionary

game.Players.PlayerAdded:Connect(function(Player) 
local playerjogo 
local suc, err = pcall(function() 
        playerjogo = JogoStore:GetAsync(Player.UserId) or "0" --Get their jogo, or if they have none, set it to zero
end)
if suc then 
   Jogo[Player] = playerjogo 
else 
   Jogo[Player] = "ERR"
   warn("Error fetching "..Player.Name.."'s data."
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
    if Jogo[Player] == "ERR" then return end --If we couldn't get their data, we don't want to save it since it's corrupted
	local suc, err = pcall(function() 
               JogoStore:SetAsync(Player.UserId, Jogo)
    end)
if err then warn("Unable to save data for"..Player.Name) end 
end)

Sorry for the terrible formatting. The Discourse script editor is really sucky.

Thanks for you effort!
Actually, the last code I posted was just a test to confirm why the SetASync was not working, so I removed all error treatment there to clean up the code.
In short, what I realized is: SetASync will work “in-game”, without needing to use BindToClose.
And if you read that code, you’ll notice that the BindToClose is there only to force a wait if it’s inside Studio.

1 Like

@HugeCoolboy2007 is right about the game:BindToClose, however when I use that function the game still saves my data when there are only some values to change, not things to add to my MainTable.

I use game:BindToClose function like this:

game:BindToClose(function()
	for i, player in pairs(game.Players:GetChildren()) do
            -- I save player data here.
        end
end)

By saying this I mean that whenever I add more things to my game to save and I play the game in Studio, add some new currency to my account and play in Studio again- it doesn’t save (even when there’s a game:BindToClose function). If I want to make new data work in Studio, I simply join my game (not in Studio), than I play it in Studio and when it seems that the data loads correctly in Studio too.

1 Like

Are you sure? Because I got the idea for saving the player’s data when the player exits the game from the official Roblox Documentation:
https://developer.roblox.com/en-us/articles/Saving-Player-Data#save-data-on-exit

I was talking about in-studio, not in-game. Sorry, I should’ve clarified

But this will save the data for all players ONLY when the server will shutdown, ie, when the last player exits the game; I want to save the player’s data WHEN a player exits the game.

I know, that’s the proper use of the BindToClose function. I would recommend you using that function and the game:GetService(“Players”).PlayerRemoving function too.

Also, as I’m trying to say, the data DOES NOT ALWAYS saves propertly in Studio, even if DataStore Service is enabled!

Ok, so that’s the solution I put in the post:

1 Like

Why?

I don’t really know why. Try publishing the game, playing it. And now when you change values in Studio, the new changes should be applied.

The last example of me trying to make you understand, @rogeriodec_games what I mean. The reason i have (tagged?) you is to make you see this reply again because I made and edit.

The example:

  1. Game before an update. Everything saves correctly even when I change values of my coins in Studio. Here’s the table (normally I use WaitForChild() function but this is only the example):

    local ExampleTable = {
    Coins= plr.Coins.Value,
    }

  2. I relased the update of my game that adds new thing to my table (my game only had coins value before the update as you can see above, now it also has XP value in it). Here’s the table with XP:

    local ExampleTable = {
    Coins= plr.Coins.Value,
    XP = plr.XP.Value,
    }

  3. I play the game in Studio, change the value of my XP to 10000000 (why not, I’m the game developer lol) and I hit the Stop playtest button.

  4. I join Studio again. Where’s my XP??? The XP didn’t change (I don’t know why, I had DataStore Setting on).

  5. I join a game on Roblox website and give XP to my account again. I leave and join Studio. The XP is here.

  6. I change XP in Studio to 23000 (it can be whatever you like). I leave playtest, join it again and I see that the XP have updated to 23000 even if I was in Studio.

As you can see in the example, the XP data only saved when I joined my game first when the update came out. Then the Studio was able to change XP (after I joined the game on the website).

That’s it. I hope you understand. I tried to help you.


Edit: I was not that good in Roblox scripting as I am now, 6 months later. It is probably caused because what Studio does is following: it closes the server / shuts it down so the PlayerRemoving doesn’t run (only when you click ‘Stop’ button and not ‘Leave’ game button). You can use this code if you always click the ‘Stop’ button:

-- Works when you click 'Stop' button in Studio and not 'Leave' game button.

local function SaveData(player)
	-- Your SaveData function.
end

-- Listen to Player leaving the game.
game:GetService("Players").PlayerRemoving:Connect(function(player)
	if not game:GetService("RunService"):IsStudio() then
		local success = pcall(function()
			SaveData(player)
		end)
	end
end)

-- Listen to server shutting down.
game:BindToClose(function()
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local success = pcall(function()
			SaveData(player)
		end)
	end
end)

That should fix the problem.

5 Likes

Thank you so much sir, i will try and place this code onto my data save script. I will try once i get home, thank you again.

Data sometimes doesn’t save in studio is probably because it won’t save it but everything works perfectly only roblox game.
Even without the bind function it seems to work perfectly fine, the only problem about this topic is probably about their data not saving in roblox studio so i’m pretty sure the bind function stuff will help

I’m not completely sure what you mean but it’s a good practice to include the bind function in your data store code. In case a server shutdowns unexpectedly, for example. This might happen and the player removing function won’t always fire in such case. You would then end up with data lost forever and angry players. I srecommend using this function too. You can read more Devforum posts about game:BindToClose if you are not completely sure about its functionality.

Edit: Apart from the example I posted above (about the stop button in Studio), it’s still really important to use BindToClose.

After almost 3 years, better than the previous solution in this thread, I consider my solution below to be the most adequate to overcome Studio’s limitation to close the game with the Stop button and maintain the correct sequence between PlayerRemoving and BindToClose:

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.