Datastore not saving

So far I have this system where it updates the leaderstat when the player touches a pad but not when they go back to a pad, the updating is done and the api is enabled. My question is, why is my datastore not saving? It keeps saying it’s 1 even when I set my value higher than that.

local ds = game:GetService("DataStoreService"):GetDataStore("Levels")
game.Players.PlayerAdded:Connect(function(plr)
	local leaderstat = Instance.new("Folder")
	leaderstat.Name = "leaderstats"
	leaderstat.Parent = plr
	local level = Instance.new("NumberValue")
	level.Name = "Levels"
	local success, dsValue = pcall(function()
		return ds:GetAsync(plr.Name)
	end)
    --I suspect its happening in this if statement
	if success then
		if dsValue then
			level.Value = dsValue
		else
			level.Value = 1
		end
	end
	level.Parent = leaderstat
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync(plr.Name, plr.leaderstats.Levels.Value)
end)

Did you set it on the server or on the client? Also, I would not recommend saving the DataStore based on the player’s name, as this will result in the player losing progress if they change their name.

1 Like

I’ll make sure to change it to their user id, but yeah its being saved on the server

You probably need to add a game:BindToClose function.

Hello, how are you doing?

Are you sure that you’re changing the value on the server, and not on the client?

Could you try running

print(game:GetService(“DataStoreService”):GetDataStore(“Levels”):GetAsync(id)) and tell me if it’s actually fetching it properly?

Also, if you’re doing this in studio do you have studio access to API services enabled?

This is for saving the data when the game shuts down.

game:BindToClose(function()
	for _,plr in pairs(game.Players:GetChildren()) do
		ds:SetAsync(plr.UserId, plr.leaderstats.Levels.Value)
	end
end)

Watch for everyone thinking I didn’t enable it or its not in the server check this rbxl file
Obby.rbxl (22.9 KB)

No need, he is already saving it on PlayerRemoving

try printing the value of levels before your if statement. The pcall() function returns success, err when the function errors, so you should get an error message if you print your levels variable.

Investigating right now. Let me see if I can find anything.

I think he has a point though, like the server shuts down when i leave since it’s in studio. I am gonna try it

1 Like

Do you have any errors or will it just not save?

BindToClose is necessary, if the server closes before saving the data it can result in data lost.

1 Like

Always use pcall when setting, removing or getting async from data store.

I just use both, just to be on the safe side

I think that would be the best thing to do, saving when a player is removed and when the server will close.

1 Like

Try this. Also you either need to kick yourself or you should test it in the actual game, because Studio datastore’s don’t work as well:

local ds = game:GetService("DataStoreService"):GetDataStore("Levels")
game.Players.PlayerAdded:Connect(function(plr)
	local leaderstat = Instance.new("Folder")
	leaderstat.Name = "leaderstats"
	leaderstat.Parent = plr
	local level = Instance.new("NumberValue")
	level.Name = "Levels"
    local data = false
	local success, dsValue = pcall(function()
		data = ds:GetAsync(plr.Name)
	end)
    --I suspect its happening in this if statement
	if success and data then
	   level.Value = data
	else
        level.Value = 1
	end
	level.Parent = leaderstat
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync(plr.Name, plr.leaderstats.Levels.Value)
end)

They do, but he’s not using game:BindToClose.
That means the server has a chance to close before the data saves, and resulting in data loss.

I did it a bit differently than you but this is how I implemented it for anyone wondering

game:BindToClose(function()
	for i=1,#game.Players:GetPlayers() do
		ds:SetAsync(game.Players:GetPlayers()[i].Name, game.Players:GetPlayers()[i].leaderstats.Levels.Value)
	end
end)
game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync(plr.Name, plr.leaderstats.Levels.Value)
end)