Stopping a Countdown timer/Ending Round

Hello,

I’ve attempted to adapt my team-deathmatch script back into a traditional deathmatch where players must get X points to win. Only problem is, after the player is declared the winner, the countdown timer for the round does not end, it keeps going to zero where it will declare “no winner.”

I’ve gone back and forth adding breaks/ends to see where I’ve gone wrong, but this results in me breaking more things. :smiley: Pretty sure this is something simple, and I’ve just overlooked it from repeated attempts. No error outputs. I’m thinking I’ve missplaced a break/end, but I’m just not having any luck anymore after several hours of back and forth.

Script inside ServerScriptStorage - I’ve edited out the parts that aren’t affecting anything, and I know these pieces work from my team scripts, and from various edits on my part succeeding, there’s nothing overly fancy about this basic rounds system script:

while true do
--Lobby Cloning, Map selection, grabs and teleports players, Lobby breaking

local maxscore = game.Players.NumPlayers * 3 - 2
maxscoredisplay.Value = maxscore
local roundtime = 90 + (game.Players.NumPlayers - 1)*30

for i = roundtime, 0, -1 do
	if i == 0 then
			wait(2)
		status.Value = 'Time Up! No Winner!'
			wait(1)
	break
	else end
			wait(1)
		
		for p, player in pairs(game.Players:GetPlayers()) do
			wait()
			if player.leaderstats.Roundkills.Value >= maxscore then
				WinnerCheckEvent:Fire(player) --BindableEvent
				wait()		
				break	
			else end
				status.Value = i..' seconds remaining!'	
				break 	 
		end
end	

-- Win status screen, Lobby cloning back, players returned to Lobby,

end -- closes while true do loop.

And this is the BindableEvent script that confirms the player has the necessary Roundkills needed to win the match:

WinnerCheckEvent.Event:Connect(function(player)
	if player.leaderstats.Roundkills.Value >= MaxScore.Value then
			wait(2)
			status.Value = player.name..' is the Winner!'
			wait(1)
				player.leaderstats.Coins.Value = player.leaderstats.Coins.Value +5
	end 
end)

Thank you again! Any assistance is much appreciated.

2 Likes

I’m pretty sure that your problem lies here:

for p, player in pairs(game.Players:GetPlayers()) do
		wait()
		if player.leaderstats.Roundkills.Value >= maxscore then
			WinnerCheckEvent:Fire(player) --BindableEvent
			wait()		
			break	
		else end
			status.Value = i..' seconds remaining!'	
			break 	 
	end

More specifically here:

if player.leaderstats.Roundkills.Value >= maxscore then
		WinnerCheckEvent:Fire(player) --BindableEvent
		wait()		
		break
else end

The break is only exiting the loop that loops through the players to check if they have a score above the max score, not the round timer for loop.

Hope this helps! :smile:

2 Likes

You could do with a debounce that tells the timer loop whether the round is still active.

For timer
    If winnerDeclared then break end
    For players
        If playerScore >= maxScore then 
            winnerDeclared = true
            Break
        End
    End
End

Sorry for the cheap code but im on mobile

1 Like

Thank you both for your response! I’ve tried doing this, removing the Break, adding a Debounce, currently when the match loads, the Countdown jumps straight to 0 and “Times Up! No Winner!” line happens, and the match ends. :smiley: Can you let me know where I’ve gone wrong below? Many many thanks!!

local maxscore =  2 --game.Players.NumPlayers * 3 - 2
local roundtime = 60 + (game.Players.NumPlayers - 1)*30
local winnerDeclared = false

for i = roundtime, 0, -1 do
	if i == 0 then 
		status.Value = 'Time Up! No Winner!'
			wait(1) 
	break 
	end
if winnerDeclared == true then break end
	for p, player in pairs(game.Players:GetPlayers()) do
		if player.leaderstats.Roundkills.Value >= maxscore then
			winnerDeclared = true
			WinnerCheckEvent:Fire(player)
			break
		else status.Value = i..' seconds remaining!'

		end
	end	
end

