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

11 KiB
Raw Permalink Blame History

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