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

[Solved]This PlayerAdded solution appears to run, but doesn't; Why?

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

1

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.

0

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.

1

There are certain times when the player loads in before the script does. You really can't do anything about that.

0

@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.

1

By the time players:GetPlayers() is called it probably returned an empty table so for loop didn't execute

0

@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).

0

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).

1

Here's a video on how to do it properly: https://www.youtube.com/watch?v=bX8MxozRTGo

0

@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.

1 answer

The reason this only runs once is a combination of what everyone said in the comments. (I wish I could divide the answer up since everyone in the comments were correct, so I'll just upvote them).

If you add a wait at the very top of the script, "test" will suddenly start printing, and the playerAdded function still only runs once. It's almost like an invisible if statement. If the script takes too long, then the player has already been loaded, then it will run the for loop (since the player is retrieved within get players) and ignore the .PlayerAdded:Connect(playerAdded) hook because the player was already added.

If you remove the wait and simulate a very fast loading script, then the for loop will return a blank table and skip it. The hook immediately follows, so it will set up the hook by the time the Player actually loads in. This will cause the PlayerAdded event to fire instead of the for loop.

Thanks to all in helping me figure this out. I'm wondering if I can use this elsewhere now.

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