Help with my loop

Hello Guys,
i need a bit help with my loop. I am already sitting 3 hours on this and i don’t have any ideas anymore how i can make it work, not even Ai helped me.
I wanna make an AFK function for my game and this code kinda works but the Lobbywait is always set back to 30 because of the loop but i have no idea how to rewrite the loop and keeping the logic of it.
I want that the Lobbycountdown works as long as more then 3 Players are in the Game and not AFK. And i want that the Round repeat gets active when a player gets Afk and the players in the game drop below 3 yk?

local Lobbywait = 30

local function round()
	while true do
		local requiredPlayers = 3
		repeat
			wait(1)
			status.Value = "At least " .. requiredPlayers .. " players are needed to start a round"

			local activePlayers = 0
			for _, Plr in pairs(game.Players:GetPlayers()) do
				if not Plr:FindFirstChild("isAFK") then
					activePlayers = activePlayers + 1
				end
			end
		until activePlayers >= requiredPlayers
		
		inRound.Value = false
		
		local function lobbyCountdown()
			for i = Lobbywait, 0, -1 do
				status.Value = "Voting begins in " .. i .. " seconds"
				wait(1)
			end
		end
		
		lobbyCountdown()

Here is the full script if anyone needs it.

local intermission = 20
local choose = 10
local roundLength = (math.random(2,4) * 60)

local inRound = game.ReplicatedStorage.InRound
local ChooseMode = game.ReplicatedStorage.ChooseMode
local status = game.ReplicatedStorage.Status
local LStatus = game.Workspace:WaitForChild("Lobby").SystemSign.SurfaceGui.SIGN

local playingTeam = game.Teams.Playing
local lobbyTeam = game.Teams.Lobby

local Modes = game.ReplicatedStorage:WaitForChild("Modes")

local RoundTimer = game.ReplicatedStorage:WaitForChild("RoundTimer")

local roguesrevengeModule = require(game.ReplicatedStorage:WaitForChild("rougeRevengeSystem"))
local reversedModeModule = require(game.ReplicatedStorage:WaitForChild("reversedSystem"))
local deathModeModule = require(game.ReplicatedStorage:WaitForChild("deathmodeSystem"))
local murderMysteryModule = require(game.ReplicatedStorage:WaitForChild("murderMysterySystem"))

local Sounds = game.ReplicatedStorage.Sounds

local function formatTime(seconds)
	local minutes = math.floor(seconds / 60)
	local remainingSeconds = seconds % 60
	return string.format("%02d:%02d", minutes, remainingSeconds)
end

inRound.Changed:Connect(function()
	if inRound.Value == true then
		for _, plr in pairs(game.Players:GetPlayers()) do
			local char = plr.Character
			local human = char:WaitForChild("Humanoid")
			local openEvent = game.ReplicatedStorage.CurrencyEvents:FindFirstChild("OpenClaim")

			plr.Team = playingTeam

			human.Died:Connect(function()
				plr.Team = lobbyTeam
			end)
		end
	else
		local spawns = game.Workspace.Lobby:FindFirstChild("Spawns"):GetChildren()
		local spawnIndex = 1

		for _, plr in pairs(game.Players:GetPlayers()) do
			local char = plr.Character
			if char then  -- Check if the player's character exists
				local humanRoot = char:WaitForChild("HumanoidRootPart")
				local human = char:WaitForChild("Humanoid")
				local openEvent = game.ReplicatedStorage.CurrencyEvents:FindFirstChild("OpenClaim")

				if plr.Team == playingTeam then
					if spawnIndex > #spawns then
						spawnIndex = 1  -- Reset to the first spawn point if we exceed the number of available spawns
					end

					local spawnPoint = spawns[spawnIndex]
					humanRoot.CFrame = spawnPoint.CFrame
					spawnIndex = spawnIndex + 1  -- Move to the next spawn point for the next player

					plr.Team = lobbyTeam

					human:UnequipTools()
					plr.Backpack:ClearAllChildren()
				end

				openEvent:FireClient(plr)
			end
		end
	end
end)

local Lobbywait = 30

