My stats not saving

Hi,

I tried everything, even turning on API, but my stats won’t save. How do I fix this?

This is a regular script in ServerScriptService named “Save”

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.UserId
	local saves = plr.leaderstats.Money
	local Save = ds:SetAsync(plrkey)
	
	if Save then
		saves.Value = Save[1]
	else
		local numbersave = {saves.Value}
		ds:SetAsync(plrkey, numbersave)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value})
end)
3 Likes

You are using SetAsync in PlayerAdded, you need to use GetAsync to read the saved data.

1 Like

So which line do I change to GetAsync?

The SetAsync in PlayerAdded as shown above

1 Like

Oh, I did that.

Is this correct:

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.UserId
	local saves = plr.leaderstats.Money
	local Save = ds:GetAsync(plrkey)
	
	if Save then
		saves.Value = Save[1]
	else
		local numbersave = {saves.Value}
		ds:GetAsync(plrkey, numbersave)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value})
end)
1 Like

This part would need to be SetAsync
GetAsync = READ from DataStore
SetAsync = WRITE to DataStore

1 Like

Ohh okay. But when player is removed, it writes to datastore, right?

Here’s what I have now:

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.UserId
	local saves = plr.leaderstats.Money
	local Save = ds:GetAsync(plrkey)
	
	if Save then
		saves.Value = Save[1]
	else
		local numbersave = {saves.Value}
		ds:SetAsync(plrkey, numbersave)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value})
end)
1 Like

Yes, that looks correct now.
Once more thing to note, if your testing this in studio then sometimes it fails to catch the PlayerRemoving before the test has shut down, so you could also add a BindToClose to make sure the data is saved before it’s shut down.

game:BindToClose(function()  for _, plr in pairs(game.Players:GetPlayers()) do ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value}) end end)

so your full script:

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.UserId
	local saves = plr.leaderstats.Money
	local Save = ds:GetAsync(plrkey)
	
	if Save then
		saves.Value = Save[1]
	else
		local numbersave = {saves.Value}
		ds:SetAsync(plrkey, numbersave)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value})
end)

game:BindToClose(function() for _, plr in pairs(game.Players:GetPlayers()) do ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value}) end end)
1 Like

I see, so like this:

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.UserId
	local saves = plr.leaderstats.Money
	local Save = ds:GetAsync(plrkey)
	
	if Save then
		saves.Value = Save[1]
	else
		local numbersave = {saves.Value}
		ds:SetAsync(plrkey, numbersave)
	end
end)

game:BindToClose(function()  for _, plr in pairs(Players:GetPlayers()) 
	do ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value}) end 
end)

The problem is player’s red underlined.

image

1 Like

Yeah, I edited my post to reflect that you hadn’t set up Players variable.
Just change Players:GetPlayers() to game.Players:GetPlayers()

It’s still not saving :frowning: I’m not sure what im doing wrong.

I also see this in output:
image

1 Like
local DataStore = game:GetService("DataStoreService"):GetDataStore("SaveData")
game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrid = "id_"..plr.UserId
	local saveMoney = plr.leaderstats.Money
	
	local GetSaved = DataStore:GetAsync(plrid)
	if GetSaved then
		saveMoney.Value = GetSaved[2]
	else
		local NumberForSaving = {saveMoney.Value}
		DataStore:GetAsync(plrid, NumberForSaving)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	DataStore:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value})
end)

Try this, and let me know if it works.

I just checked your code and run it here and it saved as it should.
That error is just because the SetAsync was called more than once to quickly for the same player (caused by the BindToClose) so that’s nothing to worry about for now.

It’s not saving for me, Idk what im doing wrong.

1 Like

It saved for you? Why isn’t it saving for me…

1 Like

plr.leaderstats.Money

Where are you setting up the Money instance?
Do you have another PlayerAdded event somewhere?

This is what I have.

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.UserId
	local saves = plr.leaderstats.Money
	local Save = ds:GetAsync(plrkey)
	
	if Save then
		saves.Value = Save[1]
	else
		local numbersave = {saves.Value}
		ds:SetAsync(plrkey, numbersave)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value})
end)

game:BindToClose(function() for _, plr in pairs(game.Players:GetPlayers()) do ds:SetAsync("id_"..plr.UserId, {plr.leaderstats.Money.Value}) end end)
1 Like

See my previous post above.
If you have another PlayerAdded event connected elsewhere to set up the leaderstats folder for the player then it could be causing an issue. It’s best to do it all in the same event.

Ohh, ok. I’ll check and see which one’s interfering.

1 Like

Maybe try publishing your game and testing it from the actual roblox player - and not studio like how @ZombieCrunchUK said here