{"record":{"id":"0f827d267d535a11","repo":"stride3d/stride","slug":"both-rigidbodies-must-be-on-the-same-simulation","errorCode":null,"errorMessage":"Both RigidBodies must be on the same simulation","messagePattern":"Both RigidBodies must be on the same simulation","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Physics/Simulation.cs","lineNumber":696,"sourceCode":"        /// <param name=\"pivotInB\">Pivot point in body b.</param>\n        /// <param name=\"axisInB\">Axis in body b.</param>\n        /// <param name=\"useReferenceFrameA\">if set to <c>true</c> [use reference frame a].</param>\n        /// <exception cref=\"System.Exception\">\n        /// Cannot perform this action when the physics engine is set to CollisionsOnly\n        /// or\n        /// Both RigidBodies must be valid\n        /// </exception>\n        public static HingeConstraint CreateHingeConstraint(RigidbodyComponent rigidBodyA, Vector3 pivotInA, Vector3 axisInA, RigidbodyComponent rigidBodyB, Vector3 pivotInB, Vector3 axisInB, bool useReferenceFrameA = false)\n        {\n            if (rigidBodyA == null || rigidBodyB == null) throw new Exception(\"Both RigidBodies must be valid\");\n            return CreateHingeConstraintInternal(rigidBodyA, rigidBodyB, pivotInA, pivotInB, axisInA, axisInB, useReferenceFrameA);\n        }\n\n\n        static Constraint CreateConstraintInternal(ConstraintTypes type, RigidbodyComponent rigidBodyA, Matrix frameA, RigidbodyComponent rigidBodyB = null, Matrix frameB = default, bool useReferenceFrameA = false)\n        {\n            if (rigidBodyA == null) throw new Exception($\"{nameof(rigidBodyA)} must be valid\");\n            if (rigidBodyB != null && rigidBodyB.Simulation != rigidBodyA.Simulation) throw new Exception(\"Both RigidBodies must be on the same simulation\");\n\n            Constraint constraintBase;\n            var rbA = rigidBodyA.InternalRigidBody;\n            var rbB = rigidBodyB?.InternalRigidBody;\n            switch (type)\n            {\n                case ConstraintTypes.Point2Point:\n                {\n                    var constraint = new Point2PointConstraint\n                    {\n                        InternalPoint2PointConstraint = \n                            rigidBodyB == null ? \n                            new BulletSharp.Point2PointConstraint(rbA, frameA.TranslationVector ) :\n                            new BulletSharp.Point2PointConstraint(rbA, rbB, frameA.TranslationVector, frameB.TranslationVector),\n                    };\n                    constraintBase = constraint;\n\n                    constraint.InternalConstraint = constraint.InternalPoint2PointConstraint;","sourceCodeStart":678,"sourceCodeEnd":714,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Physics/Simulation.cs#L678-L714","documentation":"When a constraint links two rigid bodies, both must belong to the same physics Simulation instance, because Bullet constraints are created within one dynamics world. CreateConstraintInternal compares rigidBodyB.Simulation with rigidBodyA.Simulation and throws if they differ (only when rigidBodyB is non-null).","triggerScenarios":"Calling Simulation.CreateConstraint or the two-body CreateHingeConstraint with bodies whose RigidbodyComponent.Simulation properties point to different Simulation objects (e.g. one body in a different scene's physics world).","commonSituations":"Cross-scene joint setups; entities moved between scenes after their bodies were registered; multiple physics simulations in one game and bodies mixed across them.","solutions":["Ensure both rigid bodies live in scenes/components served by the same Simulation before constraining them.","If the bodies must interact, move one entity into the other body's scene or merge the simulations.","Check rigidBodyA.Simulation == rigidBodyB.Simulation in setup code before creating the constraint."],"exampleFix":"// before\nSimulation.CreateConstraint(ConstraintTypes.Point2Point, bodyA, bodyB, frameA, frameB); // bodyB in another scene\n// after\nif (bodyA.Simulation != bodyB.Simulation)\n    throw new InvalidOperationException(\"Constraint bodies must share one simulation\");\nSimulation.CreateConstraint(ConstraintTypes.Point2Point, bodyA, bodyB, frameA, frameB);","handlingStrategy":"validation","validationCode":"if (rigidBodyA.Simulation != rigidBodyB.Simulation) throw new InvalidOperationException(\"Constraint bodies must share one simulation\");","typeGuard":"bool SameSimulation(RigidbodyComponent a, RigidbodyComponent b) => a?.Simulation != null && ReferenceEquals(a.Simulation, b?.Simulation);","tryCatchPattern":"try { var c = Simulation.CreateConstraint(t, a, b, fa, fb); } catch (Exception ex) when (ex.Message.Contains(\"same simulation\")) { /* relocate body or skip constraint */ }","preventionTips":["Keep jointed bodies in the same scene/physics world.","Re-check body Simulation after any entity scene move.","Avoid multiple Simulation instances unless cross-scene joints are never needed."],"tags":["physics","stride","constraint","cross-scene"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}