How to loop through players

Hello! My name is Eli, and I’d like to know how to loop through players. This kind of embarrases me, because is should know for loops by now. Well, I do know them. But not looping through tables. Anwyays, I’d like help. Here is my script so far:

   print('Loading match script')
   local numplayer = game.Players.NumPlayers
local enoughplayers = 1
local status = game.ReplicatedStorage:WaitForChild('Status')
print('MatchScript: there is curently ' .. numplayer .. ' player(s) online')
print('Starting loop')
while true do
 status.Value = 'Waiting..'
if numplayer <=enoughplayers then
	print('Enough players!')
	status.Value = 'Choosing simon..'
	local plrs = game.Players:GetPlayers()
	local randomplr = plrs[math.random(1,#plrs)]
	game.ReplicatedStorage:WaitForChild('Simon').Value = randomplr.Name
	local simon = game.ReplicatedStorage:WaitForChild('Simon')
	print(simon.Value .. ' is the simon')
	status.Value = simon.Value .. ' is the simon!'
	--for i = what

I would really appreciative help. Thanks!


You would do:

for i,v in pairs(game.Players:GetChildren()) do
-- v is your player

You can use pairs to run through a table. The Players service has a method called GetPlayers(), which returns an unsorted list of all players in the game.

You can iterate through them like so:

local Players = game:GetService("Players") -- you should use GetService over game.Players!
for _, player in pairs(Players:GetPlayers()) do
    -- this code will run for all players

Note that if the loop is broken, returned, or an error occurs the loop will stop.

You should always have helpful variable names, and not use unneeded variables.

for i,v in pairs(array) do
   -- we may not need i here
   -- besides, what is v meant to be??

Your code should always be optimized for reading!!


You should use ipairs over pairs. GetPlayers returns an array, ipairs runs quicker and it’s idiomatic for contiguous arrays. pairs is designed more for a dictionary where your keys aren’t known (noting that it returns next).

Use cases aside, it’s also good for collaborators and being clear as to what part of the table you’re intending to traverse through. I know when I see ipairs I understand that an array is being iterated over.


Well it’s a good idea, might work but in all honesty it’s not quite efficient (very inefficient).

@ElliottLMz Firstly I don’t see the need to index all players , on top of unnecessarily iterating through them in key, value pairs. It would take significantly less time returning values through index, value pairs, that is in ipairs, which I recommend you to use over in pairs for this case.


Here’s a sample of what you would do to print players’ names , by iterating through an array of players :

   local Players = game:GetService("Players")
       Players.PlayerAdded:Connect(function()--each time a player is added
   --// Loop through all existing players and..print everyone's name
      for _, player in ipairs(Players:GetPlayers()) do
        print("Player name : ".. player.Name)

However if you would want to not print everyone’s name each time a player joins, you could save the player’s names in table to prevent duplicate prints, like :

 local Players = game:GetService("Players")
  Current_Players = {}--we will save player's names here
  Players.PlayerAdded:Connect(function()--each time a player is added
--// Loop
   for _, player in ipairs(Players:GetPlayers()) do
       if Current_Players[player.Name] then--if he is already in the table then
	 return--or you could do if table.find(Current_Players,player.Name) etc.
    print(player.Name.. " has joined the game")


what do you mean?
v here would be the player, it’s necessary,
also using pairs here is a terrible idea as we don’t actually need to go through key value pairs, as @PostApproval already mentioned something similar , your code would also not work at all, unless you connect the loop to an event , that runs after players actually exist in the game. (like players.PlayerAdded)


I was honestly just answering the question on how to loop through all players quickly and not trying to give the most efficient way (I should have)

1 Like

What does “idiomatic for contiguous arrays” mean? I’m not quite understanding the advantage ipairs has over pairs.

ipairs runs faster for arrays ({"this", "is", "an", "array"). This is also reccomended by Roblox.

It’s easy to just pick pairs to iterate over any table but that often is a product of not understanding ipairs or what’s going on behind a for loop.

ipairs is designed to iterate over the array part of a table at an incremental level (index i+1 per iteration). ipairs will also guarantee ordered iteration and terminate at the first hole in an array. ipairs also makes it clear that what you’re iterating over is an array.

pairs, on the other hand, is designed to iterate over the hash part of a table. pairs is slightly slower because the keys aren’t known to the generator at the start, so it calls next to find which key-value pair should be iterated over next.

LuaU optimisations sped both generators up by a large amount, however ipairs saw the greater increase as noted by some benchmarks at RDC 2019 for the Lua As Fast As Possible presentation.


Using pairs, the iterator function is the next function, meaning if a value isn’t found for each key then it would return nil rather than stop the loop.

Ipairs on the other hand, iterates through index value pairs rather than key value pairs, and if nil is encountered through 1 to #t then the loop would stop.

Using Index value pairs (in ipairs ) also requires lesser time as no value is associated with keys, for example :

 for  i = 1 ,#t
   print ( t[i] ) 

Use ipairs where speed matters, and key value association is unnecessary.

Slightly unrelated: but is ipairs a recent thing? I’ve seen older scripts do:

local fruits = {"Apple", "Pear", "Pineapple", "Grapes"}

for i=1, #fruits do
    local fruit = fruits[i]

Was this to keep code fast before ipairs?

ipairs is not recent, it has existed since old versions of Lua (so for years). A numeric for loop was more common to use before LuaU optimisations because for whatever reason, Roblox’s implementation of ipairs was reported as noticeably slow enough not to use it. ipairs now sits as the fastest generator.

Will recomend you to use for i,v in pairs

FX. for i,v in pairs(game.Players:GetChildren()) do
i: is how many times the loop has looped and v: is the players
Hope that makes sense

As afforementioned, that is an inefficient method. Moreover, this topic is already solved.

  • i and v are unclear
  • You should be using GetService
  • ipairs is more efficient for arrays
1 Like

's not how pairs works. i, v is a key-value pair of an associative array and pairs specifically traverses through the hash part of a table implementing next to search for the next pair.

1 Like

There is 2 ways to use for i,v in pairs u can do
local fruits = {“Apple”, “Pear”, “Pineapple”, “Grapes”
for i=1, #fruits do
local fruit = fruits[i]
or just do what i just said

Those are different and the one you just posted does not implement pairs. Pairs is a generator for a generic for loop, what you wrote is a numeric for loop. Numeric for loops deal in incremental indices and lookups only. You have an array so use ipairs. Scroll up for more information.

Reading material on for loops: - Numeric for - Generic for


Ohhh, well thx for the help i didn’t know that

Hello, I’m sort of new In scripting, May I ask why sometimes in “for” you need to have “`i, v” what both of the characters stand for? Thanks for the solution tho.

The first value in this case is index, how many times you’ve looped so far. V is the value of the list.
You need them because it’s for _,v in pairs, which is why there’s two values, it’s a pair.
Also you shouldn’t necrobump, especially 3 years later. There’s plenty of explanations out there for that.

Could somebody explain for i, v in pairs