I work for a game called You have to eat 2000 crawfish, this game has an active playerbase although small, and Prestige Datastores for the game have recently been wiped in the newest update. This is important because the community is really dedicated and Prestige a high amount of times, only very few members actually have data backed up for them. Anyway, here is the code:
local datastores = game:GetService("DataStoreService")
local datastore = datastores:GetDataStore("Save")
game.Players.PlayerAdded:Connect(function(player)
local prestige = Instance.new("NumberValue") -- prestige
prestige.Name = "Prestige"
prestige.Value = 0
prestige.Parent = player
local prestigeValue = datastore:GetAsync(player.UserId) or 0
if prestigeValue then
prestige.Value = prestigeValue
else
print("could not get prestige saved data")
end
end)
game.Players.PlayerRemoving:Connect(function(player)
datastore:SetAsync(player.UserId,player.Prestige.Value)
end)
You need to use BindToClose too, in case your servers are being shut down, etc.
It’s probably because you’re settings its value to 0 when it’s inserted, and you also have the or 0 thing, which as I can tell from your script, can cause to confusion and cause some people lose their Prestiges.
Having pcalls made the Datastores not work last time, and for the second thing you said, can you elaborate on what BindToClose is? Player’s Prestiges are fine when they don’t join the game, I had checked that, but when they join the game it gets wiped. Edit: Found out what BindToClose was.
game:BindToClose will fire when the game is either shut down, or something like this.
It’s important to use it, simply because sometimes you can lose data when leaving.
…what? Whatever they mentioned above is useful and DEFINITELY the cause of data loss in your game.
:BindToClose() is VERY important as it makes sure that the server does not shut down before it has saved all player’s data.
pcall functions are to ensure that the data is actually saved. If the pcall fails, keep calling it again until it works, with increasing duration of 2, 4, 8, 16 with a max cap at 32. (just a suggestion)
STORE PLAYER’S DATA IN SERVER STORAGE! So that when the player leaves and the save fails, the server can keep on attempting to save it. Only when saved successfully, then remove all player’s data from the ServerStorage.
The data wipe happened because the values failed to load but your script didn’t detect it. So when the players left, the default values were saved.
There are 2 crucial updates you should apply to the script to prevent the data wipes.
Use pcalls to determine if the values have been loaded:
local success, value = pcall(function()
return ds:GetAsync(player.UserId)
end)
if (not(success)) then
return player:Kick('The data failed to load:\n' .. val)
end
This code will kick the player when DataStoreService encounters an error.
Make sure the values have been already loaded before you save them
There are plenty of problems with the DataStores and they are not very stable.
Under certain circumstances the PlayerRemoving event may be called before the values have been fetched from the DataStore. It will cause the value to reset to default for affected player.
To prevent it, you should always check if the values are loaded:
Players.PlayerAdded:Connect(function()
local loaded = {}
local success, value = pcall(function()
return ds:GetAsync(player.UserId)
end)
if (not(success)) then
return player:Kick('The data failed to load:\n' .. val)
end
-- assign the value here
loaded[player] = true
end)
Players.PlayerRemoving:Connect(function(player)
if (loaded[player])
-- perform SetAsync here
end
end)
This is a basic version of data wipe prevention every game should have.