I’ve had people report to me quite often that they’re losing data when crashing. The DataStore code used in all the game’s places is below. Is there anything i could do to improve it and decrease the rate of data loss? This is not the entire script. I removed parts of the script, such as the creation of the values.
local RS = game.ReplicatedStorage
local MainData=game:GetService("DataStoreService"):GetDataStore("MainData")
function AttemptGetAsync(key)
local data
local success, msg = pcall(function()
data = MainData:GetAsync(key)
end)
return success, data
end
function Load(key,Folder)
local Tries = 0
local success, data
repeat
wait()
success, data = AttemptGetAsync(key)
Tries = Tries + 1
until Tries > 3 or success
local CanSave = Instance.new("BoolValue")
CanSave.Name = "CanSave"
CanSave.Parent = Folder
if success then
CanSave.Value=true
else
CanSave.Value = false
end
if data then
for i, v in pairs(data.Character) do
Folder.Character[i].Value = v.Value
end
for i, v in pairs(data.Stats) do
Folder.Stats[i].Value = v.Value
Folder.Stats[i].Xp.Value = v.Xp
end
end
end
function Save(key,Folder)
local MainTable = {}
MainTable.Character = {}
MainTable.Stats = {}
for i, v in pairs(Folder.Character:GetChildren()) do
local tab = {
Value = v.Value
}
MainTable.Character[v.Name] = tab
end
for i, v in pairs(Folder.Stats:GetChildren()) do
local tab = {
Value =v .Value,
Xp = v.Xp.Value
}
MainTable.Stats[v.Name] = tab
end
local success, msg = pcall(function()
MainData:SetAsync(key,MainTable)
end)
return success
end
game.Players.PlayerAdded:Connect(function(plr)
local key = plr.userId .. "data"
local Folder = Instance.new("Folder")
Folder.Name = plr.Name
Folder.Parent = RS
local Stats = Instance.new("Folder")
Stats.Name = "Stats"
Stats.Parent = Folder
local Character = Instance.new("Folder")
Character.Name = "Character"
Character.Parent = Folder
Load(key, Folder)
end)
game.Players.PlayerRemoving:Connect(function(plr)
local key = plr.userId .. "data"
local Folder = RS[plr.Name]
if Folder:FindFirstChild("CanSave") then
if Folder.CanSave.Value == true then
local success = Save(key, Folder)
if success then
Folder:Destroy()
else
Save(key, Folder)
Folder:Destroy()
end
end
end
end)
game:BindToClose(function()
wait(3)
end)
The part of your code in which values are created is also kind of important to figure out what the problem is. There’s not enough information though, here, for me to solve the issue (someone else may be able to). What specifically is going on? Are your requests getting throttled? Is there an error in your code somewhere? Is data outright not saving?
And on the topic of crashing, how often are we talking? Is it a problem of the game itself or their own computer/network?
An immediate solution I can think of (it’s 5:20 AM EST right now) is to autosave in intervals every now and then. Keeps data relatively fresh every now and then plus you don’t have to worry too much about missing data due to only saving when a player enters and leaves.
I’ll see what I can do without the above provided.
There is not an error in the code. I also can’t see a reason for the requests to be throttled. This has never happened with me being present, so it’s very hard for me to provide specific information. According to the reports, players both lose their data completely and up to the last time their data was successfully saved. I’d also like to say the crashing is caused by the computer/network of the player rather than the game. I will take your suggestion and have it autosave here and there to minimize possible losses.
Well, it so seems that I unfortunately do not have a response to give aside from the auto save function I mentioned earlier. I use relatively the same code and don’t have issues with users crashing or the like.
As far as this script goes, it seems to be working fine. I suggest you hop this over to #development-support:requests-for-code-feedback (the new category) to see if anyone will be able to help you with the issue. This is the workflow I go with saving data:
PlayerAdded
Create data files, whether that’s internally or through physical values
Get player data; if that data doesn’t exist, use default data and set their current data to the defaults
Alert other scripts that their data has been ready (a spoof of the old WaitForDataReady)
PlayerRemoving
Check if player hasn’t had any data interactions in the last 10 seconds to respect limitations
Check if player should be allowed to save, to not waste my budget for any request type
Use a custom function “WaitForRequestBudget” that yields thread until request type budget is not 0
Save data through UpdateAsync (I don’t like SetAsync anymore)
Remove any references to the data and player (nullifying a table or deleting physical objects)
Background
Auto save function every 45 seconds that runs through all players and calls the Save function*
* I keep the Save function separate rather than putting it directly in any of the above three slots because then I can use it multiple times. I’ll usually include an argument called “PlayerLeaving” which will determine if the player is leaving or not; if it’s true, it will run the cleanup protocol after saving, otherwise it’ll only save.
If you are absolutely sure there should be no problem with your data stores and the code you’re using is fine, then it may be an issue on Roblox’s backend. This should prompt you to file a bug report.
I personally haven’t experienced any data loss issues yet but that’s primarily because I haven’t used data stores recently. Story for another time.
If it makes you feel better, I’ve had people reporting data loss from phantom forces, and our system is setup very well to ensure no data loss, the only thing i can think of is servers are crashing. I am planning to setup some statistics to track these issues, but something may be up. We do use datastores as well (so you dont get confused by my title)
My game’s servers aren’t crashing. People are just confused of that, but everything works well. It has never happened to me, but data are just disappearing… .-. Tell me if you figure out something.
Scripting Support was the correct category for this (I’ve moved it back). Even though there doesn’t appear to be anything wrong, the script isn’t functioning as intended. Data loss in datastores is complicated, and generally the developer is at fault even if there doesn’t seem like anything is wrong with the code. If this is indeed a bug though (since it’s happening in games it doesn’t normally), feel free to post again in Client Bugs with appropriate information the engineers can use to isolate the issue.