Backpack being created twice

I’m creating a system and I need to access the player’s backpack when the player joins the game, the thing is that I noticed that the ChildAdded event wasn’t working when I added a Tool in the player’s backpack. I started to think the reason and I finally figured it out! When a player joins the game, the backpack is being created twice and the WaitForChild("Backpack") gives me the first one that is destroyed right after its creation.

Code
image

Output
image

As the backpack used is the second one, the solution I found was doing it:

local Players= game:GetService("Players")
local RunService = game:GetService("RunService")

local Player = Players.LocalPlayer
local Backpack do
	local conn
	
	conn = Player.ChildAdded:Connect(function(Child)
		if Child.Name ~= "Backpack" then return end
		
		if Backpack then
			conn:Disconnect()
		end
		
		Backpack = Child
	end)
	
	repeat RunService.Heartbeat:Wait() until Backpack and not conn.Connected
end

Why this happens? Is there any alternative to access the backpack?

I choosed this category because I would like to understand the reason for this, I don’t know if its an engine bug or it has been always like that… Tell me if I’m Off-topic please.

3 Likes

Change it to scripting support quickly. And please copy and paste so I can edit it.

4 Likes

This is not in the category it’s supposed to be, move it in scripting support.

3 Likes

You are doing Player.ChildAdded, Tool is a child of Backpack not Player.

4 Likes

Player.ChildAdded to detect when the Backpack is created, I’m not talking about the tools itself but the Backpack being created twice.

2 Likes

You said when you added a tool to the backpack nothing happened, which suggests you expected ChildAdded to fire when you added a tool to the backpack.

My bad if that’s not what you meant.

However, I cannot recreate this bug, it seems to be only creating one for my end.

2 Likes

It looks like you are trying to access the player’s backpack when they join the game. However, you are experiencing an issue where the ChildAdded event is not working as expected.

Based on your code, it seems like you are using the ChildAdded event to listen for when the backpack is added to the player. However, since the backpack is being created twice when the player joins, the event is not triggered as expected.

To solve this issue, you can use the CharacterAdded event instead. This event is triggered when the player’s character is added to the game, and at that point, you can access the backpack using player.Backpack.

Here’s an updated version of your code using the CharacterAdded event:


local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Player = Players.LocalPlayer
local Backpack

local function onCharacterAdded(character)
    Backpack = character:WaitForChild("Backpack")
    -- Perform any actions you need with the backpack here
end

Player.CharacterAdded:Connect(onCharacterAdded)

-- Wait for the backpack to be available
repeat
    RunService.Heartbeat:Wait()
until Backpack

In this code, the onCharacterAdded function is called when the player’s character is added to the game. It waits for the backpack to be available using WaitForChild and then performs any actions you need with the backpack.

After connecting the CharacterAdded event, you can use a repeat…until loop to wait until the backpack is available before continuing with your code.

I hope this helps! I don’t understand it right I guess, can you warn me if I got it wrong?

2 Likes

That’s a good solution since the character is added after backpack is created and it would work, but I yet want to understand the reason for the backpack being created twice

2 Likes

Bruh, I confused more!
Maybe it is a bug or smth?

I tried my best to understand•~•

The backpack is being created twice because there is a potential race condition in the script.

In the script, the Player.ChildAdded event is being used to listen for when a child is added to the player. If the added child has a name other than “Backpack”, it is immediately returned and not processed further.

The issue arises when the “Backpack” child is added. The script checks if the Backpack variable is already assigned a value. If it is, that means the backpack has already been created and assigned, so the connection to the Player.ChildAdded event is disconnected.

However, immediately after the check, the script assigns Backpack to the newly added “Backpack” child. This is where the potential race condition occurs. If another child is added in quick succession and it is not the “Backpack” child, the script will assign that child to Backpack. If this happens before the connection to Player.ChildAdded is disconnected, the script will end up assigning the “Backpack” child again, resulting in it being created twice.

To resolve this issue, you can modify the script to wait until the connection is disconnected before assigning the child to Backpack. Here’s an updated version of the script:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Player = Players.LocalPlayer
local Backpack

local conn
conn = Player.ChildAdded:Connect(function(Child)
    if Child.Name ~= "Backpack" then return end

    if Backpack then
        conn:Disconnect()
    end

    Backpack = Child
end)

repeat
    RunService.Heartbeat:Wait()
until Backpack and not conn.Connected

This version ensures that the connection is disconnected before assigning the “Backpack” child to Backpack, preventing it from being created twice.

I hope I got it right this time​:tea::woman_technologist:
Edit: I’m hungry I’ll look for your issue again when I come back🤗

1 Like

Backpack is being created twice, the first one is created, then it’s destroyed then another one is created.

Using Player:WaitForChild("Backpack") it gonna returns me with the first Backpack being created, this backpack returned by WaitForChild is destroyed and another one is created.

if do it:

local Backpack = Player:WaitForChild("Backpack")

Backpack.ChildAdded:Connect(function(Child)
    print(Child.Name)
end)

and after a while I put a Tool inside Player’s backpack, nothing will be detected by the event since this connection is listening but the Instance backpack is the wrong one

1 Like

Considering the backpack is being created twice, the code I made yields the code untill I get the second Backpack created. It isn’t the reason for the backpack being created twice, it’s the solution I got to get the second Backpack created. Backpack being created twice is an engine thing.

1 Like

If the first one is created already, then the child got by the event is automaticaly the second one, so I stop to listen to the event disconnecting it and I assign the second backpack instance created to the variable

1 Like

If you take a time, create a baseplate on studio, add a script on StarterPlayerScripts and put this code:

local Players = game:GetService("Players")
local Player = Players.LocalPlayer

Player.ChildAdded:Connect(function(PlayerChild)
    print(PlayerChild.Name.." created")

    PlayerChild.Destroying:Once(function()
        print(PlayerChild.Name.." destroyed")
    end)
end)

You gonna observe that it’s an engine issue. I tested it many times on different places.

1 Like

Each time your character respawn, the current backpack is removed and a new one is created, this isn’t a bug.

The first created backpack is when the player is entering the game (Player object added in Players Service), and the second one is when the player character is spawning… so the first one got deleted for the new one.

More infos about backpack here: Backpack | Documentation - Roblox Creator Hub


The first solution is to put the local script inside the StarterCharacterScript, then the current backpack will always be the last and right one, also the script will reset as well as the backpack each time the character respawn, so you don’t need to update the variable, you can access it normaly like this:

local PlayerService = game:GetService("Players")
local Player = PlayerService.LocalPlayer
local Backpack = Player:WaitForChild("Backpack", 30)

The second solution when your local script is in somewhere else than StarterCharacterScripts, is to always keep your backpack variable updated, by simply do this:

local PlayerService = game:GetService("Players")
local Player = PlayerService.LocalPlayer

local Backpack = nil

Player.ChildAdded:Connect(function(Child)
	if Child:IsA("Backpack")then
		Backpack = Child
	end
end)
3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.