Should you kick a player after failing to load their data?

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?

It’d be better to try reload their data instead of kicking…

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.

You should try getting their data at least 3 times with a second or two cooldown. If their data did not error (not that it’s nil), then you should:

  • Inform the user their data failed to load
  • Let them play as a new player after telling them
  • Their data should not be saved in this state
  • Later when their data comes back, everything will be normal again

That’s how I would go about it anyway.

1 Like

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.

Good suggestion, you could also give the player the option to rejoin besides the option of playing as a “new” player.

1 Like

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.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.