Files
stickman/plans/KINEMATIC_BLENDING_AND_RECOVERY.md
ryan e3df1cc5c0 feat: Implement kinematic-to-ragdoll transition system
- Added KINEMATIC_BLENDING_AND_RECOVERY.md to outline features for smooth transitions between kinematic and ragdoll states, including visual and physical blending, and ragdoll recovery.
- Introduced KINEMATIC_TO_RAGDOLL.md detailing the objectives, scope, and core architecture for transitioning the stickman from kinematic to ragdoll mode.
- Created KINEMATIC_TO_RAGDOLL_SPEC.md as an implementation specification, verifying codebase facts and correcting the initial plan based on Godot 4.4 source.
- Enhanced StickmanRig with state management for animated and ragdoll modes, including momentum preservation and ragdoll construction.
- Updated physics_test_harness to support toggling between kinematic and ragdoll states with user input.
2026-08-27 00:05:17 -04:00

206 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.51.0 seconds). This avoids jarring pops and creates a more polished, filmlike 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 (nearrigid).
- 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 ragdolls 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 bodys 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` nodes global position and rotation to match the captured ragdoll pose.
- This ensures the skeleton matches the ragdolls 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, reenable 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 Torsos 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, reenable 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 standup 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)
- **Standup 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 standup 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 pregenerated `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. FutureProofing
- 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. DirectorControlled 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 → reenable IK). | Endtoend 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. | Directorfacing. |
---
## 7. Risks & Mitigations
| Risk | Mitigation |
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Recovery animation looks unnatural because the starting pose varies. | Use a generic "pushup" style animation that starts from a prone position; blend the first frame from the captured pose to the animations 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 (easeinout) 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 standup. |
| `scenes/physics_test_harness.tscn` | Add UI controls (slider/spinbox) for `rest_timeout`. |
| `scripts/physics_test_harness.gd` | Connect UI to the rigs `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 directordefined duration.
- The standup 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_