CharacterAdded does not fire upon first spawn

I have a code with the CharacterAdded event, but it does not fire the first time the character loads in. However, If I reset, then it fires. How can I fix this?

What I want to achieve in this code is to add a folder into the character

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		local Folder = Instance.new("Folder", char)
		Stun.OnServerEvent:Connect(function(player, key, timer)
			local part = Instance.new("Part",Folder)
			wait(timer)
			part:Destroy()
		end)
	end)
end)
1 Like

hmm that’s odd. Try adding a print statement in the function handling character added and see if it prints anything. Because your code looks good, I am not sure why it would otherwise not work

I did it, and it only prints when i reset my character after loading in

You may be running code before this that is delaying it, or the Player could be joining before the PlayerAdded event fires.

There is nothing which should delay it before that code. Even if there is, it would have to load at some point, but it never does.

(Output says:

Infinite yield possible on 'Workspace.toyJig:WaitForChild("Folder")' 

You can check if the character exists right when the player joins and if that’s true then do what you did in the characteradded event.

And you can just put OnServerEvent outside of PlayerAdded event.

This could be because the playerAdded function isn’t firing for the current players that are already in the game. You could separate those functions out and initialize the players at the end by doing this:

Stun.OnServerEvent:Connect(function(player, key, timer)
    local Folder = player.Character.Folder
    local part = Instance.new("Part",Folder)
    wait(timer)
    part:Destroy()
end)

local function characterAdded(character)
    local Folder = Instance.new("Folder", char)
end

local function playerAdded(player)
    characterAdded(player.Character or player.CharacterAdded:Wait())
    player.CharacterAdded:Connect(characterAdded)
end

for _, player in ipairs(Players:GetPlayers()) do
    coroutine.wrap(playerAdded)(player)
end
Players.PlayerAdded:Connect(playerAdded)
1 Like

No, otherwise i cant change the folder instance which is in a local variable there

2 Likes

But that just inserts a new part into the folder that is inside the character.

You can check if the player has that folder in his character.

is the script that produced this warning the same one that houses the Player/CharacterAdded handler?

oh ye lol i frogot
ree least characters

No, it is from a local script, but it shouldn’t affect much

Oh wow! it worked. I dont really get what you said though. care to explain?

1 Like

Sure, I’d love to explain :slight_smile:

Basically, if you have any code above the “PlayerAdded” signal, it yields the signal from listening at the start of the game. So basically, all the code above it has to run first, AND THEN the signal will start detecting when players enter the game, which isn’t what you want.

By separating this code out into its own functions, you can apply the PlayerAdded functions to the current players AND the added players.

for _, player in ipairs(Players:GetPlayers()) do
    coroutine.wrap(playerAdded)(player)
end
Players.PlayerAdded:Connect(playerAdded)

This basically applies the function to all the current players, then to the added players!

local function playerAdded(player)
    characterAdded(player.Character or player.CharacterAdded:Wait())
    player.CharacterAdded:Connect(characterAdded)
end

I called characterAdded() on the current character of the player (if it exists), or I wait until the character is loaded or spawned (if it doesn’t exist). Then I set a connection to call that function whenever the character respawns!

Let me know if that makes sense to you :slight_smile: or if you need any additional assistance.

2 Likes

Oh, the wording now makes sense, but I still don’t get some of the code lol. I dosn’t really matter too much though, thanks!

my inner self screaming to ask what they do:
(what does _ in a for loop do?
also how does that coroutine.wrap work? I thought it could only contain a function or something)

1 Like

“for” loops can be used to loop through a table. In this case, by doing Players:GetPlayers(), this returns a table, which consists of indexes and values. Try and imagine it like this:

Players:
1 | Awesom3_Eric
2 | toyJig
3 | zyxw

The left side is the index and the right side shows the values, kinda like a playerlist.

local tableOfPlayers = Players:GetPlayers() -- Table
for index, player in ipairs(tableOfPlayers) do
    print(index, player)
end

--[[

This eventually prints:
1 Awesom3_Eric
2 toyJig
3 zyxw

]]--

By using this for loop, I’m able to loop through all the current players in game.Players and apply the playerAdded function to those players!

coroutines are used to run things on a separate thread to prevent yields, like running a function at the same time. That way, the playerAdded function can be run on each player at the same time. My use of coroutine.wrap here uses the function, and then the parameters.

coroutine.wrap(playerAdded)(player)
-- playerAdded is the function
-- player is the parameter

Hope this clears some portions up :slight_smile:

Oh so its just the same as for i,v in ipairs, but the i is replaced with a underscore???

wait, but wouldn’t that be

coroutine.wrap(playerAdded(player))

?