Please help me optimize this script

I made a script that (when running) reaches an activity percentage of about 20% (per player)

I dont know how to optimize this and I dont want to risk lag issues, please help!

I tried already tried replacing the while loop with:
a) a connection to Touched
b) :GetPropertyChangedSignal(“CFrame”)
these were sub-optimal at best

local ws = game:GetService("Workspace")
local rs = game:GetService("ReplicatedStorage")

local BrickCollection = require(game:GetService("ServerScriptService"):WaitForChild("BrickCollection"))

ws.DescendantAdded:Connect(function(descendant: Instance)
	
	if not descendant:IsA("BasePart") then return end
	
	if descendant.Name == "ExtendedHitbox" then
		
		-- Actual Collection process --
	
		while descendant do task.wait() task.wait()

			for _, brick in pairs(ws:FindFirstChild("Bricks"):GetChildren()) do

				
				local Table = ws:GetPartBoundsInBox(brick.Value, Vector3.new(1,1,1))

				
				for _, part in pairs(Table) do

					
					if part == descendant then

						local player = brick:FindFirstChild("Player").Value
							
						if player == descendant:FindFirstAncestorOfClass("Model"):FindFirstChild("Player").Value then

							BrickCollection.collect(descendant, player, brick)
							
						
						end
						
					end
					
				end
				
			end
			
		end
		
		
		

	end
	
end)
7 Likes

since idk what ur tryna do, any reason why ur using a while loop and not:

player = brick:FindFirstChild("Player")
player.Changed:Connect(function() 
   --some that u wanna do 
end)

6 Likes

Well, let me clarify what Im trying to do:

I have about 240 CFrame values in a Folder in the workspace:
I need to check if a “collecting” Hitbox is overlapping with these to the destroy them

I need the Values to be destroyed as soon as the hitboxes overlap, for that i used a while loop, but, of course a fitting connection would be more efficient. Thats where I need help

4 Likes

You could try using run service to check each frame

3 Likes

No, that makes it counter-productive. I want to lessen the lag caused by the constant while-loops

2 Likes

240 :skull: ? Ok thats really bad in my opinion. Why not use a module script that will have the data of the CFrame and it can be accessed from any other script? (you need to use OOP)

3 Likes

what? No, I think you might have misunderstood. (or i explained it badly) WELL, the goal of the game is to collect bricks. these get spawned in by another script and end up as cframevalues in the bricksfolder mentioned above or in the script. This script then has to check if they are touched/collected. The actual brick model is only on the clientside

In the game how would you collect these bricks?

2 Likes

Like I somewhat explained above, you move around on a plate where all of these bricks are (and the CFrameValues’ Value is also there)
There is a hitbox as well parented to a players character and their collector npcs character as well

1 Like

Hmmm alr I kind of see the thing. I would do something like this:

for i,v in pairs(folder for the brick or idk anything) do 
   v.Touched:Connect(function)
end

and for the npc can you tell is the npc going around randomly to find them or directly going to the positions to collect the parts?

Well, the Bricks are CFrame values and therefore cannot be touched

I believe that ridding the script of atleast one for-loop should lessen the activity rate by a whole lot. Can you help me achieve that?

then why there are hitboxes I dont understand the point. I either understand it wrong or there is a point ur missing.

1 Like

Yes sure 1 minute and I will try to see if the script I will make will fit ur problem

1 Like

Thank you so much :slight_smile: (maxcharsmaxchars)

1 Like

This is also badly optimised.
At best:

for _, v in ipairs(t) do

end
2 Likes
local ws = game:GetService("Workspace")
local rs = game:GetService("ReplicatedStorage")

local BrickCollection = require(game:GetService("ServerScriptService"):WaitForChild("BrickCollection"))

local bricksFolder = ws:WaitForChild("Bricks") -- this ur bricks folder

ws.DescendantAdded:Connect(function(descendant: Instance)
	if not descendant:IsA("BasePart") or descendant.Name ~= "ExtendedHitbox" then return end
	
	local ancestorModel = descendant:FindFirstAncestorOfClass("Model")
	if not ancestorModel then return end
	
	local descendantPlayer = ancestorModel:FindFirstChild("Player")
	if not descendantPlayer or not descendantPlayer.Value then return end
	
	for _, brick in pairs(bricksFolder:GetChildren()) do
		local brickPlayer = brick:FindFirstChild("Player")
		local brickValue = brick:FindFirstChild("Value")
		
		if brickPlayer and brickPlayer.Value == descendantPlayer.Value and brickValue then
			local partsInBounds = ws:GetPartBoundsInBox(brickValue.Value, Vector3.new(1,1,1))
			for _, part in pairs(partsInBounds) do
				if part ~= descendant then return end
				BrickCollection.collect(descendant, descendantPlayer.Value, brick)
				break
			end
		end
	end
end)

maybe this idk Im in urry rn so it may be worng

2 Likes

what is the difference tho I always see that “_” but idk what it meant

1 Like

_ represents an unnecessary variable. By replacing i with _, it shows that i is unneeded and will then be discarded from memory and ultimately optimising the loop.

1 Like

This doesnt work as it only fires once when the script loads or a hitbox gets added

1 Like