NEON-29: Suspend ledge peel on column treads to stop idle jitter.

When vertical route is latched and nav column steering is active, peel
plus zero floor snap caused a 3-frame limit cycle (NEON-16 traces).
Skip peel and restore normal snap while feet are within 0.48 m of the
goal surface vertically.
pull/41/head
VinPropane 2026-04-12 18:51:07 -04:00
parent 33b6db979e
commit 26ad33230d
1 changed files with 16 additions and 0 deletions

View File

@ -28,6 +28,10 @@ const NAV_COLUMN_STEER_EXIT_DIST: float = 0.97
const NAV_PATH_STEER_MIN_LOOKAHEAD: float = 0.22
## If lookahead steering points more than ~105° from the click direction (XZ), use direct goal steer instead.
const NAV_PATH_STEER_MIN_GOAL_DOT: float = -0.25
## While [code]vlat && ncol[/code], ledge peel + zero floor snap fight [method move_and_slide] on approach treads
## (3-cycle NEON-16 traces: same XZ triplet, Y/feet_y ping-pong). Suspend peel and allow normal snap when the
## feet are within this vertical distance of the goal **surface** (m).
const WALK_PEEL_SUSPEND_VERT_SEP: float = 0.48
## Hysteresis for [code]needs_vertical_routing[/code]: [code]feet_y[/code] wobbles with
## [code]move_and_slide[/code] on treads (~7 cm), so a single margin (see [member DESCEND_GOAL_Y_MARGIN])
## can flip path vs direct steering every tick → velocity sign ping-pong while [code]has_goal[/code].
@ -462,6 +466,14 @@ func _apply_walk_air_gravity(delta: float, _feet_y: float, _move_dir_xz: Vector2
velocity += _player_vertical_accel(delta) * delta
func _walk_peel_suspend_on_column_treads(feet_y: float) -> bool:
return (
_walk_vert_route_latched
and _walk_nav_column_steering
and absf(_auth_walk_goal.y - feet_y) < WALK_PEEL_SUSPEND_VERT_SEP
)
## After [method move_and_slide], peel the capsule down when the authoritative goal is below the feet
## but the engine still reports floor contact (GROUNDED mode ate negative [code]velocity.y[/code]).
## Uses a small accumulated peel speed so displacement matches [code]∫ g dt[/code], not [code]g Δt[/code] (wrong units).
@ -483,6 +495,9 @@ func _apply_walk_post_slide_ledge_peel(
if _auth_walk_goal.y > feet_y + 0.04:
_walk_ledge_peel_vy = 0.0
return
if _walk_peel_suspend_on_column_treads(feet_y):
_walk_ledge_peel_vy = 0.0
return
var peel: bool = (
feet_y > _auth_walk_goal.y + WALK_DEEP_DESCENT_FEET_ABOVE_GOAL
or not _walk_has_close_floor_probe_below(move_dir_xz)
@ -506,6 +521,7 @@ func _walk_floor_snap_length(
# Strong moving snap + lip [code]is_on_floor()[/code] otherwise cancels gravity every tick.
if (
is_on_floor()
and not _walk_peel_suspend_on_column_treads(feet_y)
and (
not _walk_has_close_floor_probe_below(move_dir_xz)
or feet_y > _auth_walk_goal.y + WALK_DEEP_DESCENT_FEET_ABOVE_GOAL