- Updated `DEBUG_RECOVERY` to false for production. - Introduced `RAGDOLL_JOINT_BAND_LIMITS` for customizable joint bend limits based on facing profile. - Added `RECOVERY_LEG_SIDE_FORCE` for manual control of leg IK bend direction during recovery. - Implemented `RECOVERY_JOINT_PATH` to allow optional tween path overrides for elbow/knee recovery. - Removed debug print statements related to recovery visuals to clean up output. - Adjusted `_apply_ragdoll_joint_limits` to utilize new bend limits configuration. - Enhanced documentation in `ragdoll-cleanup.md` to reflect changes in the recovery pipeline and tuning tables.
201 lines
8.1 KiB
Markdown
201 lines
8.1 KiB
Markdown
# 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:**
|
|
|
|
```gdscript
|
|
# 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:
|
|
|
|
```gdscript
|
|
# 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.
|