Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 4 years ago
Edited 4 years ago

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

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. CeramicTile 847 — 4y
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. SteelMettle1 394 — 4y
1
There are certain times when the player loads in before the script does. You really can't do anything about that. DeceptiveCaster 3761 — 4y
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. SteelMettle1 394 — 4y
View all comments (5 more)
1
By the time players:GetPlayers() is called it probably returned an empty table so for loop didn't execute programmerHere 371 — 4y
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). SteelMettle1 394 — 4y
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). SteelMettle1 394 — 4y
1
Here's a video on how to do it properly: https://www.youtube.com/watch?v=bX8MxozRTGo Wiscript 622 — 4y
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. SteelMettle1 394 — 4y

1 answer

Log in to vote
0
Answered by 4 years ago

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.

Ad

Answer this question