For as long as we can remember, Roblox has always tried to automatically remove redundant welds. We are going to change that soon in the pursuit of eventual consistency for welds.
Currently, whenever you insert a Weld into Workspace, we will check if there is already an existing Weld, Snap, WeldConstraint, or Motor6D between the same two parts and remove the preexisting weld.
Soon, for places using Workspace.AutoJointsMode = Explicit
, we will no longer automatically remove welds for you in this way. If needed you should do this yourself, explicitly.
Update This change was enabled at 11:05 AM PST on December 6th 2018.
Along with this change, we will be extending the opt-in window for Workspace AutoJointsMode.Explicit
until January 10th 2019. After that point, we will change the meaning of AutoJointsMode.Default
to the Explicit mode behavior, including the effects of this change. New game servers for existing games using the Default
setting will start using Explicit mode at this time.
Note that AutoJointsMode.Legacy
will be removed at some point in Q1 2019 (TBD). Please report any issues you find and update your games to support Explicit mode before then!
Why Are You Doing This?
The way we apply this rule is already flawed; when you change the Part properties of a JointInstance or move one of those parts in and out of workspace, this rule is not applied. This loophole lets you create redundant welds anyway, even though this will not usually replicate correctly. Additionally, when we do remove redundant joints, we only remove one redundant joint even if there are several others; if you already had 3 redundant joints and add another one you will still have 3 redundant joints.
Recently we tried to fix this by tightening up the enforcement of this “there can only be one” rule so it would be applied more consistently and remove all other existing redundant joints when applied. Unfortunately, this caused some client-server desynchronization issues and had to be disabled. While investigating, we realized some of these issues were already happening before, and this change simply exacerbated a more fundamental issue with this rule: It creates an ordering dependency for joint and part property setters, and our replication code makes very few ordering guarantees.
In general we strive to avoid order dependencies in the DataModel. This is critical if we want replication to be eventually consistent, which we do.
We probably wouldn’t have shipped this system for removing welds today; under current design rules, this probably wouldn’t pass review. It’s time to say goodbye to the age of “There Can Only Be One”. Welcome to The Weld Party, where all welds are welcome.
How Will This Affect My Games?
We know it’s common for games to use “weld scripts” to weld all the parts in a model together. We see a lot of models including multiple redundant (sometimes conflicting) weld scripts and rely on this code to clean up the mess. We’re not going to clean this up automatically anymore. You’re going to end up with a bunch of unnecessary welds if you do this.
Start by deleting your old weld scripts. The age of weld scripts is over. If you are using AutoJointsMode.Explicit
, it is safe to move models with welds in and out of workspace with their welds in tact. WeldConstraint
s can also be safely moved in and out of Workspace in any mode. Weld your models together as needed when you author them and let welds be cloned with the model.
Any other code relying on welds being automatically removed when new ones are added will be affected.
Code using Part:MakeJoints()
or Part:BreakJoints()
shouldn’t be affected. MakeJoints()
already includes a check for existing joints and BreakJoints()
will work the same as before, by removing joints from the world.
Games using AutoJointsMode.LegacyImplicit
are also unaffected for now. Note that Legacy mode is going away soon. Legacy mode is only a temporary option to buy you time to fix games and report issues.
We’re also going to be releasing an Active
property for joints soon, which you will be able to use to see which rigid joints are being ignored internally. This will help with writing plugins for removing duplicate joints or even unnecessary joints forming indirect cycles that can be removed if your model doesn’t need to support arbitrary destruction. We’ll make a separate post when it’s available.