Does having 600+ script connections in my game make it lag?

I am trying to implement a system where, once an int value changes, I need 600+ lights in my game to change their color at once. I’m not sure of an efficient way to do this. I’ve tried working with the below script, but I think it is creating an immense amount of lag in general in the game. Is there a better way to do this?

for _,brick in pairs(workspace.AmbienceLights:GetChildren()) do
		wait()
		game:GetService("ReplicatedStorage").GameValues.IntensityLevel.Changed:Connect(function()
			if game:GetService("ReplicatedStorage").GameValues.IntensityLevel.Value == 1 then
				brick.BrickColor = brick.OriginalColor.Value
				if brick:FindFirstChild("PointLight") then
					brick.PointLight.Color = BrickColor.White().Color
				end
			else
				brick.BrickColor = BrickColor.Red()
				if brick:FindFirstChild("PointLight") then
					brick.PointLight.Color = BrickColor.Red().Color
				end
			end
		end)
	end
1 Like

You’re making 600 different connections, yes, that’s going to be expensive. Just connect to the IntensityLevel’s Changed event once, and then loop through and change all the bricks properties. (Don’t use wait() in that loop or it’ll have a noticeable delay.)

4 Likes

The problem with doing that without a wait() is that it causes a script timeout.

1 Like

Try checking if the remainder of the index (which you’re discarding right now) divided by some number (say, 50) is 0, so that it only waits every 50 iterations or so. There will still be a noticeable delay, but it shouldn’t be as bad.

6 Likes

That did the trick. I was unaware that worked, I thought a wait() had to be called every time, otherwise it timed out. Thanks!

1 Like

Switch the loop and the event listener around.
That way you will only have one event listener and it just iterates through all the parts.

local intensityLevel = game:GetService("ReplicatedStorage").GameValues.IntensityLevel
intensityLevel.Changed:Connect(function()
	for _, brick in ipairs(workspace.AmbientLights:GetChildren()) do
		if (intensityLevel.Value == 1) then
			brick.BrickColor = brick.OriginalColor.Value
			if (brick:FindFirstChild("PointLight")) then
				brick.PointLight.Color = BrickColor.White().Color
			end
		else
			brick.BrickColor = BrickColor.Red()
			if (brick:FindFirstChild("PointLight")) then
				brick.PointLight.Color = BrickColor.Red().Color
			end
		end
	end
end)
2 Likes

(this might be overly micro-optimising, apologies)

Adding on to your suggestion, if the number of ambient lights does not change, consider putting all the lights into a table. You’ll only have to run GetChildren() and FindFirstChild() once when the game starts, and reference the table whenever needed. I would also localise some values to reduce the amount of work done in the for loop.

local intensityLevel = game:GetService("ReplicatedStorage").GameValues.IntensityLevel

local AmbientLights = {}

local Red = BrickColor.Red()
local White = BrickColor.White()
local RedColor3 = Red.Color
local WhiteColor3 = White.Color

for _, brick in pairs(workspace.AmbientLights:GetChildren()) do
    local brickData = {}
    brickData["Part"] = brick
    brickData["OriginalColor"] = brick.OriginalColor.Value
    local PointLight = brick:FindFirstChild("PointLight")
    if PointLight then
        brickData["PointLight"] = PointLight
    end
    table.insert(AmbientLights, brickData)
end

intensityLevel.Changed:Connect(function()
    for _, brickData in ipairs(AmbientLights) do
        local brick = brickData["Part"]
        local OriginalColor = brickData["OriginalColor"]
        local PointLight = brickData["PointLight"]
        if (intensityLevel.Value == 1) then
            brick.BrickColor = OriginalColor
            if PointLight then
                PointLight.Color = WhiteColor3
            end
        else
            brick.BrickColor = Red
            if PointLight then
                PointLight.Color = RedColor3
            end
        end
    end
end)

4 Likes