How to make an advanced round system

it’s a simple system to just make a round loop that has a game time and intermission but Im stuck on how to implement things like restarting when all the players are dead or when the last player leaves.

How would I program these functionalities, do I just make connections for each player when the round starts?

Try this-

Round Loop: Controls the main flow of the game (intermission → game start → round end → restart).
Player Connections: Keep track of players and check conditions like “all players dead” or “last player leaves.”
Restart Condition: Trigger round restart when necessary.

-- Server Script

local playersService = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")

local gameState = "Intermission" -- Tracks the current state of the game (Intermission, InGame, etc.)
local intermissionTime = 10 -- Time for intermission
local gameTime = 60 -- Time for each round

local roundInProgress = false -- Tracks if a round is currently active
local alivePlayers = {} -- Table to store alive players

-- Remote events for UI updates (e.g., for timers)
local roundStatusRemote = replicatedStorage:WaitForChild("RoundStatusRemote") 

-- Function to check if all players are dead
local function checkPlayersAlive()
    for _, player in pairs(alivePlayers) do
        if player and player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health > 0 then
            return true -- There is at least one player alive
        end
    end
    return false -- All players are dead
end

-- Function to handle when a player dies
local function onPlayerDied(player)
    table.remove(alivePlayers, table.find(alivePlayers, player)) -- Remove the player from alivePlayers list
    if not checkPlayersAlive() then
        endRound() -- End round if no one is alive
    end
end

-- Function to start the round
local function startRound()
    gameState = "InGame"
    roundInProgress = true

    -- Reset alive players
    alivePlayers = {}

    -- Add all players to alivePlayers list
    for _, player in pairs(playersService:GetPlayers()) do
        if player.Character and player.Character:FindFirstChild("Humanoid") then
            table.insert(alivePlayers, player)

            -- Connect death event
            player.Character.Humanoid.Died:Connect(function()
                onPlayerDied(player)
            end)
        end
    end

    -- Notify clients that the game has started
    roundStatusRemote:FireAllClients("Game Started", gameTime)

    -- Wait for the game time to end or players to die
    local startTime = tick()
    while tick() - startTime < gameTime and roundInProgress do
        wait(1)
    end

    -- End the round if time runs out or all players die
    if roundInProgress then
        endRound()
    end
end

-- Function to end the round
local function endRound()
    gameState = "Intermission"
    roundInProgress = false
    roundStatusRemote:FireAllClients("Round Ended")

    -- Restart the round after a delay (intermission time)
    wait(intermissionTime)
    startRound()
end

-- Function to handle when a player leaves during the game
local function onPlayerLeft(player)
    if roundInProgress then
        -- Remove the player from alivePlayers list
        table.remove(alivePlayers, table.find(alivePlayers, player))
        
        -- Check if all players are gone
        if #alivePlayers == 0 then
            endRound() -- End the round if no players remain
        end
    end
end

-- Main game loop
local function mainGameLoop()
    while true do
        if gameState == "Intermission" then
            -- Start intermission and wait
            roundStatusRemote:FireAllClients("Intermission", intermissionTime)
            wait(intermissionTime)
            startRound()
        end
    end
end

-- Event for when players join or leave
playersService.PlayerRemoving:Connect(onPlayerLeft)

-- Start the main game loop
mainGameLoop()

1 Like