local function round()
	while true do
		local requiredPlayers = 3
		repeat
			wait(1)
			status.Value = "At least " .. requiredPlayers .. " players are needed to start a round"

			local activePlayers = 0
			for _, Plr in pairs(game.Players:GetPlayers()) do
				if not Plr:FindFirstChild("isAFK") then
					activePlayers = activePlayers + 1
				end
			end
		until activePlayers >= requiredPlayers
		
		inRound.Value = false
		
		local function lobbyCountdown()
			for i = Lobbywait, 0, -1 do
				status.Value = "Voting begins in " .. i .. " seconds"
				wait(1)
			end
		end
		
		lobbyCountdown()
		
		game.ReplicatedStorage:FindFirstChild("VotingEnabled").Value = true

		for i = intermission, 0, -1 do
			status.Value = "Research begins in " .. i .. " seconds"
			wait(1)
		end
		game.ReplicatedStorage:FindFirstChild("VotingEnabled").Value = false

		local modeBoolValues = Modes:GetChildren()
		local randomModeIndex = math.random(1, #modeBoolValues)
		local chosenModeBoolValue = modeBoolValues[randomModeIndex]

		chosenModeBoolValue.Value = true
		ChooseMode.Value = true

		for i = 5, 0, -1 do
			status.Value = "Mode gets Chosen"
			wait(1)
		end

		ChooseMode.Value = false
		inRound.Value = true

		if chosenModeBoolValue.Name == "Roguemode" then
			roguesrevengeModule.ChooseRoles()
		elseif chosenModeBoolValue.Name == "Reversed" then
			reversedModeModule.ChooseRoles()
		elseif chosenModeBoolValue.Name == "Deathmode" then
			deathModeModule.ChooseRoles()
		elseif chosenModeBoolValue.Name == "MurderMystery" then
			murderMysteryModule.ChooseRoles()
		end

		local modeStartTime = tick() -- Record the time when the mode starts

		for i = roundLength, 0, -1 do
			local elapsedTime = tick() - modeStartTime
			local remainingTime = roundLength - elapsedTime

			status.Value = "Crew escapes in " .. formatTime(remainingTime) .. " Minutes"
			RoundTimer.Value = remainingTime  -- Update RoundTimer with remaining time

			local playing = {}
			local murderer = nil
			local nonMurderers = {}
			local death = nil 

			for _, plr in pairs(game.Players:GetChildren()) do
				if plr.Team.Name == "Playing" then
					table.insert(playing, plr.Name)
					if chosenModeBoolValue.Name == "Deathmode" then
						if plr:WaitForChild("Role").Value == "Death" then
							death = plr
						elseif plr:WaitForChild("Role").Value == "Rogue" then
							murderer = plr
						else
							table.insert(nonMurderers, plr)
						end

					else
						if plr:WaitForChild("Role").Value == "Rogue" then
							murderer = plr
						else
							table.insert(nonMurderers, plr)
						end
					end
				end
			end
			
			if murderer and not death and #nonMurderers == 0 then
				status.Value = "The Rogue has Won this Round"
				Sounds.Murder:Play()
				wait(2)
				chosenModeBoolValue.Value = false
				break
				
			elseif death and (not murderer or i == 0) and #nonMurderers == 0 then
				status.Value = "The Death has Won this Round"
				Sounds.Death:Play()
				wait(2)
				chosenModeBoolValue.Value = false
				break

			elseif death and #nonMurderers > 0 and (not murderer or i == 0) then
				status.Value = "Death helped the Crew"
				Sounds.Innocents:Play()
				Sounds.Death:Play()
				wait(2)
				chosenModeBoolValue.Value = false
				break
				

			elseif #nonMurderers > 0 and (not murderer or i == 0) then
				status.Value = "The Crew won this Round"
				Sounds.Innocents:Play()
				wait(2)
				chosenModeBoolValue.Value = false
				break

			elseif #playing == 0 then
				status.Value = "Everyone died, Round end!"
				wait(3)
				chosenModeBoolValue.Value = false
				break
			

			elseif #playing == 1 then
				status.Value = playing[1] .. " Has Won The Game!"
				for i, plr in pairs(game.Players:GetChildren()) do
					if playing[1] == plr.Name then
					end
				end
				wait(3)
				break
			end
			wait(1)
		end
		wait(3)
	end
end


spawn(round)

I really need help and would be thankful if someone helped me :))

while true do will run forever, consider adding a break and making it more dynamic than just depending on running over and over

Hey! It seems like we’re both working on something similar. For me, I’m making a lobby and the countdown thing for at least 2 players. And I have an AFK button too.

Your approach would eventually “limit” and “constrain” itself due to you having to constantly check the amount of not AFK players and intercept the main loop etc, etc, and on and on and on. It get’s tough, and I understand how fustrated you may be, especially with 3 hours in.

I’m a scripter for around 5 years already, and here’s my approach:
(Quick glance: My approach was to use functions and coroutines.)

Starting Lobby Countdown

So I have a list of “active” players (players that are not AFK). Whenever a player joins, add them to the list. Then, check if #listOfActivePlayers at least 3. If so, then start countdown thread.

Canceling the Lobby Countdown

What to do if it was counting down but some player left or went AFK.

Whenever a player AFK or leaves, use a function that removes the player from the list check if #listOfActivePlayers is less than 3. If so, then cancel (aka close/kill) countdown thread.

I can type some more, if needed, but this should direct you in a general right direction.