I think that you’re for loop isn’t structured incorrectly… I can’t check at the moment because I’m on mobile but instead of having it:
For I = roundtime, 0, -1 do
Make it:
For I = 0, roundtime, -1 do
Hope this helps

1 Like

You’re not waiting at all here:

so the loop runs through almost instantly

Also @RedDuck765, his format is correct as it’s a countdown

1 Like

Oh right thanks for noticing my mistake :smile:

1 Like

Ah! Thanks for that! I can’t believe I forgot the wait(). x.x; Unfortunately, the countdown is still running really fast, instead of a single second decrease, I’m getting dozens of seconds at once, do I need another Break? Also, only Player1 can win, not Player2, even if Player2 hits the max score needed first.

local maxscore =  2
local roundtime = 90 + (game.Players.NumPlayers - 1)*30
local winnerDeclared = false

for i = roundtime, 0, -1 do
	if i == 0 then 
		wait(2)
		status.Value = 'Time Up! No Winner!'
			wait(1) 
	break 
	end
if winnerDeclared == true then break end
	wait()
	for p, player in pairs(game.Players:GetPlayers()) do
		wait()
		if player.leaderstats.Roundkills.Value >= maxscore then
			winnerDeclared = true
			WinnerCheckEvent:Fire(player)
		wait()	
			break
		else end 
			wait()
			status.Value = i..' seconds remaining!'
			wait()
			break
	end	
end

Is it the way I’m checking the player that’s only allowing Player1 to win?

	for p, player in pairs(game.Players:GetPlayers()) do

Thank you again for your assistance! :slight_smile:

To fix the seconds running down fast, try this code:

local maxscore =  2
local roundtime = 90 + (game.Players.NumPlayers - 1)*30
local winnerDeclared = false

for i = roundtime, 0, -1 do
	if i == 0 then 
		wait(2)
		status.Value = 'Time Up! No Winner!'
		wait(1) 
	break 
	end
if winnerDeclared == true then break end
	for p, player in pairs(game.Players:GetPlayers()) do
		wait()
		if player.leaderstats.Roundkills.Value >= maxscore then
			winnerDeclared = true
			WinnerCheckEvent:Fire(player)
		    wait()	
			break
		else end 
			status.Value = i..' seconds remaining!'
			wait(1)
			break
	end	
end

As for the player issue, try replacing

for p, player in pairs(game.Players:GetPlayers()) do

with

for p, player in pairs(game.Players:GetChildren()) do

Changing to :GetChildren() will most likely not fix his player issue. :GetPlayers() functions similarly but is superior because it ignores anything that isn’t a player object.

game:GetService("Players"):GetPlayers() -- table of player objects
game:GetService("Players"):GetChildren() -- table of all objects in Players

Also, OP, afaik NumPlayers is deprecated in favor of #Players:GetPlayers(). I don’t think it’s causing any issues but it’s definitely something to keep in mind.

Ok I got back and was able to test your code and I found your issue.
Your problem was that you exited the for loop that checks to see if someone has got above the max score after the first iteration, meaning that you only check if the first player has got above the max score. The code I am attaching also fixes the actual countdown feature of the code.

local maxscore =  2
local roundtime = 90 + (#game.Players:GetPlayers() - 1)*30
local winnerDeclared = false

wait(2)
for i = roundtime, 0, -1 do
	if i == 0 then 
		status.Value = 'Time Up! No Winner!'
		wait(1) 
		break 
	end
	if winnerDeclared == true then 
		break 
	end
	for p, player in pairs(game.Players:GetPlayers()) do
		if player.leaderstats.Roundkills.Value >= maxscore then
			winnerDeclared = true
			WinnerCheckEvent:Fire(player)
			break			
		end 
	end
	status.Value = i..' seconds remaining!'
	wait(1)
end

I tested it so it should work. Let me know if there are any more issues!

2 Likes

YES! :smiley: Yes! Thank you so very much! It worked! So many thanks to you! And also thanks to everyone else who took a look and provided some valuable insight. Thank you!

No problem glad i could help! :smile:

1 Like