Files

8.1 KiB

Ragdoll Cleanup — Implementation Plan

1. Overview

This plan addresses three specific issues with the stickman's ragdoll state:

# Issue Impact
1 Recovery Position Offset Stickman floats above the terrain when recovering from ragdoll.
2 Visual Identity Loss Custom colors/shapes disappear; replaced by gray bones.
3 Profile Persistence Joint bending doesn't respect LEFT/RIGHT/FORWARD profile in ragdoll.

Each issue has a clear fix and verification steps.


2. Issue 1: Recovery Position Offset (Floating)

2.1. The Problem

When the stickman recovers from ragdoll, it appears floating above the terrain at the landing position, rather than standing with feet on the ground.

Root Cause: _reanchor_root_to_landing() calculates the ground contact point using _captured_ground_y = torso.center.y + RAGDOLL_TORSO_RADIUS. This assumes the torso is lying flat on its side. If the ragdoll's torso is rotated (as it often is after a fall), the calculated ground point is incorrect. I

2.2. The Fix

Replace the torso-capsule ground calculation with a downward raycast from the ragdoll's center to find the actual terrain surface.

Implementation:

# In _start_recovery() before destroying the ragdoll:
func _get_ground_y_at_position(world_pos: Vector2) -> float:
    var space := get_world_2d().direct_space_state
    var query := PhysicsRayQueryParameters2D.create(
        world_pos + Vector2(0, -50),  # Start slightly above
        world_pos + Vector2(0, 2000)  # Downward
    )
    query.collision_mask = 1  # Terrain layer
    var result := space.intersect_ray(query)
    if result:
        return result.position.y
    return world_pos.y  # Fallback to current Y

Then use this to position the standing figure's feet:

# In _reanchor_root_to_landing():
var ground_y := _get_ground_y_at_position(_captured_landing_center)
var feet := Vector2(_captured_landing_center.x, ground_y)
var new_root := feet + FOOT_OFFSET
global_position = new_root

2.3. Acceptance Criteria

  • Stickman recovers to a standing position with feet touching the terrain surface.
  • Works on flat ground.
  • Works on slopes and uneven terrain.
  • Works on ramp edges.
  • No floating or clipping into terrain.

3. Issue 2: Ragdoll Visual Identity

3.1. The Problem

When entering ragdoll mode, the stickman's custom colors and shapes are hidden, replaced by gray capsule "bone guide" visuals.

Root Cause: _enter_ragdoll() hides Body/* visuals and spawns plain RigidBody2D bodies with default capsule colors. The gray appearance is the default capsule color.

3.2. The Fix Ragdoll bodies should inherit the visual properties (colors, shapes) from the Body/* nodes.

Implementation:

Read the geometry and color from each Body/* part node (Line2D or Polygon2D).

Create matching visual children on each ragdoll rigidbody.

The ragdoll's collision shapes remain simple capsules for physics; visual shapes are cosmetic overlays.

Mapping:

Body Node	Ragdoll Body	Visual Child
Body/Head	Head RigidBody	CircleShape2D (color from visual)
Body/Body	Torso RigidBody	CapsuleShape2D (color from visual)
Body/LeftUpperArm	LeftUpperArm RigidBody	CapsuleShape2D (color from visual)
etc.	etc.	etc.

Important: The visual shapes are positioned/rotated to match the ragdoll body's orientation. They are cosmetic only — physics uses the capsule collision shapes underneath.

3.3. Acceptance Criteria

  • Ragdoll bodies match the stickman's custom colors and shapes.
  • No gray "bone guide" visuals appear.
  • Visuals transition smoothly between ANIMATED and RAGDOLL.
  • Visuals stay consistent when exiting ragdoll.

4. Issue 3: Profile Persistence in Ragdoll

4.1. The Problem

The stickman's facing profile (LEFT/RIGHT/FORWARD) bone bending does not persist into ragdoll mode. Joints bend unrealistically when ragdolling.

Root Cause: The ragdoll's PinJoint2D angular limits are set once at build time using a generic rule. They don't account for the current facing_profile.

4.2. The Fix

The ragdoll build should read the current facing_profile and apply profile-specific joint limits.

Implementation:

When building the ragdoll (_build_ragdoll()), pass the current facing_profile to _apply_ragdoll_joint_limits():

FORWARD: Use the existing default (elbows/knees fold toward +CW).

LEFT: Mirror the joint limits (swap the elbow/knee fold direction).

RIGHT: Use the same as FORWARD (or mirror appropriately).

Using PROFILE_FLAGS:

The existing PROFILE_FLAGS constants already map facing profiles to per-joint flip_bend_direction flags. Use these to determine joint limit mirroring:

Joint	FORWARD	LEFT	RIGHT
LeftArm	Normal	Normal	Inverted
RightArm	Inverted	Normal	Normal
LeftLeg	Inverted	Inverted	Normal
RightLeg	Normal	Inverted	Inverted
``
The flip_bend_direction flag determines which way the joint naturally bends. This should be applied to the ragdoll's PinJoint2D angular limits.

Example for elbow/knee joints:

```gdscript
# If flipped = true, the joint bends toward -CW instead of +CW
if flipped:
    joint.angular_limit_lower = -150.0
    joint.angular_limit_upper = 5.0
else:
    joint.angular_limit_lower = -5.0
    joint.angular_limit_upper = 150.0

4.3. Acceptance Criteria

  • LEFT profile ragdoll joints bend the correct way.
  • RIGHT profile ragdoll joints bend the correct way.
  • FORWARD profile ragdoll joints bend the correct way.
  • Profile persists after recovery.
  • Joints do not hyperextend or bend backwards.

5. Implementation Order

Step Task Dependencies
1 Fix Recovery Position — Replace torso-capsule ground calculation with downward raycast. None
2 Fix Ragdoll Visuals — Ragdoll bodies inherit Body/* geometry/color as cosmetic children. None
3 Fix Profile Persistence — Ragdoll joints respect facing_profile via PROFILE_FLAGS. None
4 Integration Test — Test all three fixes together in the Sandbox Stage. Steps 1-3

6. File Changes Summary

File Changes
scripts/stickman_rig.gd Fix _reanchor_root_to_landing() with raycast; _build_ragdoll() reads facing_profile; _apply_ragdoll_joint_limits() uses profile flags for mirroring; _enter_ragdoll() preserves visual geometry.

7. Full Acceptance Criteria

7.1. Recovery Position

  • Stickman recovers to a standing position with feet touching the terrain surface.
  • Works on flat ground, slopes, and uneven terrain.
  • No floating or clipping into terrain.

7.2. Ragdoll Visuals

  • Ragdoll bodies match the stickman's custom colors and shapes.
  • No gray "bone guide" visuals appear.
  • Visuals transition smoothly between ANIMATED and RAGDOLL.
  • Visuals stay consistent when exiting ragdoll.

7.3. Profile Persistence

  • LEFT profile ragdoll joints bend the correct way.
  • RIGHT profile ragdoll joints bend the correct way.
  • FORWARD profile ragdoll joints bend the correct way.
  • Profile persists after recovery.
  • Joints do not hyperextend or bend backwards.

7.4. Backward Compatibility

  • Existing ragdoll behavior remains intact.
  • Existing profiles work as before.
  • No new errors or warnings in the console.