Weird ChildAdded Behaviour?

Hello :smiley:
I came across something weird. I guess it’s me, but it feels like a bug :sweat_smile:

This is a script that adds a clone of Billboard “BB” to every Model “Mini” that is added to a folder “Minis”.
It loops through all existing minis and connects to the folders .ChildAdded.
When the game starts, it loops through as intended, but when a mini is added it loops AGAIN.

Does anyone see the issue?

local MINIS = workspace:WaitForChild("Minis")
local BB = script.HealthBarBB
local activeBBs = {}

local function addBB(part)
	local bb = BB:Clone()
	bb.Parent = part
	return bb
end

local function connectHealthChange(mini)
	mini:WaitForChild("Health").Changed:Connect(function(val)
		activeBBs[mini].TextLabel.Text =  tostring(val)
	end)
end
for _, mini in pairs(MINIS:GetChildren()) do
	print("mini looped: ", mini.Name)
	local head = mini:WaitForChild("Head")
	if activeBBs[mini] == nil then
		activeBBs[mini] = addBB(head)
		connectHealthChange(mini)
	end
	
end

MINIS.ChildAdded:Connect(function(mini)
	print("mini added: ", mini.Name)
	local head = mini:WaitForChild("Head")
	if activeBBs[mini] == nil then
		activeBBs[mini] = addBB(head)
		connectHealthChange(mini)
	end
end)


MINIS.ChildRemoved:Connect(function(mini)
	activeBBs[mini] = nil
end)

I really hope I am not just blind right now and that you can help me :smiley:

I’m not sure if this is the problem, but pairs is for dictionaries. Try using ipairs instead.

1 Like

Oh, in this case I don’t need it to loop through the models in order, so I chose pairs.
But I tried it with ipairs and it’s still weird :smiley:

Is it printing mini looped or mini added?

I’m not sure, but the 1st function runs whenever the Health is changed.
The 2nd function runs whenever a mini is added.

On that behaviour, whenever a mini is added doesn’t the Health change causing the first function to be called as well?

1 Like

I am sorry, I forgot to provide the output.

Here is some more background:
For testing purposes there is one mini already in the folder before the game starts.
This produces:
>mini looped: Original Mini.

When a mini is then added to the folder following output is produced:
mini added: New Mini
mini looped: Original Mini
mini looped: New Mini

Update: I tried to remove the for loop, but it’s still adding multiple Billboards.
I am despairing :joy:

Is there only this script?
Is this script being cloned?

1 Like

Yes, it’s the only one.
I went through all scripts multiple times :smiley:

Is the script parented to the original Mini?

If so, it would cause the script to clone and activate again.
Parent it to ServerScriptService.

1 Like

No, I have the Billdboard-“Prefab” under StarterGui and with the script as a parent
image

(I forgot to mention that the billboards are handled on the client)

The script works correctly when I tested it out

How are you adding a mini to the folder Minis?

1 Like

Currently via a server script that adds a mini whenever a player touches a certain part.
For me it works fine on the first “new” mini, but not for the original mini. When adding multiple minis, it also doesn’t work for them.

I can’t replicate the behavior while testing.
It simply does not happen to me with your script.

1 Like

Thanks for trying so hard to help me :smiley:

I’ll create a new project containing only the involved scripts and see if I still have the issue. If so, I guess I should make a post under bug reports. Brb

I made a little video just to be clear of any misunderstanding:

Progress! :smiley:
I rewrote the script a little and put a print(“…”) in the first line. It runs multiple times.
I have it under StarterGui. Players can change their character to a “mini”. Apparently the script runs on game start AND when a player changes their character. I still have no solution for this, and the script isn’t working like this, but I thought this realization could help figure it out.

Here is the script:

print("HEALTHBAR SCRIPT RUNNING")
local Players = game:GetService("Players")
local BB = script.HealthBarBB

local function addBB(part)
	local bb = BB:Clone()
	bb.Parent = part
	return bb
end

local function connectHealthChange(mini)
	mini:WaitForChild("Health").Changed:Connect(function(val)
		mini.TextLabel.Text = string.rep(" ▀ ", val-1)
	end)
end

Players.PlayerAdded:Connect(function(plr)
	print("Player Added")
	plr.CharacterAdded:Connect(function(char)
		print("Char Added")
		if char:GetAttribute("Mini") == true then
			print("Char is MINI")
			local healthBoard = addBB(char:WaitForChild("Head"))
			char.Health.Changed:Connect(function(val)
				healthBoard.TextLabel.Text = string.rep(" ▀ ", val-1)
			end)
		end
	end)
end)