# Kinematic-to-Ragdoll Translation ## 1. Objective We want dynamic state-switching system that transitions the `master_rig.tscn` stickman from a kinematic, IK-driven puppet (`ANIMATED` mode) into a fully physical, ragdoll-driven entity (`RAGDOLL` mode). This enables natural falling, tumbling, and collision responses with the physics environment (terrain and props) while preserving the stickman’s current momentum. ## 2. Scope & Impact - **Primary Target:** `scripts/stickman_rig.gd` (the runtime controller of `master_rig.tscn`). - **Secondary Target:** `scripts/physics_test_harness.gd` (adds trigger method). - **Scene Impact:** The `master_rig.tscn` scene file will **not** be modified. All ragdoll nodes (bodies and joints) will be spawned procedurally in code, keeping the scene file clean and maintaining the separation between visual authoring and runtime physics. ## 3. Core Architecture / Behavior ### 3.1. State Management `StickmanRig` gains a new `state` property with two modes: `ANIMATED` and `RAGDOLL`. - **`ANIMATED` (Default):** The skeleton and visual `Body/*` nodes are visible and driven by the `AnimationPlayer` and `SkeletonModificationStack2D` (IK). The script tracks the root node’s velocity every frame to cache momentum. - **`RAGDOLL`:** The kinematic rig is frozen (IK disabled, `AnimationPlayer` stopped), the `Body/*` visual nodes are hidden, and a new network of `RigidBody2D` nodes (with matching collision shapes) is spawned and reparented to the world root. Physical `PinJoint2D` nodes connect these bodies, simulating the bone hierarchy. ### 3.2. Velocity Handoff (Momentum Preservation) To avoid unnatural "freeze" effects when switching, the system captures the `linear_velocity` and `angular_velocity` of the rig root in `ANIMATED` mode (using `_process`). Upon entering `RAGDOLL` mode, these cached velocities are applied directly to the ragdoll’s **Torso** body, ensuring the stickman continues its current motion (falling, sliding, etc.) seamlessly. ## 4. Implementation Breakdown ### 4.1. Ragdoll Construction A dedicated builder function iterates over a predefined set of `Bone2D` nodes from the `Skeleton2D` hierarchy. For each bone, it spawns a `RigidBody2D` with the following specifications: - **Position:** The midpoint of the bone (calculated from `global_position` and `bone.length`). - **Rotation:** Matches the `global_rotation` of the bone. - **Collision Shapes:** - **Head:** Uses a `CircleShape2D` with a radius of **100px** (matching the visual head graphic). - **Other Bones (Limbs & Torso):** Uses a `CapsuleShape2D`. The height matches the bone’s `.length` property, and the radius matches the visual line width (approximately **14px**). - **Mass Distribution:** The Torso is given a significantly higher mass (e.g., `8.0`) compared to limbs (e.g., `1.5`) to create realistic inertia and prevent limbs from dragging the body into orbit upon collision. - **Damping:** `Linear` and `Angular` damping are applied to prevent excessively bouncy or "spaghetti-like" behavior. ### 4.2. Jointing (Parent-Child Constraints) For every child bone that has a valid parent bone, the system spawns a `PinJoint2D`. - **Positioning:** The joint is placed at the **bottom of the parent bone**, which aligns with the **top of the child bone**. - **Rotation Limits (Critical for realism):** - **Elbows and Knees:** Angular limits are enforced (strictly restricted to prevent backward bending/hyperextension). - **Head/Neck:** Loose limits or free rotation to allow natural lolling. - **Torso/Shoulders/Hips:** Moderate limits to maintain structural integrity while allowing dynamic twisting. - **Stiffness:** The `softness` and `bias` properties are tuned to prevent limb separation (stretching) under stress. ### 4.3. Cleanup & Reversion The `RAGDOLL` mode is designed to be reversible: - When exiting `RAGDOLL` (or reloading the rig), all dynamically spawned `RigidBody2D` and `PinJoint2D` nodes are queued for deletion. - The kinematic `Body/*` nodes are made visible again. - The `SkeletonModificationStack2D` (IK) is re-enabled, and the `AnimationPlayer` is reset to a neutral state. ## 5. Integration with Test Harness The existing `PhysicsTestHarness` scene will be updated to include a user trigger: - **Key Binding:** Pressing the **R** key will call the `toggle_ragdoll()` method. - **Collision Proxy Management:** The harness currently places a `RigCollisionProxy` (a large static box) around the rig to allow props to interact with it. When entering `RAGDOLL` mode, this proxy **must be destroyed** immediately; otherwise, the physical ragdoll will spawn inside the box and float unrealistically. The ragdoll will instead collide directly with the actual terrain geometry. ## 6. Acceptance Criteria (For QA/Testing) - **Transition Seamlessness:** Switching to ragdoll mid-walk or mid-air applies the correct linear/angular momentum so the stickman continues the trajectory naturally. - **Terrain Interaction:** The ragdoll must rest, slide, or tumble naturally on flat ground, ramps, and stairs (colliding with the `TerrainBlock` static bodies). - **Structural Integrity:** Limbs should not stretch or detach under gravity or moderate impact. Elbows and knees must not bend backwards. - **Visual Fidelity:** The physical collision shapes should align visually with the hidden `Line2D` bones (no floating collision boxes). - **Cleanup:** Rapid switching between modes (spawning/deleting ragdolls) does not cause memory leaks or orphaned nodes.