What happens if player leaves in middle of running a function?

I’m probably overthinking this, i’m not talking about anything like a datastore function or a remote function that many sources say to use a pcall for.

I’m going to have a function that loops through every player on a team of 10 players changing the teams and leaderstats of a bunch of players at once.

It looks something like

for i, Player in pairs(TeamB:GetPlayers()) do
Player.Team = TeamA
Player.leaderstats.points:Destroy()
end

What happens if a player leaves as a change is happening? If the script crashses then the whole server becomes useless because the script handles the round-based game im making. Is having a single script controlling a round-based game a bad practice since something crashing could take out the whole server?

I’m still quite new, if any of my questions are vague or don’t make sense please let me know.

Actually, ipairs breaks the loop if it hits a nil value somewhere.

3 Likes

This is what i’m confused about. I don’t wanna break the loop if I hit a nil right? I have to get everyone’s team swapped.

Oh lol that’s embarrassing, thanks for the correction.

Edit: adding a conditional check if player ~= nil is still going to have the effect you are looking for.

1 Like

I should have been doing that but I was being lazy and rushing >_<

You could check if the Player exists every time the loop runs.

for i, Player in pairs(TeamB:GetPlayers()) do
if Player ~= nil then
Player.Team = TeamA
Player.leaderstats.points:Destroy()
end
end

but I think if the player left at just the right time it could still break this function. If you want to avoid all possibility of breaking it I believe you could use a pcall. Correct me if I am wrong though.

It depends on what kind of a function you’re running, how expensive it is and how long it’ll take to complete. Your function probably won’t be slow enough that it iterates over a player who left while the loop is running. Regardless though, functions usually error or cancel in the case that a player leaves while it’s running.

It’s important that you pcall error-bound code (especially anything that directly or indirectly is a web call) and don’t assume that your code will always produce truthy results for any kind of indexing (by direct indexing, FindFirst/WaitForChild, etc).

I’d suggest doing a pcall to check if the change was successful:

for i, Player in pairs(TeamB:GetPlayers()) do
	if Player then
		local plr_name = Player.Name or "unknown"
		local success = pcall(function()
			Player.Team = TeamA
			Player.leaderstats.points:Destroy()
		end)
		if not success then
			warn("Player "..plr_name.." left while processing!")
		end
	end
end
1 Like