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

Child Added won't fire unless I put in a wait? even though I used WaitForChild

So i noticed that the child added function wasn't working for my backpack inside players


game.Players.PlayerAdded:Connect(function(plr)
	
	local Backpack = plr:WaitForChild("Backpack");
	
	Backpack.ChildAdded:Connect(function()
		
		print('Some Thing was added')
		
	end)
	
	
end)

Would return nothing in the output

but when I did this

game.Players.PlayerAdded:Connect(function(plr)
	wait(4)

	local Backpack = plr:WaitForChild("Backpack");
	
	Backpack.ChildAdded:Connect(function()
		
		print('Some Thing was added')
		
	end)
	
	
end)

it started printing things

Can someone explain to me why and how I can get around this?

2 comments

0

I've always had problems with nested events, are you sure you can't just have a local script detect if something was put in the player's backpack when the player is already loaded into the server?

0

I can't because I need to save this in a datastore so I can reload it into the players backpack when they join later its like a inventory saving script

2 answers

✓ Accepted answer

Very weird behavior but I managed to find a way to bypass it.

game.Players.PlayerAdded:Connect(function(Player)
	Player.ChildAdded:Connect(function(I)
		if I.Name == "Backpack" then
			I.ChildAdded:Connect(function()
				print("Hey")
			end)
		end
	end)
end)

karlo_tr10's code will work, but I think you should know why it works, so that you're not left with this mystery workaround you don't understand. Whenever adding a wait() mysteriously fixes something, you should dig into why, to make sure you haven't just added a race condition or subtle new bug.

What's actually going on here is that on the server, the Player object is initialized already having a Backpack as a child, before PlayerAdded is even fired. Your WaitForChild("Backpack") is getting a valid reference to a Backpack--one that is destroyed and replaced on the next server tick with a new Backpack, which is the one you actually want a reference to (and the one karlo's code gets a reference to).

This is tricky because WaitForChild() doesn't actually wait for a new child to be added, if there is a matching-named child already present, which in this case there is. So in your original code, you have a ChildAdded listener getting attached to something that exists only fleetingly, and isn't the Backpack that ever has anything put into it.

Full proof of this:

local Players = game:GetService("Players")

local function OnPlayerAdded(player)
	local backpack = player:WaitForChild("Backpack")
	print("backpack:",backpack)
 
    backpack.ChildAdded:Connect(function()
		print('Some Thing was added to the first backpack')
	end)
	
	player.ChildAdded:Connect(function(child)
		print("Player",player.Name," now has a child",child.Name,"of type",typeof(child))
		if child:IsA("Backpack") then
			
			print("Backpack added to",player.Name," is the same backpack we got from WaitForChild:",child == backpack)
			
			child.ChildAdded:Connect(function()
				print('Some Thing was added to the real backpack')
			end)
		end
	end)
end

Players.PlayerAdded:Connect(OnPlayerAdded)
for _,player in pairs(Players:GetPlayers()) do
	OnPlayerAdded(player)
end

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