Getting descendants is laggy

So I got a problem trying to fix the lag but I don’t know any other way to get the results I need.

local function CheckCollisions()
	for _, part in ipairs(Parts:GetDescendants()) do
		if part:IsA("BasePart") then
			for _, v in ipairs(workspace:GetDescendants()) do
				if v:IsA("BasePart") then
					local distance = (part.Position - v.Position).Magnitude
					local speed = (part.AssemblyLinearVelocity - v.AssemblyLinearVelocity).Magnitude

					if distance <= 5 and speed >= 10 then
						Break(part)
					end
				end
			end
		end
	end
end

RunService.Heartbeat:Connect(CheckCollisions)
2 Likes

what are you trying to do?

2 Likes

You are entering this function on every heartbeat, that means this heavy search algorithm will continuously start every ~4ms. You need to wait for it to complete one iteration before starting the next iteration. This can be achieved using a debounce to prevent re-entry until an iteration has completed, or you can use the deltaTime parameter that is supplied to RunService.Heartbeat:Connect() and compare with a variable that stores startTime and currentTime to run the check at whatever frequency you find produces the least lag.

6 Likes

In this case it might be better to use an Octree so instead of looping through every descendant of workspace you only loop through the ones in the nearby sectors of part. This would not be a trivial thing to add.

Alternatively, you could try splitting up the workload with different actors (Assuming this runs on the server with a decent number of cores), but I’m convinced the bottleneck of having to re-enter serial execution every time you want to call Break would make it just perform worse.

3 Likes

As @MagmaBurnsV says. A more robust and efficient method of performing this sort of heavy part iteration would be to use an Octree, @Quenty made an excellent and efficient module for this, which has been expanded in the link @MagmaBurnsV provided.

2 Likes

So a roblox Module Script? Because I can’t find it.

Instead of tackling the herculean effort it takes to even understand what an octree is, let alone use one, try refining which parts you are even needing to iterate over in the first place.

It’d probably help if you tried explaning to us what you are even trying to accomplish. Any highly repetitive task that continously calls GetDescendants() is going to end up causing extreme lag no matter what you do.

I’m trying to make a touched event better by checking the distance from the part to the part.

If I am understanding correctly, are you calling the code you provided above whenever a Touched event occurs?

Its just another way of detecting if a part has been touched.

Then just used the Touched event? No reason to recreate the wheel here.

If you’re having issues detecting which parts are touching, you could always just use GetPartsInPart() method of WorldRoot to determine which parts are intersecting (touching) the part you are monitoring.

I can but it won’t work great.

Looping works fine but it lags.


If I use touched event, the ball would bounce off the glass and it wouldn’t look great.

The ball would bounce off the glass.


I used the touched event.

for _, part in ipairs(Parts:GetDescendants()) do
	if part:IsA("BasePart") then
		part.Touched:Connect(function(hit)
			local isFiltered = isFilteredCheck(castParams.FilterDescendantsInstances, hit)
			
			if isFiltered == true then
				Break(part)
			end
		end)
	end
end

I also used GetTouchingParts:

for _, part in ipairs(Parts:GetDescendants()) do
	if part:IsA("BasePart") then
		RunService.Heartbeat:Connect(function()
			local touchingParts = part:GetTouchingParts()
			
			for i,v in pairs(touchingParts) do
				local isFiltered = isFilteredCheck(castParams.FilterDescendantsInstances, v)

				if isFiltered == true then
					Break(part)
				end
			end
		end)
	end
end

Are you trying to break every part of the glass at once when any member of the glass is hit by the ball?

Unanchor the glass that has been touched.

Why would do this when you are ultimately going to get the Descendants of the workspace?

What do you mean? Parts is a folder that is storing the parts for the model. I’m detecting if anything is hitting any part in the Parts folder, if so, break the part.

You should use collectionservice instead then.

What is that? Can you send a documentary?

Why would I need to add tags? What would change?