Constraints should take complete precedence over forces acting on objects

I made a simple sliding door using a prismatic constraint:

The transparent part is the part Attachment0 is parented to, and the black door is the part Attachment1 is parented to. The attachments are pointed so that the door will only move on the Z axis. The constraint’s limits are [0,8]. To move the door, I inserted a BodyVelocity with a Velocity of <0,0,10> and MaxForce of <0,0,1000>. I noticed that the door got pushed past the limit though – for instance, when I pulled it back, the constraint’s CurrentPosition was -0.02 and it was clearly visible that it was not flush with the door frame:

I set the MaxForce to <0,0,-10000000000> in an attempt to forcefully break the constraint, and it did just that:

The prismatic constraint which is supposed to only allow for movement on one axis was completely ignored and the door was flung out of the frame, and became unable to return inside when the constraint tried to pull it back in.

Obviously I shouldn’t be doing things like I did in the last image, but the one before it was perfectly reasonable usage of the constraint and BodyVelocity, yet the constraint had issues anyway. Currently constraints are undependable and prone to break immediately when conditions are no longer ideal (which is very frequently due to the nature of ROBLOX physics) – this is not what I’d like to see from constraints. Further, I thought the whole reason constraints were created was because hinges/motors were unpredictable/unreliable – constraints seem to have the same issue though. Constraints should be absolutes that I can depend on. If the physics engine is making a calculation that involves a constraint, the physics should be constrained by the constraint, and not an after effect that tries (and generally fails) to produce the desired result.

1 Like

The -0.02 offset is by design in the physics engine (our penetration margin for linear limits is 0.05, so this is within the margin). Allowing small errors is very important for the stability of the physics engine: if the error was required to be 0, the objects would switch between two states: within the limits <-> beyond the limits, causing visible jitter. The good news is, I have ideas how to reduce this margin significantly in static situations (the two parts not moving too much relatively), so expect it to get better in future releases.

Obviously high enough forces will break any of the simulated constraints. It is not voluntary by design, but more a consequence of the numerical methods used in the solver.

2 Likes

Why do constraints limits need to have small errors? Is the physics engine built in a way that you have to constrain the value after it’s already been set by the physics engine instead of constraining it before it’s distributed to anything else leading to this type of elastic snapping?

In a perfect world shouldn’t the physics of the door in the OP be <attachment1.X, attachment1.Y, constrain(targetValue, constraint.MinLimit, constraint.MaxLimit)>? That way there’s no issue with bouncing back and forth.

1 Like

At a guess, floating point errors?

Not sure how that affects constraints. Regardless of whether the part is 0.1 studs below the min limit or 0.00000000000001 studs below it, the position is always constrain(position, minLimit, maxLimit).