Loop breaks even though there is a player on the team

I made a round script that cycles through intermission and game time forever, but it halts temporarily when one team wins or all dies. It worked all the way up until I tried to implement a system that halts time when everyone on the “runners” team dies. For some reason, the script breaks when I try to mess around with tables. There were also no errors in the output. I tried to show only the parts of the script I had trouble with, but I couldn’t pin point where exactly there was a problem, so here is the whole script. I also have it in a paste bin if it’s too hard to work with the one below. Any help would be greatly appreciated!

Pastebin: local roundLength = 60local intermissionLength = 10local victoryLength = 15 - Pastebin.com

Script:

local roundLength = 60
local intermissionLength = 10
local victoryLength = 15
local InRound = game.ReplicatedStorage.InRound
local lobbyspawn = game.Workspace.LobbyAreaSpawn
local gamespawn = game.Workspace.GameAreaSpawn
local deathspawn = game.Workspace.deathspawn
local status = game.ReplicatedStorage.Status
local won = game.ReplicatedStorage.Won
 
local music = game.Workspace.music
local music1 = game.Workspace.music_duplex
local music2 = game.Workspace.music_duplexwon
local trombone = game.Workspace.trombone
 
local runnersTable = game.Teams.Runners:GetPlayers()
 
local title = game.StarterGui.Menu.TitleScreen
 
game.Players.PlayerAdded:Connect(function(player)
    local Neutral = game.Teams.Neutral
    player.Team = Neutral
end)
 
InRound.Changed:Connect(function()
    if InRound.Value == true then  
        local death = game.Teams.Death -- this sets the teams
        local runnersTeam = game.Teams.Runners
        local plrs = game.Players
        local runners = {}
            repeat wait(1) until #plrs:GetPlayers() > 0
        local chosen = plrs:GetChildren()[math.random(1, #plrs:GetChildren())]
        for i, plr in pairs(plrs:GetChildren()) do
            if plr ~= chosen then
                table.insert(runners, plr)
                plr.Team = runnersTeam
            else
                plr.Team = death
            end
        print("teams have been chosen")
        end
   
        for _, player in pairs(game.Players:GetChildren()) do -- this teleports the players
            local char = player.Character
            if player.Team == runnersTeam then
                char.HumanoidRootPart.CFrame = gamespawn.CFrame
            else
                char.HumanoidRootPart.CFrame = deathspawn.CFrame
            end
        end
        print("players have teleported to the game area")
    else --if the round isn't going, this places everyone in the neutral team and teleports them to the lobby
        local plrs = game.Players
        local Neutral = game.Teams.Neutral
        for i, plr in pairs(plrs:GetChildren()) do
            plr.Team = Neutral
        end
        print("all players have been placed in neutral")
        for _, player in pairs(game.Players:GetChildren()) do
            local char = player.Character
            char.HumanoidRootPart.CFrame = lobbyspawn.CFrame
        end    
        print("players have teleported to the lobby")
    end
end)
 
local function RoundTimer() --this is the timer for the rounds. It changes the text in a GUI as well
    while wait() do
        if won.Value == false then
            music:Play()
            music1:Stop()
            for i = intermissionLength, 0, -1 do
                InRound.Value = false
                wait(1)
                status.Value = "Intermission: ".. i .." seconds left!"
            end
            music:Stop()
            music1:Play()
            for i = roundLength, 0, -1 do
                InRound.Value = true       
                if #runnersTable == 0 then
                    break
                end
                if won.Value == true then
                    break
                end
                wait(1)
                status.Value = "Game: ".. i .." seconds left!"
            end
            local function test()
                if #runnersTable ==0 then
                    status.Value = "Death has destroyed the runners!"
                    wait(5)
                elseif #runnersTable >0 then
                    status.Value = "The runners have ran out of time!"
                    wait(5)
                end        
            end
            test()
        else
            music:Stop()
            music1:Stop()
            music2:Play()
            for i = victoryLength, 0, -1 do
                wait(1)
                status.Value = "The runners have beaten death!"
            end
 
            for _, player in pairs(game.Players:GetChildren()) do
                local char = player.Character
                char.HumanoidRootPart.CFrame = lobbyspawn.CFrame
            end    
            won.Value = false
        end
    end
end
 
spawn(RoundTimer)

What do you mean by the script breaks?

Sorry for late response, but what happens the intermission timer goes out, but it just says that death killed all the runners even though the #runnersTable has 1 player in it.

You just had your loop logic laid out wrong

local function RoundTimer() --this is the timer for the rounds. It changes the text in a GUI as well
	while wait() do
		music:Play()
		music1:Stop()
		for i = intermissionLength, 0, -1 do
			InRound.Value = false
			wait(1)
			status.Value = "Intermission: ".. i .." seconds left!"
		end
		music:Stop()
		music1:Play()
		for i = roundLength, 0, -1 do --Start the loop
			InRound.Value = true
			if #runnersTable == 0 then --Everyone is dead, exit the loop
				break
			end
			if won.Value == true then --Runners won, exit the loop
				break
			end
			wait(1)
			status.Value = "Game: ".. i .." seconds left!"
		end --Loop has exited
		--Now we find out why the loop exited. Before, you never checked if the reason the loop exited was the runners winning, only if it was them dying or running out of time. We check that first as the most exclusive condition.
		if won.Value == true then --We move this here, because if they win it won't be caught before the loss stuff if it isn't before it. If the runners win, then we do all this code.
			music:Stop()
			music1:Stop()
			music2:Play()
			for i = victoryLength, 0, -1 do
				wait(1)
				status.Value = "The runners have beaten death!"
			end
			for _, player in pairs(game.Players:GetChildren()) do
				local char = player.Character
				char.HumanoidRootPart.CFrame = lobbyspawn.CFrame
			end	
			won.Value = false
		elseif #runnersTable ==0 then --If we get to here, now we know the runners haven't won, let's see how many there are.
			status.Value = "Death has destroyed the runners!"
			wait(5)
		elseif #runnersTable>0 then --We know they didn't all die, so we know it must be time.
			status.Value = "The runners have ran out of time!"
			wait(5)
		end
	end
end

The way you had it before, it would only check to see why the runners lost, not if they won.

Sorry for late response. I replaced my script with yours but now it doesn’t function. There are no errors in the output.

Again, what do you mean by doesn’t function? Does it not start the round, not end the round, what? You need to be descriptive with any problems you have if you want help, because “doesn’t work” is too broad.

Your potential issue is here:

local runnersTable = game.Teams.Runners:GetPlayers()

You’re assigning it once, and that one time is when the script is initially loaded. Whatever that value is, is the value you’re evaluating against forever. The script is most likely loaded before a player joins the game. So it will be 0 at all times.

What you could do, is change it to the following:

local runnersTeam = game.Teams.Runners

Renamed for convenience, you can then call :GetPlayers() method whenever you need the correct player count. So you can get the correct count of players the moment it’s called.

For example,

if #runnersTeam:GetPlayers() == 0 then