Changing the Behavior of Welds to Anchored Parts

It appears this change broke a couple of morphing scripts


(taken by a friend)

Changed weld to constraint instead but didn’t do much of any improvement. Any help?

3 Likes

teleporting people via changing their humanoidrootpart cframe while they are sitting now moves the seat instead of breaking the weld and teleporting them

2 Likes

I am also experiencing some issues with my morphing system. Same issue as to what @LordMerc is facing.

1 Like

@LordMerc @Jamie_Jr Does this system involve anchoring parts at any point? If not it’s more likely related to:

2 Likes

It just unanchors the parts actually after connecting the welds. I’ve also tried all 3 Jointsmode and still same result. This also just started happening as soon as this change went live.

1 Like

Here is also another example picture.

1 Like

Am having similar issues as @rachjumper. In my game, players can place a seat down which gets welded to part of the map. It now seems that if the player finds a way to have their HumanoidRootPart’s cframe changed while sitting in a seat, the cframe of the seat and the cframe of the map underneath the seat will also be changed. This is causing a lot of problems in my game:

Why does changing the cframe of an unanchored part welded to an anchored part also move the anchored part? Is this intended? Is there a different type of weld that won’t move an anchored part if it’s welded unanchored part does move?

1 Like

I managed to fix his issue and my friends morph issue with a re-write of the welding.

2 Likes

Putting a repo here actually in hopes of maybe the error showing itself(excuse the ugly code, its been used since 2013)

Code forcing the issue

https://pastebin.com/BRL79Tem

Code that works

https://pastebin.com/jJW66xsu

Hopefully the code is easy to follow and may point out what’s breaking it.

1 Like

It works this way because of the way “Assemblies” work. This is poorly documented and I didn’t go into a lot of detail in the original post so I’ll try to explain it better.

Rigid Joints and Assemblies

Welds, Snaps, and ManualWelds, Motor6Ds, and WeldConstraints are basically all equivalent to the physics engine. They’re all “rigid joints.” The direction of a rigid joint (which part is Part0 or Part1) doesn’t matter at all, they’re bidirectional. All of these rigid joints combine multiple parts into a single Assembly (with one weird exception that we just changed). No physics forces can separate the parts in an Assembly; an assembly is a single physical object (rigid body).

Welds to Anchored parts…

So we have three different cases with respect to anchored parts:

  1. unanchored part welded to unanchored part
  2. anchored part welded to anchored part.
  3. anchored part welded to unanchored part

Case 1: Unanchored to Unanchored

Nothing changed here. The parts are a single assembly and CFraming one part in an Assembly always moves the whole Assembly (no exceptions!).

When the parts aren’t anchored there’s some sorting rules to determine which part in the Assembly is the root part that I’ve covered before.

Case 2: Anchored to Anchored

Nothing changed here either, but here both parts are two different assemblies.

Anchoring something guarantees it’s an assembly root.

In this case the weld between two anchored parts will even be inactive meaning it’s totally being ignored!

The black parts are both anchored. Notice that the weld is not Active, meaning it has no effect.
image

Case 3: Anchored to Unanchored

Now case 2 is where something changed.

Previously we had some weird logic that would make any unanchored part directly welded to an anchored part also it’s own “grounded” assembly root (effectively also anchored, physically unmovable, but this “also a root” thing wasn’t recursive).

This meant creating a weld between an anchored part and an unanchored part would “freeze” the unanchored part in place where it was before, without ever applying the weld C0/C1, and not in any way that was reflected consistently by replicated properties. This caused some replication consistency issues where parts would end up frozen in different positions on different clients. It also made the rules for Assembly behavior inconsistent and very hard to explain.

Here’s case 3 in with the old behavior, the way it was before. Red square indicates assembly root. Only the bottom black part is unanchored, note that the unachored part connected to the anchored part is it’s own assembly because of weird logic. Note that the weld between them is not Active. It “grounds” the part, effectively anchoring it, but the weld C0/C1 is ignored. Note how long this paragraph is. It’s not consistent and it’s hard to explain to a new developer who isn’t just used to things being this way even if they don’t understand why.

