Having issues with datastore

Hey!
I am trying to make a simple datastore that will store the player’s cash and level.
The cash works just fine, it stores everytime, but for some reason the level never stores, everytime at print(dsLevel:GetAsync(player.UserId)) it prints 1.

local DataStore = game:GetService("DataStoreService")
local ds = DataStore:GetDataStore("CashSaveSystem")
local dsLevel = DataStore:GetDataStore("LevelSaveSystem")



game.Players.PlayerAdded:connect(function(player)
 local leader = Instance.new("Folder",player)
 leader.Name = "leaderstats"
 local Cash = Instance.new("IntValue",leader)
 Cash.Name = "Cash"
 Cash.Value = ds:GetAsync(player.UserId) or 0
 ds:SetAsync(player.UserId, Cash.Value)
 Cash.Changed:connect(function()
  ds:SetAsync(player.UserId, Cash.Value)
 end)
 local Level = Instance.new("IntValue",player:WaitForChild("leaderstats"))
 Level.Name = "Level"
 print(dsLevel:GetAsync(player.UserId))
 Level.Value = dsLevel:GetAsync(player.UserId) 
 Level.Changed:connect(function()
  dsLevel:SetAsync(player.UserId, Level.Value)
 end)
end)

game.Players.PlayerRemoving:connect(function(player)
 ds:SetAsync(player.UserId, player.leaderstats.Cash.Value)
 dsLevel:SetAsync(player.UserId, player.leaderstats.Level.Value)
end)
1 Like

This could be due to the sever closing before the level gets a chance to save, looking it to this might be helpful: https://developer.roblox.com/en-us/api-reference/function/DataModel/BindToClose

Also I would recommend looking into UpdateAsync or even IncrementAsync

But it also saves everytime the level value changes, But thanks I will have a look at it.

Please don’t save everytime the level changes because you will end up eating through your data store budget very quickly. Data can only be saved every 6 seconds to stay within the limits. I would take a look at this developer hub page about data store limits: https://developer.roblox.com/en-us/articles/Datastore-Errors


The most obvious reason why your data could be not saving properly is because you are going over your data store limits. As described above you are saving each time the level changes which could eat through your budget very quickly. The next this is that you currently have 2 data stores per player which can also rack up your data store calls very quickly if you are not careful.

To fix this you should look into saving all your data under one big table to try and limit the amount of calls you do. To save your data you should should look into keeping a cache of your data somewhere(such as a folder or a table). Then you either make an auto save mechanic to save your data directly from the values in the cache. Alternatively you could save the players data when they leave providing you first check if the players data has loaded.

The next reason why your data may not be saving is because it may be failing to save. Data store calls occasionally fail at no fault of the developer so you should rap each call in a pcall. Using pcall will allow you to track whether the call failed and then do the required actions if it does.

Lastly you shouldn’t be using SetAsync to save data because it can be hazardous according to the developers hub. Instead you should be using UpdateAsync or IncrementAsync. You should take a look this tururial about using UpdateAsync rather than SetAsync: Stop using SetAsync() to save player data.

2 Likes

Thanks!
It seems to work good now.

so to get the data store you have to do this
so like this ds:GetAsync(player.UserId, Cash.Value) or 0

and to put the level in the leaderboard all you do is , leader so like this

local level = Instance.new(“IntValue”, leader)

and set both the cash instances closest to the leader

and for the saving you have to wrap it in a pcall like this

game.Players.PlayerRemoving:connect(function(player)
local success, errormessage = pcall(function()
ds:SetAsync(player.UserId, player:WaitForChild(“leaderstats”):WaitForChild(“Cash”).Value)
dsLevel:SetAsync(player.UserId, player:WaitForChild(“leaderstats”):WaitForChild(“Level”).Value)
end)
if success then
print(“Success”)
elseif errormessage then
print(“errormessage”)
end
end
end)
end)