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?
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.
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
-- 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.
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)
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.