Now welds to anchored parts aren’t an exceptional. The rules are consistent.

If you want the old behavior you can just anchor both parts. This should get you the exact same behavior we had before.

Here I re-enabled the new logic and anchored the middle part. Note that the weld active and assembly breakdown is the same as the old case before

So from this we have three rules only two simple rules for assemblies:

ContextLost’s Rules of Assemblies

An assembly is a group of Parts connected by rigid joints. An assembly is a single rigid body. If no parts in the assembly are Anchored it can be moved by physical forces.

The First Rule of Assemblies

An assembly is a single physical unit that always moves together. All of the parts within an assembly are positioned relative to the root part, as defined by the Active rigid joints in the Assembly.

It’s not possible to move one part in an assembly without moving all of the others. Everything moves relative to the root. When you assign to the CFrame of any part in an Assembly, the root part is the only part that is actually moved, we just move it relative to the part you wanted to move.

To move the non-root parts within an assembly you have to update the welds that specify how parts are positioned relative to each other (like disabling WeldConstraints to split the assembly, moving the part, and re-enabling the WeldConstraint).

The Second Rule of Assemblies

An anchored parts will always be its own Assembly root. That is part:GetRootPart() == part is always true if part is Anchored.

If two parts are connected by welds they will always be in the same assembly unless there are multiple anchored parts involved (due to this rule).

The Third Rule of Assemblies

An unanchored object welded directly to an anchored object is it’s own assembly. It will be frozen in place where it was before the weld was created as if the object is anchored itself, except it’s not recursive. It only applies if the part is directly welded to an anchored part. The position of the unanchored part may not replicate consistently.

This “third rule” is what we changed to make the behavior of welds simpler and more consistent for developers in the future.

Hopefully this helps explain why we did this a little better and why you’re seeing the things you’re seeing.

11 Likes

But will the issue in his post be addressed? Where changing the CFrame of unanchored parts affects anchored parts welded to them?

I think anchored parts are inheriting the velocity from parts welded to them. I noticed in my game that the baseplate would sometimes unexpectedly have a velocity, thus causing a bouncy map. It’s late though so I’m going to try to repro it tomorrow.

It’s working as intended. They’re the same assembly now.

2 Likes

Can we make it not do that, please? You can see in @chillthrill709’s picture that his game is being destroyed by the behavior.

Not to mention that welded anchored parts are not affected. If welded anchored parts were affected I would probably have a different opinion, but since they aren’t, this feature makes welds a confusing gimmick since they don’t affect Anchored parts the same way; unanchored -> anchored works, but anchored -> anchored does not.

Yes, I realize what I’ve described is “working as intended” but I find it confusing and annoying.

E.G. If I snapped a tower of bricks, alternating Anchored, Unanchored, Anchored, etc. would CFraming the bottom brick properly change the CFrame of the top? Would it make all those parts a single assembly, transferring between anchored and unanchored parts? In the old system the answer is a resolute “no” but it’s hard to tell now.

3 Likes

Sorry to bump this post, but I made a post talking about my experience with this exact issue, and how GetTouchingParts() seems to have adverse behavior because of this change.

The unanchored part seems to not be detected by GetTouchingParts() of any hitbox if it is welded to an anchored part, regardless of CanCollide true or not.

1 Like

so there’s no plans to fix it? should I just remove the seats from my game?

1 Like

Am not sure if anything will be changed about this new behavior. But to fix your problem for now, I would try checking if a player is sitting in a seat before moving them. If they are sitting, destroy the weld connecting them to the seat and then move them. I hope that helps. :slightly_smiling_face:

We just enabled a change that might fix this. Seats themselves will no longer reposition the humanoid and will only rely on the welds to do this.

This should fix cases where just sitting in a seat or quickly switching between seats would move anchored parts that were welded to the player and you had no other scripts moving the Humanoid.

This will not change anything if you have scripts that reposition a Humanoid while welded to a seat. You’ll have to update your scripts to break the seat weld first or update the seat weld itself if this is the case.

This should take effect on all servers within 10 minutes from now.

1 Like

Thank you! this really helps with my issue.