How do I control multiple Bricks and their decals at once without lagging my game?


  1. I’m trying to achieve a script that controls everything at once when it comes to bricks changing, decals changing and so on.

  2. The main issue is; I get kicked due to unexpected client behavior or the entire place lags heavily for a brief few seconds which I believe could also lead to my first main issue. I assume this is from so much changing at once and being changed on the Server which is causing a conflict to the Client.
    image

  3. I tried moving everything to the client; however to no prevail. It still causes lag in studios and if it causes lag in studios like it did when it was a typical Script, then I’m afraid it’ll do the same thing here.

  4. If you have any criticism with this code, please share it so I may learn from it.


Further Explanation

Alright, what I mean by it freezes is that when played in Studios; the entire screen freezes and when played in the Roblox Client, the person has a massive lag spike. This happens every time I try to change any bricks Color or a Decals image; which I believe is the cause for Error 268.


The Script

--[[Made By MillerrIAm]]--
--[Main Script]--
--[[The Value `Tween` is a bool value inside of the server script.]]
local LEDs2Change = {"LEDColor","Top Rope","Middle Rope","Bottom Rope"}
for _,LED2Change in pairs (LEDs2Change) do
	if game.Workspace:FindFirstChild(LED2Change) then
		game.Workspace[LED2Change].Changed:Connect(function()
			local BindableEvent = game.ReplicatedStorage.ControlEvents.ControlBindableEvent
			if script.Tween.Value == true then
				BindableEvent:Fire("LED Control","Tween",game.Workspace[LED2Change].Name,game.Workspace[LED2Change].Color)
			else
				BindableEvent:Fire("LED Control","Instant",game.Workspace[LED2Change].Name,game.Workspace[LED2Change].Color)
			end
			wait(.05)
		end)
	end
	wait(.05)
end

local Screens = {"TV","Screen1","Screen2","TVTop","Side1","Side2","Side3","Side4"}
for _,Screens2Find in pairs (Screens) do
	if game.Workspace:FindFirstChild(Screens2Find) and game.Workspace[Screens2Find].ClassName ~= "Decal" and  game.Workspace[Screens2Find].ClassName ~= "ImageLabel" then
		for i,Image in pairs (game.Workspace[Screens2Find]:GetDescendants()) do
			if Image:IsA("Decal") then
				spawn(function()
					Image.Changed:Connect(function()
						for index,Screen in pairs (game.Workspace:GetDescendants()) do
							coroutine.wrap(function()
								local ScreenName = string.lower(Screen.Name)
								local ScreenMatch = string.lower(Screens2Find.."Copy")
								if ScreenName == ScreenMatch then
									for ind,ScreenImage in pairs (Screen:GetDescendants()) do
										if ScreenImage:IsA("Decal") then
											ScreenImage.Texture = Image.Texture
										elseif ScreenImage:IsA("ImageLabel") then
											ScreenImage.Image = Image.Texture
										end
									end
								end
							end)()
							--wait(.05)
						end
					end)
				end)	
			end
		end
	end
end

Thank you for any help you can give me.

Doing GetDescendants is intensive versus GetChildren.
It’s probably this line causing the lag:
for index,Screen in pairs (game.Workspace:GetDescendants()) do
I tend to organise similar items into a folder if they need to be referenced by a script. It also makes your environment easier to manage.
The script also seems to perform duplicate effort in finding entries. With each Screens2Find you are looping through the workspace multiple times which seems hugely inefficient. Think of the shortest loop you can use to identify all items and update them.
So, I’d recommend:

  1. Put these items that need to be changed into a single folder
  2. Change the logic of your script to optimise how it finds each item using the minimum of GetChildren & GetDescendants

That’s impossible for my situation, allow me to explain why…
I have to spawn things in from workspace that have it’s own designated folder and it’s multiple things in multiple different folders as well. Also no, I can not change the folder it goes to; due to how certain things are programmed and set up, I have to keep things simple for others to use. They’re also quite illiterates in studios, so it would also be hard for them to do this as well.

Can you show us an example of an example in the workspace, cos that line above doesn’t make much sense to me. It might also give a clearer picture of how to optimise the whole loop.

Oh, that’s just to make sure it’s a not a decal or image label. It’s for a part that has a decal inside of it that controls what each screen changes to. image

Do you have control over the process when these parts are created? If you do then it would be easier to tag them using CollectionService so you don’t need to loop through the entire workspace getting all descendants.
Then when you want to update, you can just get the tagged [arts and change them. I think that is probably the best way to achieve it.

That’s a solution my friend suggested as well, if you have any suggestions on improvement; please let me know. The Neon Bricks change color slowly and the images on the other screens change slowly as well… by slowly, I mean; ten seconds goes by and then it goes to the next brick/image.

--[[Made By MillerrIAm]]--
--[Main Script]--
local CollectionService = game:GetService("CollectionService")

local LEDs2Change = {"LEDColor","Top Rope","Middle Rope","Bottom Rope"}
for _,LED2Change in pairs (LEDs2Change) do
	local led = workspace:FindFirstChild(LED2Change)
	if led then
		led:GetPropertyChangedSignal("Color"):Connect(function()
			local BindableEvent = game.ReplicatedStorage.ControlEvents.ControlBindableEvent
			local class = script.Tween.Value and "Tween" or "Instant"
			BindableEvent:Fire("LED Control",class,game.Workspace[LED2Change].Name,game.Workspace[LED2Change].Color)
		end)
	end
end

local Screens = {"TV","Screen1","Screen2","TVTop","Side1","Side2","Side3","Side4"}
for _,Screens2Find in pairs (Screens) do
	local screen = workspace:FindFirstChild(Screens2Find)
	if screen and not screen:IsA("Decal") and not screen:IsA("ImageLabel") then
		for i,Image in pairs(screen:GetDescendants()) do
			if Image:IsA("Decal") then
				spawn(function()
					Image.Changed:Connect(function()
						for index,Screen in pairs(workspace:GetDescendants()) do
							if string.lower(Screen.Name) == string.lower(Screens2Find.."Copy") then
								for _,ScreenImage in pairs(Screen:GetDescendants()) do
									if ScreenImage:IsA("Decal") or ScreenImage:IsA("ImageLabel") then
										local property = ScreenImage:IsA("Decal") and "Texture" or "Image"
										ScreenImage[property] = Image.Texture
									end
								end
							end
						end
					end)
				end)    
			end
		end
	end
end