Trying to make my datastores as bulletproof as I can. I’ve got it set up so when you join it tries to load your data up to five times, and if it fails all five times you get kicked after being added to a DoNotSave table so the server knows not to overwrite your data when you’re kicked. My main worry is I want to know if it’s possible if someone’s data got corrupted or something could they just get kicked every time and never be able to join again? Hopefully that’s not possible.
local DoNotSave = {}
local function LoadData(Player)
local dataStore = DSS:GetDataStore(DATA_STORE_NAME)
local key = "Player_"..Player.UserId
local maxattempts = 5
local attempts = 0
local success = nil
local result = nil
repeat wait(1)
attempts += 1
success, result = pcall(function()
return dataStore:GetAsync(key)
end)
until success == true or attempts >= maxattempts
if success == false then-- failed to load after trying repeatedly
table.insert(DoNotSave, Player)--add player to DoNotSave table so we know not to overwrite their data when they are kicked
Player:Kick()
end
if success and result then
--do stuff with data
else
if success then --Successfully loaded data, but no result. I think this has to mean player must be joining for the first time?
--welcome player to game
end
end
end
local function saveData(Player)
--make sure player is not in DoNotSave folder before saving
--set async here
end
Also in my case of there being a ‘success’ but no ‘result’ does that for sure mean it’s a players first time joining?
If you kick a player, they will be able to join again. And if success is true, but there is no data, or I suppose result in this matter, the player is a new player.
If you kick the player, make sure to add a message like, “Data error, please rejoin.”
An alternative to kicking is just to add a “tag” to the player that their data didn’t load and can’t save. And you can inform the player that their data did not load and that they need to rejoin using GUI. For example:
Server
local data
local success, result = pcall(function()
data = dataStore:GetAsync(player.UserId)
end
if not success then
warn(result)
remote:FireClient(player, "DataError")
return -- Skip the next lines of the player's data usage.
end
Client
remote.OnClientEvent:Connect(function(action)
if action == "DataError" then
-- You can change your TextLabels' text to "Please Rejoin."
-- A frame can pop up that says "Data error, please rejoin."
-- These are just examples.
end
end)
There are other ways to do this, like using in-game notifications.
Also, I think you should change this
to this, since you’re already checking if success is not true.
if result then -- Player has data.
-- Do stuff with data.
else -- Player doesn't have data; player is new.
-- Add data.
end
And add a return after the line where you kick the player.
An alternative to kicking is just to add a “tag” to the player that their data didn’t load and can’t save. And you can inform the player that their data did not load and that they need to rejoin using GUI.
I think I’ll do that then. I already made it so they can’t save after failing to load their data so might as well let them play while also letting them know. By any chance do you know if them leaving and rejoining would their ‘Player’ object still be in the DoNotSave table if it’s the same server they just left?
I can easily just add a check when someone joins that would remove them from the table (which could be totally unnecessary) but I’m just curious if that previous player object would still exist or even be the same as their new one if they rejoin.
I think that you should remove the Player object from the table. I say this because if you put an Instance inside of an array, then delete it, the Instance won’t turn nil inside of the array. You just wouldn’t see it in the Explorer.
If the player rejoins, a new Player object will be created, from what I know, so it shouldn’t affect the previous Player object in the array, though, since it’s a new Instance.