Buggy round system

Hello! I have been trying to create a round system for a client of mine, something I have never done, but it turned out pretty alright. However, I can’t seem to get the actual logic of the automatic round system.

I want it to

  1. Check if there are enough players
  2. Force a count down of 15 seconds
  3. While counting down, simultaneously check if there are enough players
  4. Start the game
  5. If the game that has started doesn’t have enough players, retry

That is all I am trying to do.

The only problem in my way is the actual game start function. It appears that even if you die and are the last one remaining, it doesn’t teleport you back like it’s supposed to.

local teams : Teams = game:GetService("Teams")


local canSpectate : BoolValue = game.ReplicatedStorage.CanSpectate
local tiles : Folder = game.Workspace["Plate Model"]
local lobby : SpawnLocation = game.Workspace.SpawnLocation

local maxPlayers = 2

local playing = false
local changeText = false
local winnerName = ""
local connections = {}

local teams_list : {} = {
	Playing = teams:WaitForChild("Playing"),
	Not_Playing = teams:WaitForChild("Not Playing")
}


-- table shuffler
function shuffle(tbl)
	for i = #tbl, 2, -1 do
		local j = math.random(i)
		tbl[i], tbl[j] = tbl[j], tbl[i]
	end
	return tbl
end

local function teleportPlayers(players : {Player})
	local parts = {}

	for _, part in pairs(tiles:GetChildren()) do
		table.insert(parts, part:FindFirstChild("Hatch")) -- put all parts in a table
	end
	
	for i = 1, #players do
		local shuffled = shuffle(parts) -- shuffle all parts
		local random = shuffled[math.random(1, #shuffled)] -- get random part
		local part = random -- save the random part (to prevent it from becoming undefined)
		table.remove(parts, shuffled[random]) -- makes sure players dont spawn on the same part
		players[i].Character.HumanoidRootPart.CFrame= part.CFrame + Vector3.new(0, 3, 0) -- teleport
        players[i].Team = teams_list.Playing
    end
end

local function enoughPlayersNotPlaying()
	return #teams_list.Not_Playing:GetPlayers() >= maxPlayers
end

local function  enoughPlayersPlaying()
    return #teams_list.Playing:GetPlayers() >= maxPlayers
end


local function endGame(toptext : TextLabel)

    for _, connection in pairs(connections) do
        connection:Disconnect()
    end

    if playing then
        playing = false
        changeText = false
        canSpectate.Value = false
        local players = teams_list.Playing:GetPlayers()
        for _, player in pairs(players) do
            winnerName = player.Name
            player.Team = teams_list.Not_Playing
            player.Character.HumanoidRootPart.CFrame = lobby.CFrame
        end
    end

    toptext.Text = "Winner is " .. winnerName .. "!"
    task.wait(5)
    print("Game Ended")
end

local function startGame(toptext : TextLabel)
    print("Starting Game")
    local enough = enoughPlayersNotPlaying()
	if not enough then warn("Not Enough Players") return false end
    
    local players = teams_list.Not_Playing:GetPlayers()
    for _, player in pairs(players) do
        player.Team = teams_list.Playing
        player.PlayerGui.Top.TextLabel.Visible = false
       
        local connection = player.Character:WaitForChild("Humanoid").Died:Once(function()
            player.Team = teams_list.Not_Playing
        end)

        table.insert(connections, connection)

    end
    
    -- Start the game
    teleportPlayers(players)
    canSpectate.Value = true
    playing = true
    changeText = true

    -- Check if there are enough players to continue the game
    local function onPlayerRemoved()
        if not enoughPlayersNotPlaying() then
            endGame(toptext)
        end
    end

    for _, player in pairs(players) do
        player.AncestryChanged:Connect(onPlayerRemoved)
    end
end

game.Players.PlayerAdded:Connect(function(player)
    player.Team = teams_list.Not_Playing
    task.wait(5)
    local top : TextLabel = player.PlayerGui.Top.TextLabel

    local function checker()
        if not enoughPlayersNotPlaying() then
            if enoughPlayersPlaying() then
                return
            else
                top.Text = "Not enough players!"
                game.Players.PlayerAdded:Wait()
            end
        end
    end
    
    -- Here is where the game logic starts
    while true do
        if not playing then
            top.Visible = true
            top.Text = "15"
            for i = 1, 15 do
                checker()
                top.Text = tostring(15 - i)
                task.wait(1)
            end
        
            local started = startGame(top)
            if not started then
                top.Text = "Not enough players!"
            end
        end
        task.wait(1)
    end
end)

Viable functions are the startGame(), endGame() and checker() which actually checks if there are enough players and waits until one has joined.

1 Like

I realised a small issue in my code, but please ignore the while true do function inside the game.Players.PlayerAdded:Connect(function() and treat it as if it weren’t there, rather someplace else

2 Likes

I think that’s the issue, switch over to RunService.Heartbeat Instead

1 Like

yeah but its not only that its the actual logic inside the loop aswell as the startgame function