Data store doesn't save

Frist, enable API mode in the studio.


After change playerRemoving for game:BindToClose() (BindToClose are better like, if your shutdown your game for whatever reason this will call BindToClose and playerRemoving don’t) and try it on roblox becose on studio the data saving have by disabled so this is normally giving you a error that you can avoid by seeing if the game is in the studio and if it is, don’t even try to save
https://developer.roblox.com/en-us/api-reference/function/RunService/IsStudio
Here a small exemple

	if not game:GetService("RunService"):IsStudio() then
	for i, player in pairs(game.Players:GetPlayers()) do
		saveValues(player)
	end
	else
		warn("Stage not save Studio Detected")
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	if not game:GetService("RunService"):IsStudio() then
	saveValues(player)
	else
		warn("Stage not save Studio Detected")
	end
end)

As for saving try a script in this style

local function saveValues(player)
	local saveData = {}
	local StatsFile = player.leaderstats

	for i,v in pairs(StatsFile:GetChildren()) do
			saveData[#saveData + 1] = v.Name
			saveData[#saveData + 1] = v.Value
	end
	ds:SetAsync(player.UserId, saveData)
end

@RoBoPoJu and @reygenne1 we have already listed some element of what I just said
Also, there is DataStore2 which was created by (I can’t find the source so I won’t say anything)

Are you testing this in Studio? If so, enable Studio Access to API Services.

I’m sorry but I don’t know how to use game:BindToClose(), also I had never seen a developer use this function for alt PlayerRemoving

You can check the developer hub what you can use it for, it’ll tell you that it is probably a function, property, etc.

Just checked the developer hub and it’s a function of data model.

Ok now it works, but it only saves my data while I am in studio. When I tried to play the game, it doesn’t save my data there.

This is the code now,

local DSS = game:GetService("DataStoreService")
local ds = DSS:GetDataStore("CashAndWins")
local run = game:GetService("RunService")

game.Players.PlayerAdded:Connect(function(plr)
	local folder = Instance.new("Folder",plr)
	folder.Name = "leaderstats"
	
	local cash = Instance.new("IntValue",folder)
	cash.Name = "Cash"
	
	local id = plr.UserId
	
	local data
	local success, errormessage = pcall(function()
		data = ds:GetAsync(id)
	end)
	
	if success then
		print("Successfully obtain data!")
		cash.Value = data
	else
		warn("Failed to load ata.")
	end
end)

game:BindToClose(function()
	print("hi")
	
	if not run:IsStudio() then
		for i,v in pairs(game.Players:GetChildren()) do
			local data = v.leaderstats.Cash.Value
			
			local success, errormessage = pcall(function()
				ds:SetAsync(v.UserId,data)
			end)
			
			if success then
				print("yes")
			end
		end
	end
end)

Why are you using BindToClose, but not PlayerRemoving event? BindToClose runs when the game is going to shut down, PlayerRemoving runs when a player is going to leave the game.

This thread here is really useful as you seem to be pretty confused in what both of them do specifically:

1 Like

They literally told me to use BindToClose instead of PlayerRemoving.

You must use both. Not just one.

We here on the developer forum, can only give the advice/solution, writing the script is actually your work after understanding what we say.

So everything that I can do is guide you, I would say you should use the player removing function and the BindToClose event for saving, and also have a look at the thread I gave in my last reply and as a side note always Ensure that API Services are turned on for the DataStores to work in studio.

1 Like

I still don’t understand the meaning of using both of the functions at the same time.

BindToClose runs prior to the game shutting down, so that is when you need to save all the players data before the server shuts down.

PlayerRemoving is used when player is leaving the game, so that is used to save that specific player’s data.

So why you basically use BindToClose is stated in the thread I had sent earlier (I believe you still haven’t read it.)

It said that when one of these 3 events happen:

  • The last player leaves
  • The developer manually shut them down via the game page
  • A network error is encountered and the server is forced to shut down

In these cases, the PlayerRemoving event listener is never called or doesn’t finish.

So this is where BindToClose comes in use.

What do you mean saving a specific player’s data?

Then if a player leaves the server, everyone’s data could be saved. So why do I still need the PlayerRemoving event?

I don’t think you are understanding the thing, or maybe my explanation is bad. I will try once more:

What the PlayerRemoving Event Does:
The PlayerRemoving event fires right before a Player leaves the game. So suppose you join a game, and then leave 2 minutes later, this event will be fired, until and unless you were the last player to leave, or the developers shut down the game or some network error was faced and the server was shut downed

What the BindToClose Event Does:
This event function is run prior to the game server being shut downed not when a player leaves, so for example: if a player leaves and there are still players in the server this event would not be run. So this is useful when the game Server shutdowns for some reason / The last player leaves the game.

If none of the player leaves the game, then why will it fired? Now I’ve understand the BindToClose function well.

What do you mean? Anytime a player is leaving the game PlayerRemoving event is fired, the only exceptions when it doesn’t run are:

  1. The Last Player in the server is leaving
  2. Server Shutdowns for some reason.

And this is when BindToClose comes in action.

Sorry, ive looked at the message wrongly, but however, even though I used PlayerRemoving event to save a player’s data, it still doesn’t work. I’ve made sure I spelt correctly. Is it because I’m in studio? Will it work when I’m playing in the game or Will it work as well if I play in studio?

I believe if you have created the PlayerRemoving and BindToClose functions properly, it should work. Could you post your lastest code after you make the changes?

The problem is that you just set the value to a dictionary containing the values, not the saved value it self. Since you save cash inside data, you would have to index cash inside the dictionary since dictionary are key-value pairs.

int.Value = data.Cash

If you print data, it would print the memory address at where it is located.

Now your telling me to use 2 functions at the same time. I’m very confused now.

Sorry, I don’t understand what you’re trying to say. I’ve learnt from other youtubers and they did the same thing as well.