Roblox Avatar Joint Upgrade Phase 2: Motor6D to AnimationConstraint Migration and the Phase 3 Deadline
Posted: Thu Oct 22, 2026 4:02 am
Quick Summary
Roblox's Physics Team announced Phase 2 of the Avatar Joint Upgrade on May 27, 2026, and the practical effect is a default flip. Before Phase 2, a game had to opt in by setting StarterPlayer.AvatarJointUpgrade to Enabled. After it, any experience whose property sat on Default automatically received the new joint logic, which replaces the traditional Motor6D joints with physics-capable AnimationConstraints and BallSocketConstraints.[1] The argument for the change is that the joints let animation interact physically with the environment instead of rigidly following predetermined animation transforms, which can produce emergent behaviour like limbs swinging.[2]
The control itself is a non-scriptable property. The API reference lists StarterPlayer.AvatarJointUpgrade as ReadOnly with RobloxScriptSecurity on both read and write, which means you cannot set it from a script at runtime.[4] You change it in Studio, where it appears as a rollout state, and you republish the place. That detail catches people who try to handle it in code.
The rollout was always planned as three phases, and the shape of the schedule is the part worth remembering.[2]
Roblox was explicit that setting Disabled is a temporary safety net, not a long-term home. The Phase 2 post asks developers who have to disable the upgrade to comment with exactly what broke so the team can help migrate before the forced migration lands.[1]
What an AnimationConstraint Actually Is
The docs describe AnimationConstraint as aligning two BaseParts with an animate-able kinematic or force-based joint that supports physical simulation, and they name it as the default joint type for R15 avatar rigs.[3] It replaces Motor6D in R15 player character rigs once AvatarJointUpgrade is on.[3]
Two behaviours live behind one property. When IsKinematic is true, the connected parts follow the Transform perfectly and behave the same way a Motor6D does. When IsKinematic is false, the joint follows the trajectory using forces and torques capped by MaxForce and MaxTorque, which is what makes ragdolls and simulated limbs work.[3]
There is a default asymmetry that trips people up. Avatar joint AnimationConstraints spawn with IsKinematic set to true, which is what prevents the migration from breaking every animation at once. AnimationConstraints created outside the upgrade, by your own scripts, spawn with IsKinematic set to false.[2] If you write a test script that builds a joint and immediately expects Motor6D-like behaviour, it will not behave that way.
The parameters that only apply when IsKinematic is false are worth knowing by name:[3]
The Motor6D Migration, Property by Property
The engine API reference carries a migration list for existing Motor6D code, and it is more forgiving than the original announcement suggested.[3]
The replacement is to multiply into Transform during RunService.PreSimulation, which layers procedural math on top of the active animation track without breaking retargeting.[1] The reference docs carry the same pattern:[3]
Note the EvaluationThrottled guard. When the animation system throttles evaluation at lower LOD, skipping the frame avoids stacking your math on top of a pose that was not refreshed.[1]
There is a third rule that is easy to miss: do not drive procedural animation from the server. Some developers set C0 on the server so it replicated to every client. The recommended approach is local animation evaluation on the client, and if you need to sync a value such as an aim direction, replicate a custom Attribute or fire an UnreliableRemoteEvent and process the transforms locally.[1]
What Is Still Not Upgraded
Three carve-outs keep surprising people.[2]
Where Custom Rigs Fit In
If your characters are not stock avatars, two other systems matter more than the joint swap.
Adaptive Animation exists to make one animation library work across very different body types. It uses HumanoidRigDescription and DigitsRigDescription objects inside your character model to map your custom joints onto Roblox's standardized 15-joint skeleton.[6] Once the mapping and a baseline T-pose are configured, the character can play any R15 animation, or any animation published from a character that carries those description objects.[6] The import path is to set Rig Type to Custom in the 3D Importer, then use the Adaptive Animation button in the Avatar tab to generate the rig description objects and assign joints.[6]
Standard and advanced R15 rigs can also use Roblox's character animation library regardless of whether the model belongs to a player or an NPC.[7] Advanced rigs add up to 37 optional joints on top of the required 15, covering spine subdivisions, clavicles, a HeadBase joint, up to 15 finger joints per hand, and toe joints.[5]
For procedural posing rather than authored animation, IKControl is the tool Roblox points to when you are manipulating joints only to make something look at or reach a point.[1] It generates procedural poses through inverse kinematics, and it overrides the animation for every part between ChainRoot and EndEffector, with Weight controlling how much it blends over the underlying animation.[8] The docs recommend it explicitly over manual joint math for reach and aim behaviour.[1]
How to Check Whether Your Game Is Affected
The Community Split
The reaction in the Phase 2 thread is not uniform, and both sides have a real point.
The argument against the change is that it breaks working systems for a feature most games never asked for. The first reply in the announcement thread asks why it cannot remain opt-in, and a later one questions why the old and new systems cannot coexist.[1] A separate community resource titled Animation Constraint Replacer was published in May specifically to intercept spawning characters and convert the new constraints back into standard Motor6Ds, with an attribute flag so legacy scripts can wait for the conversion to finish.[10] Its author's description of the problem is blunt: hierarchy and Instance bloat, broken legacy animation and rigging systems, and disrupted tools that depend on the classic Motor6D structure.[10]
The argument for the change is that the migration is smaller than it looks and that Motor6D is being left behind on purpose. Roblox stated in January that Motor6Ds will continue to work as they do today but will not see improvements as legacy JointInstances, and that investment is moving to constraint tooling.[2] One reply in the community resource thread makes the counter-argument directly, saying the effort to migrate is minimal and recommending against clinging to older joints.[10]
Both readings are defensible. If your game is simple, the upgrade is close to free. If your game has years of Motor6D manipulation baked into ragdolls, viewmodels and procedural animation, it is a real rewrite, and the May post is the warning that the deadline for doing it on your own schedule is the end of the year.[1]
FAQ
Is Motor6D being removed?
Not yet, and not all at once. Motor6Ds continue to work today, but Roblox has described them as legacy JointInstances that will not receive improvements, and said they would be marked deprecated in favour of AnimationConstraints in the weeks following the January announcement.[2] Phase 3 removes the old behaviour entirely.[1]
My ragdoll broke. What do I do first?
Check whether your script writes to C0 or C1. Writing those properties on an AnimationConstraint throws an error, and the docs say to use Attachments instead.[2] If you need the old behaviour back immediately, set StarterPlayer.AvatarJointUpgrade to Disabled and republish, then treat that as a stopgap while you migrate.[1]
Does AvatarJointUpgrade affect R6 games?
No. Roblox says the upgrade does not affect R6 characters, and anyone who wants the behaviour in an R6 experience has to add the constraints with a script in StarterCharacter.[2]
Can I set AvatarJointUpgrade from a script?
No. The API reference lists the property as ReadOnly with RobloxScriptSecurity on read and write, so it cannot be set from running code.[4] Change it in Studio and republish.
Will this affect my NPCs?
No. Upgraded joints are only added to characters from the Player spawning flow and character-creation flows such as HumanoidDescription. NPCs already placed in your place keep their existing joints.[2]
Should I use IKControl or manual joint math for aiming?
IKControl. Roblox's own migration guidance points at it when you are manipulating joints purely to make an arm, head or weapon reach or look at a target, because it handles the chain automatically and bridges with the joint upgrade.[1][8]
Where should I start if I have a lot of Motor6D code?
Three searches, in this order: Motor6D, then C0 and C1, then IsA("Motor6D"). The first tells you the size of the job, the second finds the lines that will throw, and the third finds the guards that will silently stop matching.[2][3]
Sources
- The Avatar Joint Upgrade moved to Phase 2 on May 27, 2026. Any experience where StarterPlayer.AvatarJointUpgrade sits on Default now spawns R15 characters with AnimationConstraint and BallSocketConstraint joints instead of Motor6D joints
- AnimationConstraint is the new default joint type for R15 avatar rigs. Motor6D still works, but Roblox has said Motor6Ds are legacy JointInstances that will not receive improvements
- Phase 3 is targeted for the end of the year and removes the opt-out, so the window to fix Motor6D-dependent scripts is finite
- Do not migrate by editing RigAttachment.CFrame. The recommended path is multiplying into AnimationConstraint.Transform during RunService.PreSimulation
- R6 characters are unaffected by the upgrade, and only characters that come through the player spawn flow or character-creation flows get upgraded joints
Roblox's Physics Team announced Phase 2 of the Avatar Joint Upgrade on May 27, 2026, and the practical effect is a default flip. Before Phase 2, a game had to opt in by setting StarterPlayer.AvatarJointUpgrade to Enabled. After it, any experience whose property sat on Default automatically received the new joint logic, which replaces the traditional Motor6D joints with physics-capable AnimationConstraints and BallSocketConstraints.[1] The argument for the change is that the joints let animation interact physically with the environment instead of rigidly following predetermined animation transforms, which can produce emergent behaviour like limbs swinging.[2]
The control itself is a non-scriptable property. The API reference lists StarterPlayer.AvatarJointUpgrade as ReadOnly with RobloxScriptSecurity on both read and write, which means you cannot set it from a script at runtime.[4] You change it in Studio, where it appears as a rollout state, and you republish the place. That detail catches people who try to handle it in code.
The rollout was always planned as three phases, and the shape of the schedule is the part worth remembering.[2]
| Phase | AvatarJointUpgrade default | What it means |
| Phase 1 (ended) | Maps to Disabled | No breaking change. Creators opted in by setting Enabled. |
| Phase 2 (current) | Maps to Enabled | Breaking change for experiences that depend on Motor6D behaviour. Opt out by setting Disabled and republishing. |
| Phase 3 (end of year) | Property removed | Every place runs the new behaviour. No opt-out, and the old behaviour is no longer accessible. |
What an AnimationConstraint Actually Is
The docs describe AnimationConstraint as aligning two BaseParts with an animate-able kinematic or force-based joint that supports physical simulation, and they name it as the default joint type for R15 avatar rigs.[3] It replaces Motor6D in R15 player character rigs once AvatarJointUpgrade is on.[3]
Two behaviours live behind one property. When IsKinematic is true, the connected parts follow the Transform perfectly and behave the same way a Motor6D does. When IsKinematic is false, the joint follows the trajectory using forces and torques capped by MaxForce and MaxTorque, which is what makes ragdolls and simulated limbs work.[3]
There is a default asymmetry that trips people up. Avatar joint AnimationConstraints spawn with IsKinematic set to true, which is what prevents the migration from breaking every animation at once. AnimationConstraints created outside the upgrade, by your own scripts, spawn with IsKinematic set to false.[2] If you write a test script that builds a joint and immediately expects Motor6D-like behaviour, it will not behave that way.
The parameters that only apply when IsKinematic is false are worth knowing by name:[3]
- MaxForce and MaxTorque, the ceiling on how hard the joint can push or twist toward its goal
- LinearStrength and AngularStrength, defined as a normalized natural frequency where the default of 1 equals a target frequency of 60 Hz
- LinearDamping and AngularDamping, damping ratios where 1 is critical damping and 0 lets the joint oscillate
The Motor6D Migration, Property by Property
The engine API reference carries a migration list for existing Motor6D code, and it is more forgiving than the original announcement suggested.[3]
- C0, C1, Part0 and Part1 exist on AnimationConstraint as read-only aliases for backwards compatibility. They map to Attachment0.CFrame, Attachment1.CFrame, Attachment0.Parent and Attachment1.Parent. Do not write to them, and expect an error if you do.[3]
- Finding joints means swapping FindFirstChildOfClass("Motor6D") for FindFirstChildWhichIsA("AnimationConstraint"). For code that has to support both, check AnimationConstraint first and fall back to Motor6D.[3]
- IsA("Motor6D") returns false on an AnimationConstraint, so any type guard needs to accept both class names.[3]
- Transform works the same way Motor6D.Transform does. The Animator writes to it every frame, and it is reset each frame.[3]
The replacement is to multiply into Transform during RunService.PreSimulation, which layers procedural math on top of the active animation track without breaking retargeting.[1] The reference docs carry the same pattern:[3]
Code: Select all
-- Before (Motor6D): writing to C0 directly
local originalC0 = neck.C0
RunService.RenderStepped:Connect(function()
neck.C0 = originalC0 * computeNeckRotation()
end)
-- After (AnimationConstraint): multiply into Transform during PreSimulation
RunService.PreSimulation:Connect(function()
if not animator.EvaluationThrottled then
neck.Transform = computeNeckRotation() * neck.Transform
end
end)
There is a third rule that is easy to miss: do not drive procedural animation from the server. Some developers set C0 on the server so it replicated to every client. The recommended approach is local animation evaluation on the client, and if you need to sync a value such as an aim direction, replicate a custom Attribute or fire an UnreliableRemoteEvent and process the transforms locally.[1]
What Is Still Not Upgraded
Three carve-outs keep surprising people.[2]
- R6 characters are not affected by the Avatar Joint Upgrade. Roblox's stated reason is that creators who choose R6 are usually intentionally opting out of new avatar features. A developer who wants the behaviour in an R6 game has to add BallSocketConstraints and AnimationConstraints with a script in StarterCharacter.[2]
- Only characters from the Player spawning flow and character-creation flows, such as HumanoidDescription, get the upgraded joints. NPCs already placed in your map are not upgraded.[2]
- AnimationConstraints are available to every experience regardless of whether it opted into the Avatar Joint Upgrade. The upgrade only governs which joints spawn on player characters.[2]
Where Custom Rigs Fit In
If your characters are not stock avatars, two other systems matter more than the joint swap.
Adaptive Animation exists to make one animation library work across very different body types. It uses HumanoidRigDescription and DigitsRigDescription objects inside your character model to map your custom joints onto Roblox's standardized 15-joint skeleton.[6] Once the mapping and a baseline T-pose are configured, the character can play any R15 animation, or any animation published from a character that carries those description objects.[6] The import path is to set Rig Type to Custom in the 3D Importer, then use the Adaptive Animation button in the Avatar tab to generate the rig description objects and assign joints.[6]
Standard and advanced R15 rigs can also use Roblox's character animation library regardless of whether the model belongs to a player or an NPC.[7] Advanced rigs add up to 37 optional joints on top of the required 15, covering spine subdivisions, clavicles, a HeadBase joint, up to 15 finger joints per hand, and toe joints.[5]
For procedural posing rather than authored animation, IKControl is the tool Roblox points to when you are manipulating joints only to make something look at or reach a point.[1] It generates procedural poses through inverse kinematics, and it overrides the animation for every part between ChainRoot and EndEffector, with Weight controlling how much it blends over the underlying animation.[8] The docs recommend it explicitly over manual joint math for reach and aim behaviour.[1]
How to Check Whether Your Game Is Affected
- Open your place in Studio and inspect StarterPlayer. If AvatarJointUpgrade is on Default, your place is already on the new joints.[1]
- Press Ctrl + Shift + F and search for Motor6D across the whole place. The January post used exactly this search and linked a screenshot of the results.[2]
- Search for the properties C0, C1, Part0 and Part1. These are the four that throw when written on an AnimationConstraint.[2][3]
- Search for IsA("Motor6D"). Any guard written this way silently stops matching after the migration.[2][3]
- Look at anything that sets C0 from a server script. That pattern needs to move to client-side evaluation.[1]
- Playtest with a physically simulated joint, meaning IsKinematic set to false, on a low-spec device before you call it done. Roblox has flagged choppy physics replication on other characters as a known limitation of the upgrade, most visible when a character mixes kinematic and physically driven joints.[2]
The Community Split
The reaction in the Phase 2 thread is not uniform, and both sides have a real point.
The argument against the change is that it breaks working systems for a feature most games never asked for. The first reply in the announcement thread asks why it cannot remain opt-in, and a later one questions why the old and new systems cannot coexist.[1] A separate community resource titled Animation Constraint Replacer was published in May specifically to intercept spawning characters and convert the new constraints back into standard Motor6Ds, with an attribute flag so legacy scripts can wait for the conversion to finish.[10] Its author's description of the problem is blunt: hierarchy and Instance bloat, broken legacy animation and rigging systems, and disrupted tools that depend on the classic Motor6D structure.[10]
The argument for the change is that the migration is smaller than it looks and that Motor6D is being left behind on purpose. Roblox stated in January that Motor6Ds will continue to work as they do today but will not see improvements as legacy JointInstances, and that investment is moving to constraint tooling.[2] One reply in the community resource thread makes the counter-argument directly, saying the effort to migrate is minimal and recommending against clinging to older joints.[10]
Both readings are defensible. If your game is simple, the upgrade is close to free. If your game has years of Motor6D manipulation baked into ragdolls, viewmodels and procedural animation, it is a real rewrite, and the May post is the warning that the deadline for doing it on your own schedule is the end of the year.[1]
FAQ
Is Motor6D being removed?
Not yet, and not all at once. Motor6Ds continue to work today, but Roblox has described them as legacy JointInstances that will not receive improvements, and said they would be marked deprecated in favour of AnimationConstraints in the weeks following the January announcement.[2] Phase 3 removes the old behaviour entirely.[1]
My ragdoll broke. What do I do first?
Check whether your script writes to C0 or C1. Writing those properties on an AnimationConstraint throws an error, and the docs say to use Attachments instead.[2] If you need the old behaviour back immediately, set StarterPlayer.AvatarJointUpgrade to Disabled and republish, then treat that as a stopgap while you migrate.[1]
Does AvatarJointUpgrade affect R6 games?
No. Roblox says the upgrade does not affect R6 characters, and anyone who wants the behaviour in an R6 experience has to add the constraints with a script in StarterCharacter.[2]
Can I set AvatarJointUpgrade from a script?
No. The API reference lists the property as ReadOnly with RobloxScriptSecurity on read and write, so it cannot be set from running code.[4] Change it in Studio and republish.
Will this affect my NPCs?
No. Upgraded joints are only added to characters from the Player spawning flow and character-creation flows such as HumanoidDescription. NPCs already placed in your place keep their existing joints.[2]
Should I use IKControl or manual joint math for aiming?
IKControl. Roblox's own migration guidance points at it when you are manipulating joints purely to make an arm, head or weapon reach or look at a target, because it handles the chain automatically and bridges with the joint upgrade.[1][8]
Where should I start if I have a lot of Motor6D code?
Three searches, in this order: Motor6D, then C0 and C1, then IsA("Motor6D"). The first tells you the size of the job, the second finds the lines that will throw, and the third finds the guards that will silently stop matching.[2][3]
Sources
- Roblox DevForum: Avatar Joint Upgrade (AJU) Phase 2 Rollout and Updated Migration Recommendations (May 27, 2026)
- Roblox DevForum: Avatar Joint Upgrade for Physically-Simulated Character Movement is Now Live (January 26, 2026)
- Roblox Creator Hub: AnimationConstraint API reference, including the Motor6D migration notes
- Roblox Creator Hub: StarterPlayer API reference, AvatarJointUpgrade property
- Roblox Creator Hub: Characters overview, R15 rigs and the Avatar Joint Upgrade
- Roblox Creator Hub: Adaptive Animation, HumanoidRigDescription and DigitsRigDescription
- Roblox Creator Hub: Inverse Kinematics and IKControl setup
- Roblox Creator Hub: IKControl API reference, required properties
- Roblox Creator Hub: Character body specifications, standard and advanced R15 rigs
- Roblox DevForum: Animation Constraint Replacer, a community resource for reverting to Motor6D