We’ve just enabled two new properties for parts to give you more power over root selection and the physical properties of your models.
BasePart.Massless
If Massless
is enabled the part will not contribute to the total mass or inertia of its rigid body as long as it is welded to another part that has mass.
If the part is its own root part according to BasePart:GetRootPart()
then Massless
will be ignored for that part, and it will still contribute mass and inertia to its rigid body like a normal part. Parts that are massless should never become an assembly root part unless all other parts in the assembly are also massless.
TL;DR it’s like avatar hats.
This might be useful for things like optional accessories on vehicles that you don’t want to affect the handling of the car or a massless render mesh welded to a simpler collision mesh.
BasePart.RootPriority
RootPriority
is an integer between -127 and 127 that takes precedence over all other rules for root part sort (including the weird rules based on part size). A part with a higher RootPriority will take priority over other unachored parts with equal Massless
values and a lower RootPriority.
Use this to control which part of an assembly is the root part and keep the root part stable if size changes.
What’s a Root Part?
Welds and other rigid joints like Motor6Ds combine multiple parts into a single “assembly.” If none of the parts in an assembly are anchored then each assembly forms a single rigid body. Every assembly has a single root part which you can check with BasePart:GetRootPart()
.
Welds and Motor6D joints have no defined direction. When you change C0/C1 or animate a Motor6D which part is Part0 and which is Part1 does not matter for answering which part moves. To answer that you first need to ask which part will be the root part.
The root part of an assembly is the one that does not move when rigid joint CFrames are updated.
With welds you should never need to care: if you use WeldConstraints or otherwise just move both parts where they should be before welding them you avoid the problem. However, if you’re using Motor6Ds for animation you need to know which part will move.
To handle this internally we start by first picking the root part based on the part sorting rules below, then we build a spanning tree from the graph of rigid joints that branches out from the root part. When a rigid joint CFrame is updated the part that is closest to root will stay put and the child part and its children will move. Basically, we internally build a conventional transform hierarchy for each assembly.
Here’s a visualization of this tree in a basic R15 humanoid rig on the left, and a representation of this implicit tree of which parts move relative to which parts on the right.
A typical Humanoid rig is a single assembly joined by Motor6Ds. HumanoidRootPart is typically the root part because Accessories are “massless” and the name “HumanoidRootPart” applies a special hacky 10x multiplier to the part’s Size
based sort size (from a time before RootPriority).
The root part is also used for physics replication. For physics replication to work correctly all clients will have to have the same root parts. Separately, when constraints are involved we also need a consistent mechanism structure for network ownership assignment to work.
Updated Assembly Root Part Sorting Rules
For choosing a root part parts are compared on, in order:
- Anchored (anchored parts will always be their own assembly root)
- Not massless
- RootPriority
- Legacy sort size based on the largest surface area of the object aligned bounding box defined by
Size
with an additional multiplier for Seats (20x) or parts named “Torso” (5x) or “HumanoidRootPart” (10x):floor(maxPlanarSize() * 50.0) * specialMultiplier
That last one is very old and many games rely on it without realizing it, so we can’t change it.
Now when you know which part should be root take control and avoid the weird old rules by setting the RootPriority
higher on the part that you want to be root!