Phase 14 - Organized directories.
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user