NOT Changing the rules for eliminating duplicated Welds and other rigid joints (yet)

Update 2: We just DISABLED this change!

We disabled this change at 4:47 PST (September 7th).

I found some issues with how it played with replication. It was possible for welds to be added seemingly out of order causing the client to remove the wrong weld before applying the removal of the old weld from the server. The client would up with no weld where the server still had one. This is the kind of terrible desyncronization we were trying to reduce with this change in the first place. This was already possible in the existing implementation, but this actually ended up occurring more likely to happen after my change.

We’ll need to re-evaluate. After some reflection and discussion with the team we’re leaning towards removing this rule for removing redundant welds altogether and just allowing them to all coexist. We already have a system for deterministically picking which welds are active. Maybe we’ll expose a read-only Active property add some APIs to allow you to do this yourself if you want?

We’ll post another update like this well before we make any new changes. More updates to come…

Original Post:

Hey Developers,

We’ve seen a lot of requests to allow WeldConstraints to be duplicated.

We heard you! Soon you’ll be able to duplicate away. We’ll also be making some other changes to how redundant joints are handled that might affect games.

We are planning to enable these changes globally on September 4th. If you want to test them in your game earlier, let me know. We can enable it early for specific places.

We don’t expect this change to impact any games, however, if you noticed any issues in your game, please let us know!

What’s Changing?

Previously adding a new rigid joint (like a Weld, WeldConstraint, or Motor6D) between two parts in the Workspace would remove any preexisting rigid joint between the same two parts. This is why it appears you can’t duplicate these joints: Hitting Ctrl+D on a rigid joint does duplicate the joint, but it removes the existing one at the same time.

We are changing how this “there can only be one” rule is applied to allow duplicated WeldConstraints to co-exist.

We’re also changing this to be more consistently applied with JointInstances, making it more strict. Previously, if you set Part0/Part1 on a joint after parenting it into Workspace, you could create a situation with redundant joints between the same two parts. After this change, we’ll remove all other redundant rigid joints any time a rigid joint becomes active in Workspace.

Why is it Changing?

This rule makes sense for JointInstance because we can only honor one set of Weld CFrames between two parts at a time, so we try to remove other conflicting welds. Since WeldConstraints take their internal CFrames from the existing orientation of its parts when they are enabled and can’t move parts on their own this isn’t an issue with WeldConstraints. There’s no technical reason to not allow duplicate WeldConstraints.

While investigating this, I found some inconsistencies with how this rule was applied. It sometimes allowed redundant JointInstances when properties were set in different orders. This could cause issues with replication: you could create a model containing multiple rigid joints between the same two parts on the server, but after it was replicated clients would only see one of those joints. This creates inconsistencies between the server and clients that can cause worse issues with physics sync later. We decided (long-term) that we should apply this more consistently to avoid these inconsistencies and reduce the number of edge cases devs need to contend with.

40 Likes

On the topic of changing weld behavior - can we have a property for the humanoid where it doesn’t break weldconstraints upon death? :slight_smile:

12 Likes

Quick update: I’ll be releasing this change tomorrow morning (~11AM PST), instead of today as originally planned. I forgot about Labor Day, and I’d hate to disrupt any games during a long holiday weekend.

3 Likes

This change has been enabled. Let us know if you experience weld related issues.

2 Likes

Thank you for your consideration of the holiday, really appreciate that kind of thoughtfulness <3

2 Likes

My game broke some hours ago.

After going ragdoll my custom EquipWeld (in Handles) will break.
They still exist on server and client, but after you equip it the weld is destroyed on client side (yet still exist on the server).

Ragdoll basically sets my custom characters Motor6D parent to nil and adding contrains. When you come back from ragdoll the same Motor6D is readded to the character and contrains removed.

Game found here: www.roblox.com/games/177200271/Reason-2-Die-1-2-1b
Altho I patched it so it doesn’t ragdoll anymore until this is fixed.

1 Like

You should probably link any places where you’re experiencing this issue to fast-track the diagnostic of the bug.

Right!

1 Like

This recently started to break my game entirely. I use some that was mostly written by @Maximum_ADHD and re-purposed by @TheGamer101 to remove R15 packages and use the default R15 body (for this game, it’s the old one).
[Reference]: https://devforum.roblox.com/t/prevent-players-from-wearing-packages-with-r15/31035/2

The problem is, however, that the Root weld no longer stays in LowerTorso; It gets deleted right away and causes this to happen:


The character would be detached from the HumanoidRootPart.

I had my game print out which joint it was making, and if it was successfully parenting it to the right limb.
image

However when checking all children of LowerTorso, it showed no ‘Root’ Motor6D

I made a more quick repro of the bug here:
https://www.roblox.com/games/1073935307/test-pit

I managed to fix this bug by manually making the Root joint again later on in the process.

local newRoot = Instance.new("Motor6D")
newRoot.Name = "Root"
newRoot.Part0 = Character.HumanoidRootPart
newRoot.Part1 = Character.LowerTorso
newRoot.C0 = Character.HumanoidRootPart.RootRigAttachment.CFrame
newRoot.C1 = Character.LowerTorso.RootRigAttachment.CFrame
newRoot.Parent = newRoot.Part1

Could this bug be related to this change? I noticed that when turning off the R15 package resetter, it no longer happened, so it has to do with the new Root weld being deleted for some reason.

EDIT: This also doesn’t happen in Studio, only online.

1 Like

I’ll take a look at this. The techniques I’ve been using for switching out packages should no longer be necessary, now that Roblox has added GetBodyPartR15 and ReplaceBodyPartR15.

1 Like

Update: We just disabled this change. The original post is updated with more info.

To everyone who was affected and those of you who sent me some really great repro cases: thank you (it helped!) and sorry for the trouble!

4 Likes