NEON-29: Teal cardinal — snap cap during climb, descend stall, assist tune
Cap walk floor snap to WALK_STEP_ASSIST_SNAP when climbing into a blocking wall (stops 0.32m snap fighting step assist). Restore descend lip snap cap; relax floor_block when descend stalls (low vh, still far in xz). Step assist lift 0.16 m, cooldown 1 tick.pull/41/head
parent
d81e915a0a
commit
b96bec7981
|
|
@ -29,9 +29,11 @@ const IDLE_MANUAL_CORRECTION_MAX_TICKS: int = 8
|
|||
const IDLE_RIM_SETTLE_STEP: float = 0.004
|
||||
## Used by tests and vertical routing checks (feet vs goal surface).
|
||||
const DESCEND_GOAL_Y_MARGIN: float = 0.06
|
||||
## Cap snap while dropping off a pad so Jolt cannot glue the capsule to the upper surface.
|
||||
const DESCEND_LIP_SNAP_CAP: float = 0.1
|
||||
## Y lift when blocked by wall-ish slide but nav goal is higher (stepped bumps).
|
||||
const WALK_STEP_ASSIST_DELTA: float = 0.11
|
||||
const WALK_STEP_ASSIST_COOLDOWN_TICKS: int = 8
|
||||
const WALK_STEP_ASSIST_DELTA: float = 0.16
|
||||
const WALK_STEP_ASSIST_COOLDOWN_TICKS: int = 1
|
||||
## Floor-snap length while step-climbing. Small enough that it cannot reach the lower floor
|
||||
## (~0.11 m away after the first lift) but large enough to catch the step surface once the
|
||||
## capsule clears the face (~0.03 m away after the third lift for a 0.3 m step).
|
||||
|
|
@ -263,19 +265,35 @@ func _apply_walk_air_gravity(delta: float) -> void:
|
|||
velocity += get_gravity() * delta
|
||||
|
||||
|
||||
func _walk_floor_snap_length() -> float:
|
||||
return WALK_STEP_ASSIST_SNAP if _step_assist_active else FLOOR_SNAP_MOVING
|
||||
func _walk_floor_snap_length(feet_y: float, want_goal_h: Vector3) -> float:
|
||||
if _step_assist_active:
|
||||
return WALK_STEP_ASSIST_SNAP
|
||||
if _has_walk_goal:
|
||||
if want_goal_h.length_squared() > 1e-10:
|
||||
var want: Vector3 = want_goal_h.normalized()
|
||||
# Climb: FLOOR_SNAP_MOVING reaches past the lip and snaps the capsule back to the slab
|
||||
# below every tick — fights step assist on cardinal box faces (teal pad).
|
||||
if _auth_walk_goal.y > feet_y + 0.035 and _step_assist_wallish_blocks(want):
|
||||
return WALK_STEP_ASSIST_SNAP
|
||||
if (
|
||||
_auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN
|
||||
and feet_y > _auth_walk_goal.y + 0.08
|
||||
):
|
||||
return minf(FLOOR_SNAP_MOVING, DESCEND_LIP_SNAP_CAP)
|
||||
return FLOOR_SNAP_MOVING
|
||||
|
||||
|
||||
## Descend only: relax `floor_block_on_wall` when pressed against a vertical face so Jolt can
|
||||
## slide off terrace lips. Never when the goal is above the feet (climb) — avoids platform-wide
|
||||
## toggling that broke horizontal motion.
|
||||
func _apply_floor_block_for_descend_at_wall(feet_y: float) -> void:
|
||||
func _apply_floor_block_for_descend_at_wall(feet_y: float, horiz_dist: float) -> void:
|
||||
floor_block_on_wall = true
|
||||
if not _has_walk_goal:
|
||||
return
|
||||
if _auth_walk_goal.y >= feet_y - DESCEND_GOAL_Y_MARGIN:
|
||||
return
|
||||
var vh: float = Vector2(velocity.x, velocity.z).length()
|
||||
var descending_stall: bool = horiz_dist > 0.12 and vh < 0.55
|
||||
if is_on_wall():
|
||||
floor_block_on_wall = false
|
||||
return
|
||||
|
|
@ -288,6 +306,8 @@ func _apply_floor_block_for_descend_at_wall(feet_y: float) -> void:
|
|||
if absf(n.y) < 0.58:
|
||||
floor_block_on_wall = false
|
||||
return
|
||||
if descending_stall:
|
||||
floor_block_on_wall = false
|
||||
|
||||
|
||||
## When the authoritative goal shares XZ with the capsule (e.g. terrace above), horizontal
|
||||
|
|
@ -643,13 +663,13 @@ func _physics_process(delta: float) -> void:
|
|||
var feet_y: float = capsule_feet_y(
|
||||
global_position.y, CAPSULE_HALF_HEIGHT + PLAYER_CAPSULE_RADIUS
|
||||
)
|
||||
_apply_floor_block_for_descend_at_wall(feet_y)
|
||||
_apply_floor_block_for_descend_at_wall(feet_y, horiz_dist)
|
||||
|
||||
var nav_map: RID = _nav_agent.get_navigation_map()
|
||||
if NavigationServer3D.map_get_iteration_id(nav_map) == 0:
|
||||
_set_horizontal_velocity_toward(_auth_walk_goal, want_goal_h)
|
||||
_apply_walk_air_gravity(delta)
|
||||
floor_snap_length = _walk_floor_snap_length()
|
||||
floor_snap_length = _walk_floor_snap_length(feet_y, want_goal_h)
|
||||
move_and_slide()
|
||||
_after_walk_move_and_slide()
|
||||
if (
|
||||
|
|
@ -683,7 +703,7 @@ func _physics_process(delta: float) -> void:
|
|||
_set_horizontal_velocity_toward(_auth_walk_goal, want_goal_h)
|
||||
|
||||
_apply_walk_air_gravity(delta)
|
||||
floor_snap_length = _walk_floor_snap_length()
|
||||
floor_snap_length = _walk_floor_snap_length(feet_y, want_goal_h)
|
||||
move_and_slide()
|
||||
_after_walk_move_and_slide()
|
||||
if _step_assist_active:
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ No new automated GDScript tests are added for this story — there is no new GDS
|
|||
- **Terrace B descend / climb (resolved, iterated):** Scene lifts and **descend-bypass** bee-lines caused regressions (stuck climbs, lip oscillation, wrong-direction slides). **Removed the descend bypass:** vertical moves (e.g. platform ↔ floor) use the **baked nav path + step assist** only. **Walk gravity** is **`!is_on_floor()`** again — never “goal below feet” while still walking on an upper surface (that applied gravity across the whole **TerracePlatformB** deck and destroyed horizontal motion). **`velocity.y`** is cleared by the horizontal steer each tick as before.
|
||||
- **Lip stuck (floor→platform / platform→floor):** QA screenshots for this were on **`TerracePlatformA`** (10 × 10 large SE pad, **0.3 m** single step — not the NW **Terrace B** step/platform pair). Step assist required **`vel_h.dot(want) ≤ 0.52`**, so a **head-on** push into the vertical face (dot ≈ 1) **never** triggered the lift. **Removed** that gate. For **platform→floor**, **`floor_block_on_wall = false`** only when the nav goal is **below** the feet **and** **`is_on_wall()`** or a **wall-ish slide normal** exists, so open deck walking stays stable.
|
||||
- **Teal pad still stuck (follow-up):** Step assist used **slide normals only**; Jolt often exposes the lip via **`is_on_wall()`** / **`get_wall_normal()`** instead — re-added a **directional** wall check (`wnh.dot(want) < -0.02`). Descend relax now also triggers on **shallow floor normal** (`get_floor_normal().dot(UP) < 0.992`) and slightly wider vertical-ish slide band. **`TerracePlatformA`** root **Y = 0.012 m** breaks **coplanarity** with the main floor without the larger gap that hurt **TerraceStepB** approach.
|
||||
- **Teal cardinal both ways (follow-up):** **Climb:** **`FLOOR_SNAP_MOVING` (0.32 m)** was still active while **`_step_assist_wallish_blocks`** was true, snapping the capsule back to the lower floor each tick and cancelling lifts — cap snap to **`WALK_STEP_ASSIST_SNAP`** in that state; **bigger per-tick lift** (`WALK_STEP_ASSIST_DELTA` **0.16**) and **cooldown 1** tick. **Descend:** reintroduced **`DESCEND_LIP_SNAP_CAP`** when clearly above the lower goal, plus **`descending_stall`** (`horiz_dist` not trivial, **`vh < 0.55`**) to relax **`floor_block_on_wall`** when Jolt reports neither wall nor shallow floor at a cardinal lip.
|
||||
|
||||
## Open questions / risks
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue