What's wrong with this code?

I am making a Piggy inspired game from scratch will the help of my friend, and he is the scripter. I am the builder of the game, and we are having some difficulties in my system that detects if the game is over or not. If the timer runs out it is over. If everyone dies or leaves the game, the round is over. If the Slayer dies or leaves the game, the round is over. The timer part works completely fine, but the other 2 options work and don’t work. They work very well if you are doing 1 player, but not that good when multiple players get selected. I have gone over my code a bunch of times, and I even tried making it double-check, and still nothing. Voting works fine, but this glitch only happens when a player is selected and not a bot. Here is the round system code:

while true do
	for i, v in pairs(game.Players:GetChildren()) do
		v.Character.Humanoid.Health = v.Character.Humanoid.MaxHealth -- Makes sure the player's health is full
	end
	for i = 45, 0, -1 do
		game.ReplicatedStorage.Status.Value = "<ContainerHorizontalAlignment=Center><AnimateStepFrequency=0>Intermission: <AnimateStyle=Fade><AnimateStyleTime=0.25><Color=Green>" .. i  -- I used rich text module made by defaultio
		wait(1)
	end
	local slayer
	local gameOver = false
	local slayerLeft = false
	local players = game.Players:GetChildren() -- a table listing all of the players that we will put into the round
	local chosenMode = "Player"
	local numPlayers = #game.Players:GetChildren() -- the number of players
	for i, v in pairs(players) do -- Doesn't add the player to the round if they are still loading
		if not v.Character then
			numPlayers = numPlayers - 1
			table.remove(players, i)
		end
	end
	if numPlayers == 1 or #players == 1 then -- Automatically chooses bot if only 1 player in the server
		chosenMode = "Bot"
	else
		if #game.ReplicatedStorage.BotVote:GetChildren() > #game.ReplicatedStorage.PlayerVote:GetChildren() then
			chosenMode = "Bot"
		else
			chosenMode = "Player"
			numPlayers = numPlayers - 1
		end
	end
	if chosenMode == "Player" then
		slayer = game.Players:GetChildren()[math.random(1, #game.Players:GetChildren())] -- Choosing slayer is not the problem btw
	else
		slayer = game.ServerStorage.Bots.Bot:Clone()
	end
	for i, v in pairs(players) do
		if v.Name == slayer.Name then -- Removes the slayer from the player table
			table.remove(players, i)
		end
		v.Character.Humanoid.WalkSpeed = 16 + v.ExtraSpeed.Value -- Faster speed gamepass thing
		v.Character.Humanoid.Died:Connect(function() -- if player died, it will remove them from the players table
			table.remove(players, i)
			numPlayers = numPlayers - 1
			print(v, "Died!")
			if v.Character:FindFirstChildOfClass("Tool") then -- puts the tools back where they found it.
				game.ServerStorage.Tools:FindFirstChild(v.Character:FindFirstChildOfClass("Tool").Name).Parent = game.Workspace.CurrentMap.Keys
				v.Character:FindFirstChildOfClass("Tool"):Destroy()
			end
			if v.Backpack:FindFirstChildOfClass("Tool") then
				game.ServerStorage.Tools:FindFirstChild(v.Backpack:FindFirstChildOfClass("Tool").Name).Parent = game.Workspace.CurrentMap.Keys
				v.Backpack:FindFirstChildOfClass("Tool"):Destroy()
			end
		end)
	end
	game.ReplicatedStorage.Escape.OnServerEvent:Connect(function(player) -- if player escapes, they will be removed from the players table
		print(player, "Escaped")
		numPlayers = numPlayers - 1
		game.BadgeService:AwardBadge(player.UserId, 2124534311)
		player.Points.Value = player.Points.Value + (35 * player.Multiplier.Value)
		for i, v in pairs(players) do
			if v == player then
				table.remove(players, i)
			end
		end
	end)
	game.Players.PlayerRemoving:Connect(function(player)
		if player == slayer then -- resets game if slayer left
			players = {}
			gameOver = true
			slayerLeft = true
		else
			for i, v in pairs(players) do
				if v == player then
					table.remove(players, i)
				end
			end
		end
	end)
	if chosenMode == "Player" then -- resets the game if the slayer died
		slayer.Character.Humanoid.Died:Connect(function()
			gameOver = true
			slayerLeft = true
		end)
	end
	game.ReplicatedStorage.Status.Value = "<ContainerHorizontalAlignment=Center><AnimateStepFrequency=0.05><AnimateStyle=Fade><AnimateStyleTime=0.25><Color=Red>" .. slayer.Name .. "<Color=/> has been selected as<Color=Red> Slayer!<Color=/>" -- some more rich text
	wait(5)
	local map = game.ServerStorage.Maps.House:Clone()
	map.Parent = game.Workspace
	map.Name = "CurrentMap"
	game.ReplicatedStorage.Status.Value = "<ContainerHorizontalAlignment=Center><AnimateStepFrequency=0.05><AnimateStyle=Fade><AnimateStyleTime=0.25>Loading Map..."
	wait(5)
	game.ReplicatedStorage.Fade:FireAllClients(true)
	wait(2)
	game.ReplicatedStorage.Fade:FireAllClients(false)
	game.ReplicatedStorage.HideShop:FireAllClients(false)
	wait(0.1)
	if chosenMode == "Player" then
		game.ReplicatedStorage.Backpack:FireClient(slayer, false) -- hides the slayer's backpack
	end
	for i, v in pairs(players) do
		game.ReplicatedStorage.Intro:FireClient(v)
	end
	game.ReplicatedStorage.Intro:FireClient(slayer)
	for i, v in pairs(players) do -- for the intro
		if v.Character then
			pcall(function()
				v.Character:SetPrimaryPartCFrame(CFrame.new(266.253, -29.26, -93.261) * CFrame.Angles(0, math.rad(90), 0))
			end)
		end
	end
	wait(30)
	game.Workspace.GameTimeMusic:Play()
	if chosenMode == "Player" then -- changes player to the slayer skin
		skin = game.ServerStorage.Skins:FindFirstChild(slayer.Equip.Value):Clone()
		skin.Name = slayer.Name
		slayer.Character = skin
		skin.Parent = game.Workspace
		slayer.Character:SetPrimaryPartCFrame(CFrame.new(339.263, 4, 205.29))
		skin.Humanoid.WalkSpeed = 16 + slayer.ExtraSpeed.Value
	end
	for i, v in pairs(players) do
		if v.Name ~= slayer.Name then
			pcall(function()
				v.Character:SetPrimaryPartCFrame(map.Spawn.CFrame)
			end)
		end
	end
	game.ReplicatedStorage.CurrentSlayer.Value = slayer.Name
	for i = 480, 0, -1 do -- timer system
		local timer = math.floor(i / 60) .. ":" .. i % 60
		if i % 60 < 10 then
			timer = math.floor(i / 60) .. ":0" .. i % 60
		end
		if i == 450 then
			if chosenMode == "Player" then
				slayer.Character:SetPrimaryPartCFrame(map.Spawn.CFrame)
			else
				slayer.Parent = game.Workspace
				slayer:SetPrimaryPartCFrame(map.Spawn.CFrame)
			end
		end
		game.ReplicatedStorage.Status.Value = "<ContainerHorizontalAlignment=Center><AnimateStepFrequency=0>Game Time: <AnimateStyle=Fade><AnimateStyleTime=0.25><Color=Green>" .. timer
		wait(1)
		if #players == 0 then
			gameOver = true
		end
		if numPlayers == 0 then
			gameOver = true
		end
		if gameOver then -- resets game if gameOver is set to true
			break
		end
	end
	game.Workspace.GameTimeMusic:Stop()
	game.ReplicatedStorage.Status.Value = "<ContainerHorizontalAlignment=Center><AnimateStepFrequency=0.05><AnimateStyle=Fade><AnimateStyleTime=0.25>Game Over!"
	wait(3)
	game.ReplicatedStorage.Backpack:FireAllClients(true)
	game.Workspace.TrapsPlacement:ClearAllChildren()
	map:Destroy()
	if not slayerLeft then
		if chosenMode == "Player" then -- turns player back to normal if slayer
			slayer:LoadCharacter()
			skin:Destroy()
		else
			slayer:Destroy()
		end
	end
	game.ReplicatedStorage.CurrentSlayer.Value = ""
	game.ReplicatedStorage.HideShop:FireAllClients(true)
	for i, v in pairs(players) do -- teleports players back to the lobby
		if v then
			v.Character:MoveTo(game.Workspace:FindFirstChild("SpawnLocation" .. math.random(1, 3)).Position)
		end
	end
	game.ReplicatedStorage.BotVote:ClearAllChildren()
	game.ReplicatedStorage.PlayerVote:ClearAllChildren()
	game.ServerStorage.Tools:ClearAllChildren()
end

-- I just cannot figure out why it doesn’t work. I sometimes found that if a player dies it sometimes doesn’t do anything. Is the script not efficient or is it an error? I can’t seem to know!

Yep, as always. No one knows, do you get any errors? BTW, people don’t want to read these massive scripts and would rather answer short ones. I recommend you only put the game ending part script in. Title ain’t the best either

Alright, I’ll make sure to avoid that next time. I don’t get any errors though.

I actually had a similar error to this. In single player it worked fine, but in multiplayer it didn’t work always:

The problem with your code is that it has too many wait() functions that yeild the code, which will take time to detect the other 2 variables, I suggest using coroutines, which will solve these problems:

local RoundEnded = false
local Piggy = -- The piggy chosen
local PlayersIngame = {}

local function RoundStarted()
    for i, player in pairs(Players:GetPlayers()) do
        table.insert(PlayersIngame, player)
        player.Character.Humanoid.Died:Connect(function()
            table.remove(PlayersIngame, player)
            if #PlayersIngame == 1 then
                RoundEnded = true
            end
        end)
    end

    local PlayerRemoved
    PlayerRemoved = Players.PlayerRemoving:Connect(function(player)
        table.remove(PlayersIngame, player)
        if player.Name == Piggy.Name then RoundEnded = true end
        if #PlayersIngame == 1 then RoundEnded = true end
    end)

    local PlayerAdded
    PlayerAdded = Players.PlayerAdded;Connect(function(player)
        table.insert(PlayersIngame, player)
    end)

    coroutine.wrap(function()
        while RoundEnded == false do
            -- Countdown here
            -- When couontdown ends run this line of code:
           PlayerRemoved:Disconnect()
           PlayerAdded:Disconnect()
        end
    end)
end

@Little_Joes

Don’t assume that people don’t know how to do these things, it’s because the thread is really tedious to read and understand, people volunteer to help people on the forums.

What you should take away from this is that the better it is to understand the problem, the more people would want to help you with your probelem. These kinds of problems are more complex, so people don’t want to do it.

Do you know why this isn’t working? Is it the same reason?