Thanks, I added BindToClose()
to the code but data loss problem persists. People still reports completely deleted data.
It would probably be helpful if you knew what error the pcall is giving. You could either have the pcall displayed on the clients screen when the data is auto saved or you can send the error to a discord webhook with the player name and the data if you want. Just be sure not to spam the discord webhook.
Why are you using GetAysnc
when the player is leaving? i think it would be better to call that once, when the player joins. if you needed a way to check if a player has new data you should use UpdateASync()
as it returns the previously stored data and allows you to update it at the same, furthermore adding a BindtoClose
(as kind of mentioned above) and placing a wait inside should make the server wait (given amount, max is 30secs ) before fulling closing, thus allowing time for all players data to save( in theory) , here’s what i mean:
game:BindToClose(function()---Fired when the server is about to close
wait(10) -----wait
print("ServerClosing")
end)
I added BindtoClose()
to the code but data loss problem persists. And UpdateASync()
is not working on this situation. So I have to use SetASync()
for now. (PlayerRemoving function)
I’m using GetAysnc
to check data, it’s like; if one of player data is less than saved data, don’t save.
What do you mean UpdateAsync()
is not working in this situation? From past experience, that would suggest an issue with values, not the actual saving/loading.
Some data is saving and some is not right( so its not that its not saving any data at all)?
What if there is all of that values are strings, which is you can’t use UpdateAsync()
? I want that solution actually. There must be a solution about that.
You can use UpdateAsync for anything that set Async can save as well, so you can save strings using it For example: (using your set-up)
(this is just some quick pseudo code, you probably should modify it)
local success, message = pcall(function()
DataStore:UpdateAsync(PlayerKey, function(oldData)
if oldData == nil then
return Saving ----returns saving, (table)
else
--Save other data using return
end
end)
end
end
Can you explain me more the else
statement in that script? Because it’s not saving data if there are data.
If the game shuts down unexpectedly the data will not save. The reason is because the BindToClose function will not work if it is in the PlayerRemoving Function. PlayerRemoving does not fire if the server unexpectedly shuts down. If I were you I would create a save function(Be sure to put pcalls and if you could DataStore the pcall errors and check them that would probably give you the answer to Data Loss). Like so
function saveData(plr)
--Code to save
end
Then you call this function to Save Data when player is leaving.
game.Players.PlayerRemoving:Connect(function(plr)
saveData(plr)
end)
If the server shuts down BindToClose is going to save the data.
game:BindToClose(function()
for _,v in pairs(game.Players:GetChildren()) do
saveData(v.Name) -- v is the player name
end
end)
There is a Example BindToClose script here. If this still doesn’t help could you take a picture of the PlayerSave folder.
game:BindToClose(function()
saveData(plr) --?
end)
How to detect plr
(Player) on BindToClose()
?
Thanks for pointing that out i fixed the post.
I left out the local for plr.
game:BindToClose(function()
local plr = game.Players.LocalPlayer.Name
saveData(plr)
end)
A better option would be too do
game:BindToClose(function()
for _,v in pairs(game.Players:GetChildren()) do
saveData(v.Name) -- v is the player name
end
end)
In this example, v would not be the player name, v would be the player instance. You’d need to say v.Name to get the actual player name.
I made a tutorial on YouTube using this code. It seems to work for me (this version is untested).
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("name_here")
local dataLoaded = false
local tries = 3
local function Set(plr)
if dataLoaded then
local key = "key#-" .. plr.UserId
local data = {
["currency1"] = plr.leaderstats.name.Value,
["currency2"] = plr.leaderstats.name2.Value
}
local success, err
local count = 0
repeat
success, err = pcall(function()
dataStore:SetAsync(key, data)
end)
count = count + 1
wait(0.5)
until count >= tries or success
if not success then
warn("Failed to serialize data. Error code: " .. tostring(err))
return
end
end
end
local function Get(plr)
local key = "key#-" .. plr.UserId
local serialized
local success, err
local count = 0
repeat
success, err = pcall(function()
serialized = dataStore:GetAsync(key)
end)
count = count + 1
wait(0.5)
until count >= tries or success
if not success then
warn("Failed to read data. Error code: " .. tostring(err))
return
end
if serialized then
return serialized
else
local starterStats = {
["currency1"] = 10,
["currency2"] = 20
}
return starterStats
end
end
local function CreateStats(plr)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = plr
local data = Get(plr)
local currency1 = Instance.new("IntValue")
currency1.Name = "name"
currency1.Parent = stats
local currency2 = Instance.new("IntValue")
currency2.Name = "name2"
currency2.Parent = stats
currency1.Value = data.currency1
currency2.Value = data.currency2
dataLoaded = true
Set(plr)
end
game:BindToClose(function()
for _, v in pairs(game.Players:GetChildren()) do
Set(v.Name) -- v.Name is the player name
end
end)
Players.PlayerAdded:Connect(CreateStats)
Players.PlayerRemoving:Connect(Set)
You forgot to add a BindToClose function. This needs to be added just incase of server shutdown data won’t be lost. It is better to use UpdateAsync than SetAsync.
game:BindToClose(function()
for _,v in pairs(game.Players:GetChildren()) do
Set(v.Name) -- v.Name is the player name
end
end)
Really, the only solution is to change to a new system, unfortunately you will have to rewrite everything.
UpdateASync()
caused more problems somehow. (More reports coming about data loss now)
There’s a lot of data here, and people bought items/upgrades with real money. So I can’t rewrite everything, data scheme must remain the same.
It would make it easier if you provide a screenshot of the PlayerSave tell us if its Bool,Number,String values. The Player that reports data loss is it just certain data(if so which value) or is the whole safe getting wiped?