Round Over not functioning properly

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

  1. What do you want to achieve?
    If the game has more than one player in it, when players die or leave the current Round, the Round needs to restart.

  2. What is the issue?
    If there is only one player in the live game the Round will restart (attached video shows this). If other players come into the game the Round does not restart when all players die or leave the round, Instead the timer keeps going. I don’t understand why the Round won’t restart with more than one player in the game. I must be missing something in the script to prevent this from happening and I have not yet learned how to do it.

  3. What solutions have you tried so far?
    Changes have been made to the script to get it working in the state it is in now but it still does not work fully correctly.

Here is a Video showing the game being played, when the one player dies the Round successfully restarts. Sorry for the blurry, I don’t have state of the art equipment so working with what I do have.
robloxapp-20210511-0917163.wmv (4.9 MB)

local lobby_Duration = 30
local round_Duration = 200
local map_Fol = game.ReplicatedStorage:WaitForChild("Map")
local timerval = game.ReplicatedStorage:WaitForChild("TimerValue")



local function RTimer ()
	while wait() do
		for l = lobby_Duration, 0, -1 do
			timerval.Value = 'Intermission: '..l
			wait(1)

			if l == 0 then
				
				local mapCopy = map_Fol:Clone()
				mapCopy.Name = "mapCopy"
				mapCopy.Parent = game.Workspace
				timerval.Value = 'Teleporting players to '..mapCopy.Name
				wait(1)
				mapCopy.Parent = workspace



				wait(2)
				local plrs = game.Players:GetChildren()



				for i = 1, #plrs do

					plrs[i].Character:MoveTo(Vector3.new(-15.254, 6.232, 130.566))


				end	

				local Players = game:GetService("Players")
				local Workspace = game:GetService("Workspace")
				local ReplicatedStorage = game:GetService("ReplicatedStorage")
				local Event = ReplicatedStorage:WaitForChild("DisplayRole")
				local Sword = ReplicatedStorage:WaitForChild("Sword")


				local Killer = nil
				local Survivors = {}

				local pickPlayers = coroutine.wrap(function()
				--function pickPlayers()

					if Killer then
						if Players:FindFirstChild(Killer) then

							if Players[Killer].Bakcpack:FindFirstChild(Sword.Name) then
								Players[Killer].Bakcpack[Sword.Name]:Destroy()
							else
								if Workspace:FindFirstChild(Killer) then
									if Workspace[Killer]:FindFirstChild(Sword.Name) then
										Workspace[Killer][Sword.Name]:Destroy()
									end
								end
							end

						end
					end

					Killer = nil
					Survivors = {}


					local PlayersGroup = Players:GetChildren()
					local KillerID = math.random(1, #PlayersGroup)

					for i, v in pairs(PlayersGroup) do
						if i == KillerID then

							Killer = v.Name


							break
						end
					end

					for i, v in pairs(PlayersGroup) do
						if i == KillerID then

						else
							table.insert(Survivors, v.Name)
						end
					end





					Event:FireClient(Players[Killer], "You are Killer")
					Sword:Clone().Parent = Players[Killer].Backpack
					print("Killer: ".. Killer)
					for i, v in pairs(Survivors) do
						Event:FireClient(Players[v], "You are Survivor")
						print("Survivor: ".. v)

					end

				--end
			end)



				pickPlayers()





				wait(1)
				local players = game:GetService("Players")



			end
		end
		for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   
			if g == 0 then
				timerval.Value = 'Round over'
				wait(2)	
				local function cleanup()
					game.Workspace.mapCopy:Destroy()
				end
				cleanup()
				timerval.Value = 'Teleporting players to lobby'
				wait(1)
				for i = 1, #playersInRound do
					playersInRound[i].Character:MoveTo(Vector3.new(1097.553, -36.89, -26.611))
				end
				wait(1)
				break
						
			end
						
		end
	end
end

spawn(RTimer)

I would suggest having an Alive table which you then check if they are alive,

I also think this might be the culprit, numberdead is a value that only adds when someone dies, this is not very good because someone can just reset in the lobby and tick it up, if somone joins in the middle of the round then uh oh, the number of people won’t be the same as the number of deaths. If you make an Alive table and just check if thats zero then that should fix the problem

Ok Thanks, let me see if I can get this worked into the script. :slight_smile:

On second thought though, I don’t know what to write, is Players Alive a command already set in Lua or do I have to make it a variable.

I tried something like this and it isn’t working:


			local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = {}
			playersAlive[1] = playersInRound
			
			
			
			if playersAlive == 0 then
				
				print("End of Round")
				g = 0
			end
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   

I tried this too and it just ends the Round as soon as it starts and sends everyone back to the lobby so maybe im close but not quite yet there.

local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			local playersAlive = {}
		
			
			
			
			if #playersAlive == 0 then
				
				print("End of Round")
				g = 0
			end
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   

your setting playersAlive to a blank table after you set it to the players… Thats why it ends as soon as it starts

just do

local playersInRound = game.Players:GetPlayers()
local playersAlive = playersInRound

When I do this, the timer keeps running when players die and go back to the lobby. It does not reset.

for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			if #playersAlive == 0 then
				print("End of Round")
				g = 0
			end
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   
			if g == 0 then
				timerval.Value = 'Round over'
				wait(2)	
				local function cleanup()
					game.Workspace.mapCopy:Destroy()
				end
				cleanup()
				timerval.Value = 'Teleporting players to lobby'
				wait(1)
				for i = 1, #playersInRound do
					playersInRound[i].Character:MoveTo(Vector3.new(1097.553, -36.89, -26.611))
				end
				wait(1)
				break
						
			end
						
		end
	end
end

spawn(RTimer)
,,,

& Same if I write it this way, the timer keeps running and it does not reset

	for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			if #playersInRound == 0 then
				print("End of Round")
				g = 0
			end
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   
			if g == 0 then
				timerval.Value = 'Round over'
				wait(2)	
				local function cleanup()
					game.Workspace.mapCopy:Destroy()
				end
				cleanup()
				timerval.Value = 'Teleporting players to lobby'
				wait(1)
				for i = 1, #playersInRound do
					playersInRound[i].Character:MoveTo(Vector3.new(1097.553, -36.89, -26.611))
				end
				wait(1)
				break
						
			end
						
		end
	end
end

spawn(RTimer)

Also it seems like I’m just duplicating the playersInRound that was already written into the script, I don’t see the point of it ? It seems like playersInRound is identical to playersAlive and just a variable named differently being defined two times ? lol

I don’t see where you are removing the players from the in round table when you check if they’re dead.

You should be removing the player from the table here, or else it’s going to keep the same amount of players. You could do this with a simple,

table.remove(playersInRound, i)
continue

Ok I’m not sure I put the table remove in the correct location, I think I did but what happens is when one player dies in the round, the entire round ends and both players are getting teleported back into the lobby and it is restarting. When only one of the players died. lol uuuhhh ?

		for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			if #playersInRound == 0 then
				print("End of Round")
				g = 0
			end
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					table.remove(playersInRound, i)
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   
			if g == 0 then
				timerval.Value = 'Round over'
				wait(2)	
				local function cleanup()
					game.Workspace.mapCopy:Destroy()
				end
				cleanup()
				timerval.Value = 'Teleporting players to lobby'
				wait(1)
				for i = 1, #playersInRound do
					playersInRound[i].Character:MoveTo(Vector3.new(1097.553, -36.89, -26.611))
				end
				wait(1)
				break
						
			end
						
		end
	end
end

spawn(RTimer)

This does not work if I test with 1 or 3 Players ? Why ? It restarts the round if I have two players and one of them dies ? It only works If I test the game with two players ?

		for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			local Players = game.Players:GetPlayers()
			print(Players)
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			if #playersInRound == 0 then
				print("End of Round")
				g = 0
			end
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					table.remove(playersInRound, i)
					end
	       
			end
			if numberdead == #playersInRound then
				print("End of Round")
				g = 0
			end   

If I use this, when i test with two players the Round restarts as soon as the InRound starts yet neither player has died

for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					table.remove(playersInRound, i)
					end
	       
			end
			
			if #playersInRound >= 1 then
				print(playersInRound)
				print("End of Round")
				g = 0
			end

With the below script here is what is now happening in my Round Timer.

One Player - In Studio it starts the round but as soon as the Round starts the Round ends and throws the players back into the lobby to restart
Two Players - In Studio it starts the round and both players can play until one player dies. As soon as one player dies the Round ends and throws the players back into the lobby to restart
Three Players - In Studio it starts the round and if all three players die they go back to the lobby but the Round does not restart so the timer finishes out as if the round did not end

		for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					table.remove(playersInRound, i)
					end
	       
			end
			
			if #playersInRound <= 1 then
				print(playersInRound)
				print("End of Round")
				g = 0
			end

Can anyone explain this to me ? I’ve given a-lot of examples and show that none of them appear to be working as intended yet I do not know what to change to get it working.

I have a Round Based game with a lobby and an InRound map that players are teleported to once the intermission time ends. All players are teleported into the game and a new timer starts for the round. I was trying to script into the game for the Round Timer to end if the players die in the Round. Prior to my making changes the Inround timer would continue even though players had been transported back to the Lobby after dying.

Ive made several different changes to the script trying to get it to work yet it is not fully working correctly still ? I’m reaching out for help. I must have something written incorrectly in the script still yet I don’t know what to write to make this work. I feel its something small yet I can’t figure it out. I need Help.

Why does the help here just suddenly drop off before there is a resolution. I find this to be a pattern each time I reach out for help. Exasperated !

local RunService = game:GetService("RunService")

local roundActive = false

local playersInRound = game.Players:GetPlayers()
local playersAlive = playersInRound

function removeFromAlive(plrName)
    for i, v in pairs(playersAlive) do
        if plrName == v.Name then
            playersAlive[i] = nil
            return
        end
    end
end

function updateAlive()
    while roundActive do
        for i, v in pairs(playersInRound) do
            if v:FindFirstChild("Character") && v.Character:FindFirstChild("Humanoid") then
                if v.Character.Humanoid.Health <= 0 then
                    removeFromAlive(v.Name)
                end
            end
        end

        RunService.Heartbeat:Wait()
    end
end

function startRound()
    roundActive = true

    spawn(updateAlive())

    for g = round_Duration, 0, -1 do
        timerval.Value = "Round" .. g " seconds left"

        if #playersInRound == 1 then
            if #playersAlive <= 0 then
                print("End of Round")
                roundActive = false
            end
        else if #playerInRound > 1 then
            if #playersAlive <= 1 then
                print(playerInRound)
                print("End of Round")
                roundActive = false
            end
        end

        wait(1)
    end
end

wait(10)
startRound() -- Starts round after 10 seconds of the server being online (just an example of how to start it)

I don’t believe the above code would run and work for you, with the code you already have. However, this is the sort of way I’d go about this, and, of course, you can shape it to fit your code and needs. Let me know if you have any questions.

I did try to format mine in a sort of similar fashion with the #playersInRound and #PlayersAlive bit but it still doesn’t work and I’ve come to a conclusion on why it is not working. It works for one or two player mode, but if I test with three players it is not working. I believe it is because when the first two players have died and are teleported back to the spawn/lobby baseplate, they are now being considered alive again ? So by the time the third player is killed or dies its too late for the script to recognize them as dead ? I feel like its a timing issue but of course I may be wrong. This is what I am trying to understand. The tables are not being considered if this is the case until I actually exit a player out of the game when it has 3 players in it. The output shows this is the case. Why is it different for three players ? Why doesn’t it work like it does for one and two players ?

Here is a copy of my output for each game I tested. You can see where the round ends for one player and two players. The print statements work for those. But when we look at the Three Player the prints statements never appear and the round never really ends even though all three players have died and are now in the lobby.
One Player
v60 One Player

Two Players
v60 Two Player

Three Players
v60 Three Players

My current Script is below:
One Player :
If I start the game, once the player is teleported InRound the game immediately stops and restarts b/c it requires two people to play.
Two Players
Players are transported to the InRound map and as soon as one of the players dies the game is over and the game restarts new. Both players go back to the lobby for Intermission and a new round restart.
Three Players
Each player dies one after the other but the Round never Ends. Each player simply teleports back to the lobby baseplate. The InRound timer continues and has to finish out before the game will restart, yet no one is left InRound playing.

local round_Duration = 200
local map_Fol = game.ReplicatedStorage:WaitForChild("Map")
local timerval = game.ReplicatedStorage:WaitForChild("TimerValue")



local function RTimer ()
	while wait() do
		for l = lobby_Duration, 0, -1 do
			timerval.Value = 'Intermission: '..l
			wait(1)

			if l == 0 then
				
				local mapCopy = map_Fol:Clone()
				mapCopy.Name = "mapCopy"
				mapCopy.Parent = game.Workspace
				timerval.Value = 'Teleporting players to '..mapCopy.Name
				wait(1)
				mapCopy.Parent = workspace



				wait(2)
				local plrs = game.Players:GetChildren()



				for i = 1, #plrs do

					plrs[i].Character:MoveTo(Vector3.new(-15.254, 6.232, 130.566))


				end	

				local Players = game:GetService("Players")
				local Workspace = game:GetService("Workspace")
				local ReplicatedStorage = game:GetService("ReplicatedStorage")
				local Event = ReplicatedStorage:WaitForChild("DisplayRole")
				local Sword = ReplicatedStorage:WaitForChild("Sword")


				local Killer = nil
				local Survivors = {}

				local pickPlayers = coroutine.wrap(function()
				--function pickPlayers()

					if Killer then
						if Players:FindFirstChild(Killer) then

							if Players[Killer].Bakcpack:FindFirstChild(Sword.Name) then
								Players[Killer].Bakcpack[Sword.Name]:Destroy()
							else
								if Workspace:FindFirstChild(Killer) then
									if Workspace[Killer]:FindFirstChild(Sword.Name) then
										Workspace[Killer][Sword.Name]:Destroy()
									end
								end
							end

						end
					end

					Killer = nil
					Survivors = {}


					local PlayersGroup = Players:GetChildren()
					local KillerID = math.random(1, #PlayersGroup)

					for i, v in pairs(PlayersGroup) do
						if i == KillerID then

							Killer = v.Name


							break
						end
					end

					for i, v in pairs(PlayersGroup) do
						if i == KillerID then

						else
							table.insert(Survivors, v.Name)
						end
					end





					Event:FireClient(Players[Killer], "You are Killer")
					Sword:Clone().Parent = Players[Killer].Backpack
					print("Killer: ".. Killer)
					for i, v in pairs(Survivors) do
						Event:FireClient(Players[v], "You are Survivor")
						print("Survivor: ".. v)

					end

				--end
			end)



				pickPlayers()





				wait(1)
				local players = game:GetService("Players")



			end
		end
		for g = round_Duration,0, -1 do
			timerval.Value = 'Round '..g..' seconds left'
			wait(1)


			
			local playersInRound = game.Players:GetPlayers()
			local playersAlive = playersInRound
			
			
			

					-- now we can iterate through playerlist and connect
			numberdead = 0
	      	for i,P in ipairs (playersInRound) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
					if humanoid.health == 0 then
					numberdead = numberdead + 1
					table.remove(playersInRound, i)
					end
	       
			end
			
			for i,P in ipairs (playersAlive) do
				local humanoid = P.Character and P.Character:FindFirstChildOfClass("Humanoid")
				if humanoid.health == 0 then
					numberdead = numberdead + 1
					table.remove(playersAlive, i)
				end

			end
			
			if #playersInRound <= 1 then
				print(playersInRound)
				print(playersAlive)
				print("End of Round")
				g = 0
			end
			--if numberdead == #playersInRound then
				--print("End of Round")
				--g = 0
			--end   
			if g == 0 then
				timerval.Value = 'Round over'
				wait(2)	
				local function cleanup()
					game.Workspace.mapCopy:Destroy()
				end
				cleanup()
				timerval.Value = 'Teleporting players to lobby'
				wait(1)
				for i = 1, #playersInRound do
					playersInRound[i].Character:MoveTo(Vector3.new(1097.553, -36.89, -26.611))
				end
				wait(1)
				break
						
			end
						
		end
	end
end

spawn(RTimer)

The more I sit here and think about it too, I don’t think the table remove is working at all in any of the scenarios.

I tested this with more print statements. With only one player my username never gets removed from the table so that definitely is not working. That tells me the lines of code doing remove are useless and can be taken out all together, or need more written to get them to work.

Tables Output window