How should i "interrupt" my round service loop

Hello devs,
i have this round script, sorry ikk its long, and i have this event that fires perfectly when a player wins. This all works fine, but i want it so that when the win event is called, the round will end. I’ve tried putting the timeLeft to 0, but that changes the music to the lobby music, but it doesnt teleport the player or destroy the map, and if you see my print statement print("got here 1") and print("got here 2") it only prints got me here 1. Heres my script.

local roundTime = 500
local intermissionTime = 10
local timeLeft
local status
local roundHandler = game:GetService("ReplicatedStorage"):WaitForChild("RoundHandler")

local transitionEndedEvent = game.ReplicatedStorage.TransitionEnded

local maps = {
	"Robloxian House",
	"Castle"
}

local winner

local mapFolder = workspace.CurrentMap

local lobbyMusic = game.ServerStorage.Music.Lobby:Clone()
local gameMusic = game.ServerStorage.Music.Game:Clone()

lobbyMusic.Parent = workspace

local clientWonEvent = game.ReplicatedStorage.WonEvent
local wonEvent = game.ServerStorage.WonEvent

local function protectorCharLoad(plr)
	local protectorValue = plr.ProtectorCharacter
	local oldCharacter = plr.Character
	local newCharacter = game:GetService("ServerStorage"):WaitForChild("Characters").Protectors:FindFirstChild(protectorValue.Value):Clone()
	
	newCharacter.HumanoidRootPart.Anchored = false
	newCharacter:SetPrimaryPartCFrame(oldCharacter.PrimaryPart.CFrame)
	
	
	plr.Character = newCharacter
	newCharacter.Parent = workspace.InGameChars.Protector
	return plr
end

local function destroyerCharLoad(plr)
	local destroyerValue = plr.DestroyerCharacter
	local oldCharacter = plr.Character
	local newCharacter = game:GetService("ServerStorage"):WaitForChild("Characters").Destroyers:FindFirstChild(destroyerValue.Value):Clone()

	newCharacter.HumanoidRootPart.Anchored = false
	newCharacter:SetPrimaryPartCFrame(oldCharacter.PrimaryPart.CFrame)


	plr.Character = newCharacter
	newCharacter.Parent = workspace.InGameChars.Protector
	return plr
end


timeLeft = intermissionTime
status = "Intermission"
task.wait(1)

wonEvent.Event:Connect(function()
	timeLeft = 1
	status = "Game"
	winner = "Destroyers"
end)

while true do
	if timeLeft ~= 0 then
		timeLeft -= 1
	else
		if timeLeft == 0 then
			if status == "Intermission" then
				winner = nil
				timeLeft = roundTime
				status = "Game"
				gameMusic:Play()
				gameMusic.Parent = workspace
				
				if lobbyMusic.IsPlaying == true then
					lobbyMusic:Stop()
					lobbyMusic.Parent = game.ServerStorage.Music
				end
			else
				timeLeft = intermissionTime
				status = "Intermission"
				
				lobbyMusic:Play()
				lobbyMusic.Parent = workspace
				
				if winner == nil then
					winner = "Protectors"
				else
					winner = "Destroyers"

				end
				
				clientWonEvent:FireAllClients(winner)
				
				if gameMusic.IsPlaying == true then
					gameMusic:Stop()
					gameMusic.Parent = game.ServerStorage.Music
				end
				print("got here 1")
			end
		end
	end
	if status == "Game" and timeLeft == roundTime then
		
		local ranNum = math.random(1, #maps)
		local map = game:GetService("ServerStorage"):WaitForChild("Maps"):FindFirstChild(maps[ranNum]):Clone()
		map.Parent = workspace.CurrentMap
		
		
		local roundSpawnPart = map:WaitForChild("SpawnPart")
		
		task.wait(1)
		
		for i, v in game.Players:GetChildren() do
			v.Character:MoveTo(roundSpawnPart.Position)
			transitionEndedEvent.OnServerEvent:Wait()
			if v.GameTeam.Value == "Destroyer" then
				destroyerCharLoad(v)
			elseif v.GameTeam.Value == "Protector" then
				protectorCharLoad(v)
			end
		end
	end
	
	if status == "Intermission" and timeLeft == intermissionTime then	
	
		for i, v in game.Players:GetChildren() do
			transitionEndedEvent.OnServerEvent:Wait()
			v.Character.Humanoid.Health = 0
		end
		
		for i, v in workspace.CurrentMap:GetChildren() do
			v:Destroy()
		end
		
		print("got here 2")
		
	end	
	roundHandler:FireAllClients(timeLeft, status, roundTime, intermissionTime)
	task.wait(1)
end

Im sorry its so long, its one of my main scripts. Id love if you had a look at it, as i’m stumped. Also any optimisation suggestions are welcome, but this is mainly about ending the round.

1 Like

Honestly this is hard to read so it’s hard to answer. You should really try breaking it up into more functions to make it easier to understand what everything does.

For a bit of an example

while true do
    createMap() --Picks and loads upfront so it can finish replicating during intermission
    intermission() --yields until enough players, counts down while being willing to restart itself if players leave at any point
    teleportPlayers() --assign teams, teleport them
    roundHandler() --track whatever data you need to determine when round ends, like if there are players alive in a team.  I recommend making your timer on another task.spawn() and just have a round counter you add 1 to at the end of every round that causes the timer to stop automatically once the round ends and storedRoundNumber ~= roundNumber
    roundEnded() --handle presenting the winners and teleporting all players back or any round cleanup
end

If each of those or similar functions does what it should the problem you are facing will go away since once round returns, the game continues automatically with no complex if/else structure to handle multiple things in a loop.

As to your specific problem though it’s hard to tell because I can’t test this. Too many external dependencies and cleaning them up to run in a baseplate would be a lot as well as potentially get rid of a subtle bug if I’m not paying enough attention. I can tell you a good strategy is right before each if, try printing the values so you can see why it’s not triggering. You should print(status) and print(timeLeft) to make sure they are “Intermission” and intermissionTime accordingly. That will be spammy since this runs every second unless you create a roundEnded variable and print only when the round ends, but the spam version will work so long as you can find the right prints since you are trying to debug a specific part.

2 Likes

Hi there, I don’t have a lot of time, but I suggest that you check your scopes. Also, I suggest that you break your code down into more functions and add comments. This makes it a lot easier to read and debug in the future. I have picked out something that may be a reason for your issue, it might not be. When destroying the map in the final if statement, you didn’t start your scope with ‘game.Workspace’. Sorry that I don’t have much time to look through all of this.

1 Like

Thanks both of u, I’m soz its hard to read, I will definitely optimise and make it easier to read in the future. I did find what was causing it, in my local script that listens for the wonEvent, it has an error which is basically saying the winner is nil, which is bcus i made it if the “Destroyers” hadn’t won by the end, winner = nil. This stopped the local script from continuing, and in the round script, I had transitionEndedEvent.OnServerEvent:Wait() which would be called normally fine in the local script, but the error stopped it from being called, so it basically waited forever. Thanks for the tips on my scripting skills tho, and your effort to help, thanks all!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.