Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do I stop this for loop after it looks through all players?

So I got a function that will pick 2 random players but it first loops through the players to make sure that the players it picks want to play

it picks the players they get teleported to the map but the countdown doesn't occur

I made comments in the code to try to see what happens basically it loops through the players nonstop despite me trying to stop it from looping

	function pickrandom()
		   local players = game.Players:GetPlayers()
			d = game.Players.NumPlayers
		for _, player in pairs(players) do
			if d <= 0 then
				print('scan completed')
				break 
			else
				d = d - 1 
				print(d)
		if player:FindFirstChild("isDueling").Value == "false" then
			table.remove(players, player)
				end
			end
		end
    	player1 = table.remove(players, math.random(#players))
    	player2 = players[math.random(#players)]
    	plr1.Value = player1.Name
    	plr2.Value = player2.Name
	end

FULL SCRIPT

local replicatedStorage = game.ReplicatedStorage
local status = replicatedStorage:WaitForChild('InfoValue')
local mapstorage = workspace.Mapstorage
local mapinfo = replicatedStorage:WaitForChild("Map")
local plr1 = replicatedStorage:WaitForChild("plr1")
local plr2 = replicatedStorage:WaitForChild("plr2")
local plr1died = replicatedStorage:WaitForChild("Player1Died")
local plr2died = replicatedStorage:WaitForChild("Player2Died")
local gamepass = game:GetService("GamePassService")
local id2x = 452864179

local player1
local player2

_G. inbattle = false

_G. playing = {}

local intermissionTimer = 15

while true do
	while game.Players.NumPlayers < 2 do
		status.Value = "The game requires a minimum of 2 players please invite a friend or patiently wait.."
		repeat wait(2) until game.Players.NumPlayers >= 2
	end
	
	for i = intermissionTimer,0,-1 do
		status.Value = "Intermission : "..i
		wait(1)
	end

	function giveplayer1skin()
			local sword = replicatedStorage.Sword
			local newsword = sword:Clone()
			newsword.Parent = game.Players:FindFirstChild(plr1.Value).Backpack
	end
	
	function giveplayer2skin()
			local sword = replicatedStorage.Sword
			local newsword = sword:Clone()
			newsword.Parent = game.Players:FindFirstChild(plr2.Value).Backpack
	end

function pickrandom()
local canBePicked = {}
    for _, v in pairs(game.Players:GetPlayers()) do
        if v:FindFirstChild("isDueling").Value == "true" then -- The '== true' or '== false' is unnecessary.
            table.insert(canBePicked, v)
        end
    end

    player1 = table.remove(canBePicked, math.random(#canBePicked))
    player2 = canBePicked[math.random(#canBePicked)]
    plr1.Value = player1.Name
    plr2.Value = player2.Name
end


	local mapinserverstorage = game:GetService('ServerStorage'):GetChildren()
	local chosenmap = mapinserverstorage[math.random(1, #mapinserverstorage)]
	wait(1)
	local spawn1 = chosenmap:WaitForChild("Spawns"):WaitForChild("Spawn1")
	local spawn2 = chosenmap:WaitForChild("Spawns"):WaitForChild("Spawn2")
	
		mapinfo.Value = chosenmap.Name
		status.Value = "Loading Map : ".. chosenmap.Name
		chosenmap:Clone().Parent = mapstorage
		wait(3)
		status.Value = "Get ready to be teleported!"
		pickrandom()
		wait(1)
					plr1died.Value = false
					plr2died.Value = false
					wait(1)
					game.Players:FindFirstChild(plr1.Value).Character.Torso.CFrame = CFrame.new(spawn1.Position + Vector3.new(0,2,0))
					game.Players:FindFirstChild(plr2.Value).Character.Torso.CFrame = CFrame.new(spawn2.Position + Vector3.new(0,2,0))	
					wait(1)
					giveplayer1skin()
					giveplayer2skin()
					
		
		for i = 60, 0, -1 do
			if i == 0 then
				status.Value = "Time up!"
				-- kill players left in ring
				if game.Players:FindFirstChild(plr1.Value) then
					game.Players:FindFirstChild(plr1.Value):LoadCharacter()
					end
				if game.Players:FindFirstChild(plr2.Value) then
					game.Players:FindFirstChild(plr2.Value):LoadCharacter()
				end
				
				plr1died.Value = false
				plr2died.Value = false
				_G.inbattle = false
				break
			else 
			end
			
			wait(1)
			if _G.inbattle == true then
			if plr1died.Value == true then
				status.Value = "Calculating Player Stats..."
				wait(3)
					if plr1died.Value == true and plr2died.Value == true then
						status.Value = plr1.Value.. " Tied with ".. plr2.Value
						break
					else
						if gamepass:PlayerHasPass(game.Players:FindFirstChild(plr2.Value), id2x) then
						game.Players:FindFirstChild(plr2.Value):WaitForChild("leaderstats").Cash.Value = game.Players:FindFirstChild(plr2.Value):WaitForChild("leaderstats").Cash.Value + 500
						else
						game.Players:FindFirstChild(plr2.Value):WaitForChild("leaderstats").Cash.Value = game.Players:FindFirstChild(plr2.Value):WaitForChild("leaderstats").Cash.Value + 250		
						end
						game.Players:FindFirstChild(plr2.Value)['leaderstats'].Wins.Value = game.Players:FindFirstChild(plr2.Value)['leaderstats'].Wins.Value + 1
						wait(2)
						game.Players:FindFirstChild(plr2.Value):LoadCharacter()
						wait(1)
						status.Value = plr2.Value.. " Defeated ".. plr1.Value -- victory text
						plr1.Value = ""
						plr1died.Value = false
						plr2.Value = ""
						_G.inbattle = false
						break
						end
			elseif plr2died.Value == true then
				status.Value = "Calculating Player Stats..."
				wait(3)
					if plr2died.Value == true and plr1died.Value == true then
						status.Vaslue = plr2.. " Tied with ".. plr1.Value
						break
						else
					end
						if gamepass:PlayerHasPass(game.Players:FindFirstChild(plr2.Value), id2x) then
						game.Players:FindFirstChild(plr1.Value):WaitForChild("leaderstats").Cash.Value = game.Players:FindFirstChild(plr1.Value):WaitForChild("leaderstats").Cash.Value + 500
						else
						game.Players:FindFirstChild(plr1.Value):WaitForChild("leaderstats").Cash.Value = game.Players:FindFirstChild(plr1.Value):WaitForChild("leaderstats").Cash.Value + 250
						end
						game.Players:FindFirstChild(plr1.Value)['leaderstats'].Wins.Value = game.Players:FindFirstChild(plr1.Value)['leaderstats'].Wins.Value + 1
						wait(2)						
						game.Players:FindFirstChild(plr1.Value):LoadCharacter()
						wait(1)
						status.Value = plr1.Value.. " Defeated ".. plr2.Value -- victory text
						plr1.Value = ""
						plr2.Value = ""
						plr2died.Value = false
						_G.inbattle = false
						break
			else
			end
				status.Value = i.. " seconds remaining!" -- this is what makes the countdown
			end
		end
	mapstorage:ClearAllChildren()
wait(5)
end

can someone help me make the loop stop after it loops through all the players

1 answer

✓ Accepted answer

One problem is that you are removing items from the table as it is being traversed, which does not work well. Another problem is that when you call table.remove, instead of passing the index, you pas the value. Thirdly, I assume that isDueling is a BoolValue, in which case == "false" will not work (you are comparing it to a string rather than an actual boolean).

The way I would do something like this is to create a table of players who do satisfy the criterion for being picked, like this:

local canBePicked = {}
for _, v in pairs(game.Players:GetPlayers()) do
	if v:FindFirstChild("isDueling").Value then -- The '== true' or '== false' is unnecessary.
		table.insert(canBePicked, v)
	end
end

Then pick two random people from that list. In your function, it would look like this:

function pickrandom()
local canBePicked = {}
	for _, v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("isDueling").Value then -- The '== true' or '== false' is unnecessary.
			table.insert(canBePicked, v)
		end
	end

	player1 = table.remove(canBePicked, math.random(#canBePicked))
	player2 = canBePicked[math.random(#canBePicked)]
	plr1.Value = player1.Name
	plr2.Value = player2.Name
end

1 comment

0

so I edited my question and added the full script basically there's a for loop that has a countdown, but the countdown isn't showing it's stuck at teleporting players

This discussion is preserved as it was. New answers, comments, and votes are closed.