I was having difficulties with the PlayerAdded event running before the listener had time to finish loading. After looking around I found a solution given by two separate Roblox staff members that included a small restructuring as well as a for loop. Here is an example of the code before and after:
BEFORE works about 70% of the time:
players.PlayerAdded:Connect(function(player)
--code to initialize session tables and such
end)
AFTER playerAdded works 100% of the time:
local function playerAdded(plr)
--code to initialize session tables and such
print("This runs once") -- prints only once
end
for _,player in pairs(players:GetPlayers()) do
print("test") -- never prints
playerAdded(player)
end
players.PlayerAdded:Connect(playerAdded)
My question is: why doesn't it print out anything in the for loop? The for loop isn't nested within an if statement or some other loop; it is at the highest scope within the script, so it runs after all the variable declarations and such.
I was hesitant to use this for loop because it seemed as though playerAdded will run twice, but it doesn't, why? I'm happy it works, but I'd rather understand why it works. Thank you for the help.
[EDIT] I'm well aware this is a solution to a studio play-solo bug. The for loop isn't needed on a live server, but I test A LOT and can't afford for 30% of my tests to be botched over something that is easily remedied. I'm mainly interested in how it seems to be reading it, but not executing.
[EDIT] I tried replacing the player object with a static "test" string and it still doesn't show up. Also, I had prints inside the function that work (how I caught the odd behavior in the first place).

9 comments
On line 6 try printing out player.Name or something else instead of the player object, otherwise you might just be getting lucky with load times.
It still didn't print. Once I saw this solution, I used it multiple times and the scripts do not crash now. The Roblox staff member said "it's a good idea to loop through the function before...", but it doesn't actually loop. It has NEVER caused playerAdded to run twice.
There are certain times when the player loads in before the script does. You really can't do anything about that.
@BashCaster So, what you're saying is that the for loop IS running and the call on the bottom isn't because the player loaded in too fast? That explains why it only runs once, but it doesn't explain why it doesn't show the print.
By the time players:GetPlayers() is called it probably returned an empty table so for loop didn't execute
@programmerHere I just did a test and used a completely empty table instead of players:GetPlayers() and it did the same thing. So, you're right it looped through nothing so it did nothing. (thought for sure it would throw an error for trying to loop through a blank table).
The only problems I have with this is that it fixed my PlayerAdded listener problem. That and I've used it in several scripts (so different timings).
Here's a video on how to do it properly: https://www.youtube.com/watch?v=bX8MxozRTGo
@rodrigo455 adding a wait at the top actually does make "test" print. I think I got the full picture of this now of why this only runs once.