Break a For Loop When a Winner is Found

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I want to stop the “round” for loop when a winner is found.

  1. What is the issue? Include screenshots / videos if possible!

The issue is, after I break the for loop both timers don’t line up and music plays at the wrong times, players freeze and don’t unfreeze.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I fired a remote event to the winner’s client and from there, fired another to the server. Then I changed a variable when the event was picked up on the server and broke the loop when the variable was changed via the “.Changed” event.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local roundlength = 45
local intermissionLength = 10
local InRound = game.ReplicatedStorage.InRound
local Status = game.ReplicatedStorage.Status
local camRemote = game.ReplicatedStorage.Remotes.ChangeCameraVectorRE
local MapsFolder = game.ReplicatedStorage.Obbies
local Maps = MapsFolder:GetChildren()
local ChangeMapRE = game.ReplicatedStorage.Remotes.ChangeMapRE
local LobbySpawn = workspace.LobbySpawn

InRound.Changed:Connect(function()
	wait(1)

	if InRound.Value == true then
		--IN GAME
		
		for _, player in pairs(game.Players:GetChildren()) do

			if player.TimePlayed.Value >= 7 then
				game.ReplicatedStorage.Remotes.ChangeBackgroundMusicInRoundRE:FireAllClients(roundlength)

				player.Character:WaitForChild("Humanoid").WalkSpeed = 16

				print("Firing ChangeMapRE")
				ChangeMapRE:FireClient(player)
				print("Should have fired ChangeMapRE")

				player:WaitForChild("leaderstats").Rounds.Value = player:WaitForChild("leaderstats").Rounds.Value + 1
				local char = player.Character
				local spawnCFRAME1 = math.random(-246, -184)
				char.HumanoidRootPart.CFrame = LobbySpawn.CFrame
				char.HumanoidRootPart.Position = Vector3.new(spawnCFRAME1, 34.5, -144)

				camRemote:FireClient(player)
			end
		end
		
		local MapsFolder = game:GetService("ReplicatedStorage").Obbies
		local Maps = MapsFolder:GetChildren()

		local chosenMap = Maps[math.random(1, #Maps)]

		chosenMap.Parent = game.Workspace
		wait(roundlength)
		chosenMap.Parent = game:GetService("ReplicatedStorage").Obbies
		
		if InRound.Value == false then
			--INTERMISSION

			game.ReplicatedStorage.Remotes.ChangeBackgroundMusicIntermissionRE:FireAllClients(intermissionLength)

			for _, player in pairs(game.Players:GetChildren()) do
				player.Character.HumanoidRootPart.CFrame = LobbySpawn.CFrame
			end

		end

	end
end)

local function roundTimer()
	while wait() do
		for i = intermissionLength, 1, -1 do
			InRound.Value = false
			wait(1)
			Status.Value = "Intermission: "..i.." seconds remaining!"

			if i == 3 then
				
				for _, player in pairs(game.Players:GetChildren()) do
					player.Character:WaitForChild("Humanoid").WalkSpeed = 0
				end
				
				game.ReplicatedStorage.Remotes.PlayCountdownAudioRE:FireAllClients()
			end

		end

		for i = roundlength, 1, -1 do
			InRound.Value = true
			
			wait(1)
			Status.Value = "Round: "..i.." seconds remaining!"
		end
	end
end

spawn(roundTimer)

The game is like Tower of Hell but side ways. I need it so that when a player touches the win part, everyone is teleported to the lobby and the intermission loop is ran.

Do you want to break the loop as soon as a winner is found?

Yes, exactly. With that, I want to go back to intermission and teleport all players to the lobby.

Instance a string value called “status”.

`local status = Instance.new("StringValue", player)
status.Name = "Status")

Under the line of code that detects if the player has won write:

player.Status.Value = "Won"

Then in your for loop do

if player.Status.Value = "Won" then
return nil

After the for loop, type:

if player.Status.Value == "Won" then
char.HumanoidRootPart.Position = workspace.Lobby.Positon
end

Then last but not least, do the intermission stuff.

local intermission = player.PlayerGui.Intermission
intermission.Enabled = true
local round = player.PlayerGui.Round
round.Enabled = true

(someone posted probably a better solution than my solution):
I figured out a solution (I’m sure that better solutions exist, but it might work):

  1. When the round ends, make this script disable itself
  2. Make a new script, which will enable back the round based system script back (use Changed or GetPropertyChangedSignal("Disabled") event
    Assuming that the first intermission and round works fine, this method should work (at least I think like that). Consider waiting for me or someone else to make a better solution.

I think that this only teleports the winner, which I already have got done by killing them when they touch the win part.

Oh yeah, just realized that. I’m going to edit the code to teleport EVERYONE and not just the winner.

Instance a string value called “status”.

`local status = Instance.new("StringValue", player)
status.Name = "Status")

Under the line of code that detects if the player has won write:

player.Status.Value = "Won"

Then in your for loop do

if player.Status.Value = "Won" then
return nil

After the for loop, type:

if player.Status.Value == "Won" then
for i,v in pairs(table.find(playersinround, players) do
players.HumanoidRootPart.Position = workspace.Lobby.Position
end
end

Then last but not least, do the intermission stuff.

local intermission = player.PlayerGui.Intermission
intermission.Enabled = true
local round = player.PlayerGui.Round
round.Enabled = true

That works but the issue is, it still goes through the full round. I need to break the loop and change the InRound value (go to intermission on the InRound loop) when a player wins.

Doesn’t return nil break the loop? After return nil, simply change the value of InRound.

The gui is the status.Value in the for loop. Other than that, I will give this a try.

I got a fix, rewrote the whole system!

local roundlength = 45
local intermissionLength = 5
local s = game.ReplicatedStorage.Status
local winner = game.ReplicatedStorage.Winner
local camRemote = game.ReplicatedStorage.Remotes.ChangeCameraVectorRE
local LobbySpawn = workspace.LobbySpawn
t = 0

while true do
	
	t = intermissionLength
	repeat
		t = t - 1
		s.Value = "Intermission: "..t.." seconds!"
		wait(1)
	until t == 0
	s.Value = "Choosing Map!"
	wait(2)
	local mapselect = game.ReplicatedStorage.Obbies:GetChildren()
	local choose = math.random(1, #mapselect)
	curnum = 0
	for i = 1, #mapselect do
		curnum = curnum +1
		if curnum == choose then
			mapselect[i]:Clone().Parent = game.Workspace
			curmap = mapselect[i].Name
			s.Value = "Choose "..mapselect[i].Name
		end
	end
	wait(3)
	local plrs = game.Players:GetChildren()
	for i = 1,#plrs do
		local num = math.random(1,17)
		plrs[i].Character.Head.CFrame = workspace.Teleports["Part"..num].CFrame
		plrs[i].Character.Parent = workspace.InGame
	end
	t = roundlength
	repeat
		t = t - 1
		s.Value = "Racing: "..t.." seconds left!"
		wait(1)
	until
	t == 0 or winner.Value ~= ""
	if winner.Value ~= "" then
		s.Value = winner.Value.." won the game! 🏆"
		winner.Value = ""
	else
		s.Value = "lol no one won.."
	end
	local ingame = workspace.InGame:GetChildren()
	for i = 1, #ingame do
		local plr = game.Players:GetPlayerFromCharacter(ingame[i])
		plr:LoadCharacter()	
	end
	wait(4)
	
end

i’m glad you’ve found the solution!

1 Like