# Ragdoll ↔ Kinematic Blending & Recovery ## 1. Overview Extend the existing kinematic-to-ragdoll system with two major features: - **Blended Transition:** A smooth, visually appealing fade between the kinematic puppet and the ragdoll, eliminating the abrupt "pop" when switching modes. - **Ragdoll Recovery:** The ability for the stickman to autonomously stand back up after falling, transitioning from ragdoll back to animated mode with a "get up" animation. These features are essential for a director-driven sandbox where characters can fall, recover, and continue performing actions. --- ## 2. Feature 1: Ragdoll ↔ Kinematic Blending (Soft Transition) ### 2.1. Objective Replace the instant mode switch with a gradual transition that blends the visual appearance and physical behavior over a configurable duration (e.g., 0.5–1.0 seconds). This avoids jarring pops and creates a more polished, film‑like effect. ### 2.2. Approach #### 2.2.1. Visual Blending (Opacity Crossfade) - During the transition, both the kinematic `Body/*` nodes and the ragdoll `RigidBody2D` bodies are visible. - The kinematic nodes start at full opacity and fade out; the ragdoll bodies start at zero opacity and fade in. - Use a `Tween` or `_process` lerp to drive the `modulate.a` of all relevant nodes over the transition duration. #### 2.2.2. Physical Blending (Joint Stiffness Ramp) - When entering ragdoll, start with the `PinJoint2D` stiffness (`softness`/`bias`) at a high value (near‑rigid). - Gradually reduce stiffness over the transition period so the limbs become floppy. - Conversely, when exiting ragdoll, ramp stiffness from floppy to rigid before freezing the pose. #### 2.2.3. Implementation Outline - `StickmanRig` gains a `transition_duration` property (export, default 0.6s). - `_enter_ragdoll()` spawns the ragdoll bodies with `modulate.a = 0.0` and joints at high stiffness. - A `_transition_process(delta)` runs during the blend, updating opacities and joint properties. - Upon completion, the kinematic nodes are hidden (or vice versa) and the system settles into the target state. ### 2.3. Acceptance Criteria - No visible pop when switching modes. - The transition duration is configurable (tunable per director preference). - Both visual and physical blending are synchronized. --- ## 3. Feature 2: Ragdoll Recovery (Getting Back Up) ### 3.1. Objective Allow the ragdoll to automatically stand up after it has come to rest. This involves detecting rest, capturing the ragdoll’s final pose, applying that pose to the kinematic skeleton, playing a "stand up" animation, and transitioning back to animated mode. ### 3.2. Core Components #### 3.2.1. Rest Detection - Monitor the ragdoll Torso body’s linear and angular velocities. - When both remain below a small threshold (e.g., `0.1 m/s` and `0.1 rad/s`) for a continuous **timeout** (set by the director), trigger recovery. - The timeout must be configurable per character (or globally). #### 3.2.2. Pose Capture - After rest is detected, read the global positions and rotations of all 10 `RigidBody2D` bodies. - Convert these into local transforms relative to the `StickmanRig` root (or the `Skeleton2D` root). - This captured pose becomes the target for the kinematic bones. #### 3.2.3. Kinematic Snap - Temporarily disable IK (`SkeletonModificationStack2D.enabled = false`). - Set each `Bone2D` node’s global position and rotation to match the captured ragdoll pose. - This ensures the skeleton matches the ragdoll’s final resting posture. #### 3.2.4. Stand-Up Animation - Play a "stand up" animation (e.g., `stand_up`) that transitions the skeleton from the captured pose to a neutral standing pose. - The animation should be authored/generated to work from any reasonable rest pose. - Once the animation finishes, re‑enable IK and set the rig back to `ANIMATED` mode. ### 3.3. Implementation Outline - Add a new state `RECOVERING` to `RigState`. - In `_physics_process`, when in `RAGDOLL` mode, track the Torso’s velocity and a rest timer. - When rest timer exceeds `rest_timeout`, call `_start_recovery()`. - `_start_recovery()`: 1. Capture ragdoll pose. 2. Delete ragdoll bodies (or hide them). 3. Snap kinematic skeleton to captured pose. 4. Start the `AnimationPlayer` with the `stand_up` animation. 5. On animation end, re‑enable IK, show `Body/*`, transition to `ANIMATED`. - The recovery process should be interruptible (e.g., if the director toggles back to ragdoll during recovery). ### 3.4. Acceptance Criteria - Ragdoll automatically stands up after resting for the configured timeout. - The stand‑up motion is smooth and visually convincing. - The character resumes animated behavior after recovery. --- ## 4. Animation Generation for Recovery ### 4.1. Current State You have a `create_walk.gd` editor script that generates `walk_left` and `walk_right` animations by keyframing IK target positions. ### 4.2. Proposed Enhancement: `create_animations.gd` Refactor the animation generation into a unified script that can generate: - **Walk cycles** (already done) - **Stand‑up animation** (from a "down" pose to standing) - **Idle / breathing** (optional) #### 4.2.1. Architecture - The script should define a set of **pose templates** (e.g., `POSE_DOWN`, `POSE_STANDING`). - Each template maps IK target names to positions (relative to the rig root). - The stand‑up animation is a blend between the captured pose (first frame) and the standing pose (last frame), with intermediate frames interpolated using a curve. #### 4.2.2. Integration - The recovery logic will reference a pre‑generated `stand_up` animation stored in the `AnimationPlayer`. - The same animation library (`""`) holds all animations. - The generator script can be run once at authoring time to create the default animations. #### 4.2.3. Future‑Proofing - The generator could also accept parameters (e.g., `animation_name`, `profile`, `duration`) to make it reusable. ### 4.3. Acceptance Criteria - A single script (`create_animations.gd`) generates `walk_left`, `walk_right`, and `stand_up`. - The `stand_up` animation works from any reasonable rest pose (i.e., it starts from the current skeleton pose, not a fixed start). --- ## 5. Director‑Controlled Rest Timeout ### 5.1. Requirement The director (user) should be able to adjust how long the ragdoll stays on the ground before attempting recovery. This is crucial for storytelling—some scenes need a quick recovery, others need a long pause. ### 5.2. Implementation - `StickmanRig` gains an `@export var rest_timeout: float = 2.0` (seconds). - The `PhysicsTestHarness` UI (and ultimately the director UI) will provide a slider or spinbox to modify this value on the selected rig. - The value is read during `_physics_process` to determine when to start recovery. ### 5.3. Acceptance Criteria - The rest timeout is editable in the inspector (or via a UI control). - Changes take effect immediately (no need to reload the rig). --- ## 6. Integration Timeline (Suggested Order) | Step | Task | Notes | | ---- | ---------------------------------------------------------------------- | --------------------------------------------------- | | 1 | Add `transition_duration` and `rest_timeout` exports to `StickmanRig`. | Low risk, sets foundation. | | 2 | Implement rest detection timer in `_physics_process`. | Test by printing when rest is detected. | | 3 | Implement pose capture and kinematic snap. | Manual trigger for testing. | | 4 | Create `create_animations.gd` with a `stand_up` placeholder. | Even a simple interpolation is fine for first pass. | | 5 | Integrate recovery flow (snap → play animation → re‑enable IK). | End‑to‑end test. | | 6 | Implement visual blending (opacity crossfade). | Polish. | | 7 | Implement physical blending (joint stiffness ramp). | Advanced polish. | | 8 | Add UI control for `rest_timeout` in the harness. | Director‑facing. | --- ## 7. Risks & Mitigations | Risk | Mitigation | | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Recovery animation looks unnatural because the starting pose varies. | Use a generic "push‑up" style animation that starts from a prone position; blend the first frame from the captured pose to the animation’s first keyframe. | | Kinematic snap may cause jitter if the ragdoll pose is unstable. | Add a small stabilization delay (0.1s) after rest detection before capturing. | | Blending physics (joint stiffness) may cause limbs to twitch. | Use a smooth interpolation curve (ease‑in‑out) rather than linear. | | Multiple rigs in the scene may compete for recovery timers. | Each `StickmanRig` manages its own state independently. | --- ## 8. Summary of New/Modified Files | File | Action | | ---------------------------------- | --------------------------------------------------------------------------- | | `scripts/stickman_rig.gd` | Add transition logic, rest detection, pose capture, recovery state machine. | | `scripts/create_animations.gd` | New file: unified animation generator for walk and stand‑up. | | `scenes/physics_test_harness.tscn` | Add UI controls (slider/spinbox) for `rest_timeout`. | | `scripts/physics_test_harness.gd` | Connect UI to the rig’s `rest_timeout` property. | --- ## 9. Acceptance Criteria (Full Feature Set) - Switching between animated and ragdoll modes is visually smooth (crossfade). - The ragdoll automatically stands up after resting for the director‑defined duration. - The stand‑up animation is generated procedurally and plays seamlessly. - The director can adjust the rest timeout at runtime. - The system is robust and does not produce orphaned nodes or crashes. --- _End of Plan_