diff --git a/client/scripts/player.gd b/client/scripts/player.gd index 675271a..bf980a9 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -728,7 +728,15 @@ static func idle_support_is_stable( ) -> bool: if not on_floor: return false - if floor_normal.dot(Vector3.UP) < min_flat_up_dot: + var ridged: bool = idle_slide_contacts_are_ridged(slide_normals) + # Entering stable idle uses [member STABLE_IDLE_FLOOR_MIN_UP_DOT] (0.998). On stair treads, + # [code]get_floor_normal()[/code] often sits ~0.996–0.997 with a riser contact — never latches, + # so idle stays in corrective [method _maybe_idle_rim_settle_nudge] + [method _physics_idle_tick] + # forever (HUD jitter while **not** walking). Use the latched hold threshold (0.992) when ridged. + var required_up: float = min_flat_up_dot + if ridged and min_flat_up_dot >= STABLE_IDLE_FLOOR_MIN_UP_DOT - 1e-6: + required_up = STABLE_IDLE_FLOOR_HOLD_MIN_UP_DOT + if floor_normal.dot(Vector3.UP) < required_up: return false # Post-stop **ridged** slides (tread + riser) used to force unstable idle for the entire # `loose_ticks` window even when the **floor** is level — e.g. idle on a flat approach tread @@ -737,7 +745,7 @@ static func idle_support_is_stable( # proximity to a riser on an otherwise flat tread. if ( loose_ticks > 0 - and idle_slide_contacts_are_ridged(slide_normals) + and ridged and floor_normal.dot(Vector3.UP) < IDLE_RIM_MIN_FLOOR_UP_DOT ): return false