Will this coroutine continue running until the server dies, and how can I stop it?

So I have a coroutine that removes a player from the table when they die or leave the game. However I’m worried whether the coroutine will continue running for the entire server lifetime.

This is the piece of code itself.

-- note: module is a module script required earlier in this script, and plrs is an already defined table of the players
        local newThread = coroutine.create(function()
 game.Players.PlayerRemoving:Connect(function(p)
				local item = module.finditem(plrs, p)
				table.remove(plrs, item)
		     end)
			while true do
				for i, plr in pairs(plrs) do
					if plr.Character.Humanoid.Health <= 0 then
						plr.Backpack:ClearAllChildren()
						local item = module.finditem(plrs, plr)
						table.remove(plrs, item)
					end
				end
                wait(0.5)
			end
		end)
		coroutine.resume(newThread)

If this will continue infinitely, how can I stop it once the game is over?

Any help is appreciated!

It will run indefinitely since there is no condition to break the loop. You would have to either add an exit condition, or kill the thread from outside the coroutine.

Also it’s not a good idea to connect a new event listener every time the loop runs.

1 Like

you have to put an if condition in the coroutine, and yield it once that condition is true. For example:

local gameEnded = false

--coroutine script inside while true
if gameEnded == true then
gameEnded = false
coroutine.yield()
end

wait(20)
gameEnded = true

you can run it again by using coroutine.resume()

2 Likes

Hold it, let me edit some code real quick.

Here are some changes

-- note: module is a module script required earlier in this script, and plrs is an already defined table of the players
local newThread = coroutine.create(function()
	game.Players.PlayerRemoving:Connect(function(p)
		local item = module.finditem(plrs, p)
		table.remove(plrs, item)
	end)
	while (#plrs > 0) do
		for i, plr in pairs(plrs) do
			if plr.Character.Humanoid.Health <= 0 then
				plr.Backpack:ClearAllChildren()
				local item = module.finditem(plrs, plr)
				table.remove(plrs, item)
			end
		end
		wait(0.5)
	end
end)
coroutine.resume(newThread)

This coroutine should finish when the ‘plrs’ table becomes empty.

1 Like

Let me show the full code really quickly.

local module = require(game.ReplicatedStorage.GlobalFunctions)

game.ServerStorage.StartMinigame.Event:Connect(function(minigame)
	if minigame == "Sword Fight" then
		local plrs = {}
		for i, p in pairs(game.Players:GetPlayers()) do
			local char = p.Character.HumanoidRootPart
			char.Position = script.Parent.SwordFightSpawn.Position + Vector3.new(math.random(-50.314 / 2, 50.314 / 2), 0, math.random(-49.3 / 2, 49.3 / 2))
			table.insert(plrs, p)
		end
		for i = 10, 1, -1 do
			game.ReplicatedStorage.Text:FireAllClients("In "..tostring(i).." seconds, you will have to kill all opponents alive with a sword.")
			wait(1)
		end
		for i, pl in pairs(plrs) do
			local sword = game.ServerStorage.MinigameTools["1. Sword Fight Sword"]:Clone()
			sword.Parent = pl.Backpack
		end
		local newThread = coroutine.create(function()
			game.Players.PlayerRemoving:Connect(function(p)
				local item = module.finditem(plrs, p)
				table.remove(plrs, item)
			end)
			while (#plrs > 0) do
				for i, plr in pairs(plrs) do
					if plr.Character.Humanoid.Health <= 0 then
						plr.Backpack:ClearAllChildren()
						local item = module.finditem(plrs, plr)
						table.remove(plrs, item)
					end
				end
				wait(0.5)
			end
		end)
		coroutine.resume(newThread)
		local val = 60
		repeat
			game.ReplicatedStorage.Text:FireAllClients("You have "..tostring(val).." seconds left to kill all alive opponents.")
			val = val - 1
			wait(1)
		until #plrs <= 1 or val == 0
		if #plrs <= 1 then
			game.ReplicatedStorage.Text:FireAllClients(plrs[1].Name.." has defeated all opponents!")
		end
		if val == 0 then
			game.ReplicatedStorage.Text:FireAllClients("Time has ran out!")
		end
		for i, player in pairs(plrs) do
			local item = module.finditem(plrs, player)
			table.remove(plrs, item)
		end
		wait(3)
		game.ServerStorage.BeginIntermission:Fire()
		script.Parent.Parent = game.ServerStorage.Minigames
	end
end)

if you make it run once, you will be unable to call it/executing it again. It will be dead.

1 Like

Why would it need to continue running after the round has ended? In his code a new coroutine is created when a round starts. It would only need to last for as long as that minigame.

2 Likes