Method idea: BasePart:IsConnectedTo(part, recursive)

My suggested method will apply to the BasePart class.

boolean IsConnectedTo( BasePart part, boolean recursive )

Effectively it’s an internal bit of code to run through the connected parts of a BasePart and tell me whether or not a part is connected to my specified one.

[details=This block of code is a way to do this currently.]```
function IsConnectedTo(Part, Goal)
local Parts = Part:GetConnectedParts(true)
for Index, ConnectedPart in pairs(Parts) do
if ConnectedPart == Goal then
return true
end
end
return false
end


###Why?

It would be a lot faster / less intensive **(NEEDS CONFIRMATION)** than my given code-block.

It could be used for a few things, mainly things that rely on physics or rigs that rely on `:MakeJoints()` to confirm if it's connected.

###Why not?
The things this could be used for aren't very broad, but they are most certainly there.

Appeal to creators is fairly minor at the moment (Given most games)

If it's not faster / less intensive then this would be a useless method.
8 Likes

This should go in Client Features – API changes pertain to the entire engine, not just Studio.

Fixed

Also it would help readability tons (from point of view of engineers) to make the title the topic of the thread, rather than a by-the-way comment, i.e. “BasePart::IsConnectedTo(part, recursive)”. Then any engineer knows in one glance what the thread is about.

Bump and hopefully not too much of a necrobump.
(It’s better than making the thread again)

This thread didn’t see too much light. Is it because others don’t quite see as much of a need for it?

Have you made something where your current implementation is too slow? Yes, C++ is faster, but half of instant is still instant. I can’t think of why your current implementation would take a non-negligible amount of time to complete unless:

You’re running it on a body with lots and lots of connected parts
Which on its own isn’t very performant, so I don’t imagine this is a likely case.

You’re checking for a connection very frequently (e.g. every frame)
Which is bad practice to begin with. A more appropriate solution for this would an API to hook up an event to a part to check for connections/disconnections of joints.

If this is something you’re currently running into, you may also consider keeping track of what you weld in your other scripts so you don’t need to check connected parts to rediscover that info you already know elsewhere.

The main thing that sparked this idea was trying to remake was a Fusion Tower from Robocraft.

The tower has a post in the middle. There are four rows of connections spaced by 90 degree intervals on that post. Connected to those rows are 5 truncated octahedrons, and there’s several layers of them around the post.

Note: A truncated octahedron can be connected on 14 sides:
Front, Back, Left, Right, Top, Bottom
[Bottom…] Front, Back, Left, Right
[Top…] Front, Back, Left, Right

Here's a pic of 5 crystals going up only two rows rather than four.

Now in the event that I have the full setup of pieces, which will look a bit like the photo I’ll link in just a bit, I have to go through all of those crystals (which counts to 148 parts) and go through their recursive connected parts (Which means 149, because the post is included) just to see if it’s connected to the post in any way.

Here's that pic.

Using the script here:

for i = 1, 148 do 
	for j = 1, 149 do 
		c = c + 1 
	end 
end 
print(c)

I was given the result 22052. That’s potentially (There’s no guarantee that the post is necessarily index #149 in the recursive connected parts) 22K items to iterate through initially. Of course, as more are disconnected from the post that number will go down quite a lot, but that’s still a very large amount near the start.
Edit for clarification: I have to iterate through all of the crystals because there’s a chance that the player destroyed one that wasn’t necessarily at the end of a connection which means more than one would be disconnected from only one being destroyed.
Edit 2: I am aware of how terrible this method is, and I do see other ways of drastically improving performance, but it’d still get laggy.

I do see another way of completing this specific scenario without even using :GetConnectedParts(), which is to use BasePart:IsGrounded() and just have all of the blue crystals unanchored, but this fix won’t work for all situations.

Yeah, this is definitely an issue with how you’re processing the data than it is a problem with the speed of GetConnectedParts. Using C++ doesn’t automagically make bad algorithms good.

Conceptualizing the problem, it seems almost like a maze, with the faces attached to the pole being exits, the faces attached to bulbs being paths, and the faces attached to nothing being walls. You could try looking into algorithms for solving mazes. However, there may be an algorithm that’s been designed specifically for this sort of thing, because there are plenty of block-based building games that would need to know this kind of information. You may also get a good answer from Development Discussion from someone who’s tackled a problem like this before.

My thought is if you’re doing this multiple times you would see a lot of performance by putting the values into a set, and then checking set inclusion. In Lua this could look like

local function IsConnectedFactory(ConnectedParts)
    local IsConnected = {}
    for _, Item in pairs(ConnectedParts) do
        IsConnected[Item] = true
    end
    return function(Part)
        return IsConnected[Part]
    end
end

local IsConnected = IsConnectedFactory(Parent:GetConnectedParts(true))  -- Do not store this table forever, or you will leak Roblox parts
print(IsConnected(workspace.PartA))

1 Like