fix(physics): port retail stair edge backprobe
This commit is contained in:
parent
5a0f9868a6
commit
2dcb4f1d94
6 changed files with 218 additions and 6 deletions
|
|
@ -98,6 +98,38 @@ Copy this block when adding a new issue:
|
|||
|
||||
---
|
||||
|
||||
## #271 — Stair-side collision reverses uphill movement and rapidly slides the player down
|
||||
|
||||
**Status:** DONE — 2026-07-31 (implementation + user live gate)
|
||||
**Severity:** MEDIUM (movement feel and navigation)
|
||||
**Component:** physics / `edge_slide` / `precipice_slide`
|
||||
|
||||
**Symptom:** while running diagonally up an outdoor staircase and pressing
|
||||
against its side, the character could suddenly move backward and slide rapidly
|
||||
to the bottom.
|
||||
|
||||
**Root cause:** a 677-quantum live trace caught the first bad frame. A valid
|
||||
X side-wall collision turned a requested `+0.88377` uphill Y displacement into
|
||||
`-0.34059`, followed three frames later by a 1.52 m snap to terrain.
|
||||
`EdgeSlideAfterStepDownFailed` promoted ACDream's separately retained
|
||||
`LastWalkable` polygon into the current `SPHEREPATH::walkable` slot. At the
|
||||
stair side this could be the preceding tread, so `PrecipiceSlide` projected
|
||||
against stale geometry and reversed the tangent.
|
||||
|
||||
Named-retail `CTransition::edge_slide @ 0x0050B3D0` never substitutes an older
|
||||
polygon: when current `walkable` is null it back-probes at the current sphere
|
||||
center, restores the failed candidate, and only then invokes
|
||||
`SPHEREPATH::precipice_slide @ 0x0050CC80`. Both stale-history substitutions
|
||||
are removed. The exact captured frame is pinned against the installed stair
|
||||
fixture: pre-fix output moved downhill to Y `75.346481`, while the retail-flow
|
||||
result advances uphill to Y `76.078186` and Z `60.016247`. Core Release passes
|
||||
4,108 tests / 2 skips; the complete Release solution passes 10,062 tests /
|
||||
5 skips. The user then repeatedly climbed the same stairs while pressing into
|
||||
their sides and confirmed the rapid downhill slide was gone. Evidence:
|
||||
`docs/research/2026-07-31-271-stair-side-slide-capture.md`.
|
||||
|
||||
---
|
||||
|
||||
## #270 — Stuck spell animations + intermittently missing monster attack animations
|
||||
|
||||
**Status:** CLOSED 2026-07-31 — both symptoms user-verified fixed (stuck casts: exhaustion-edge gate `a46c8e65`; missing monster attack animations: spawn settle placement `21b3a3f3` + lost-cell retry `807fdb5f`). Final settle-session log: 14/15 spawn settles grounded; Falling-refusal spam 2,954 → 15 transient pre-settle lines. All #270 probes stripped.
|
||||
|
|
|
|||
|
|
@ -389,6 +389,16 @@ root-caused, retail-ported, and user-accepted in the same session:
|
|||
are now ported, focused/full gates pass, and the user accepted repeated
|
||||
slope jumps. Evidence:
|
||||
`docs/research/2026-07-31-269-slope-stop-capture.md`.
|
||||
- **#271 closed 2026-07-31** — a bounded stair-side
|
||||
trace proved ACDream could bypass retail's current-position edge back-probe
|
||||
by promoting a stale `LastWalkable` tread. That made PrecipiceSlide reverse
|
||||
an uphill tangent and rapidly carry the player down the stairs. The two
|
||||
stale-history substitutions are removed; current-walkable, back-probe, and
|
||||
no-walkable outcomes now follow `CTransition::edge_slide @ 0x0050B3D0`.
|
||||
The exact captured frame is pinned in the existing installed-stair fixture
|
||||
and the complete Release suite passes 10,062 tests / 5 skips. The user
|
||||
accepted repeated uphill runs while pressing into the stair sides. Evidence:
|
||||
`docs/research/2026-07-31-271-stair-side-slide-capture.md`.
|
||||
|
||||
Matrix rows accepted so far: speed parity, roof slide, downhill bounce,
|
||||
flat pop, uphill landing, and #269's slope-stop feel
|
||||
|
|
|
|||
108
docs/research/2026-07-31-271-stair-side-slide-capture.md
Normal file
108
docs/research/2026-07-31-271-stair-side-slide-capture.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# #271 — Stair-side uphill reversal capture
|
||||
|
||||
**Date:** 2026-07-31
|
||||
|
||||
**Status:** closed; retail control flow restored and user live gate passed
|
||||
|
||||
## Symptom
|
||||
|
||||
When the local player ran diagonally uphill while pressing into the side of
|
||||
an outdoor staircase, the character could suddenly move backward and rapidly
|
||||
slide to the bottom. The symptom was intermittent because it required the
|
||||
forward candidate to hit the side wall while the step-down recovery crossed a
|
||||
tread edge.
|
||||
|
||||
This is not an RDP, render-rate, animation, or gravity symptom. It reproduced
|
||||
inside the pure Core collision resolver from one captured input frame.
|
||||
|
||||
## Live evidence
|
||||
|
||||
The bounded capture is under the ignored local artifact pointer:
|
||||
|
||||
`artifacts/issue271-stair-side/LATEST.txt`
|
||||
|
||||
It contains 677 local-player physics quanta plus the matching resolver stream.
|
||||
The first decisive frame is quantum 310:
|
||||
|
||||
```text
|
||||
current = (133.03775, 75.53931, 59.608147)
|
||||
target = (133.33783, 76.42308, 59.608147)
|
||||
input = forward + run
|
||||
result = (133.18779, 75.19872, 59.316677)
|
||||
normal = (-1, approximately 0, approximately 0)
|
||||
```
|
||||
|
||||
The X side-wall collision was valid, but the tangential Y component reversed:
|
||||
an uphill request of `+0.88377` produced `-0.34059`. Three frames later,
|
||||
quantum 313 snapped from Z `59.52598` to terrain Z `58.005`. A second attempt
|
||||
reproduced the same family at quanta 479–482, falling from Z `60.96376` to
|
||||
`58.005`.
|
||||
|
||||
## Retail oracle
|
||||
|
||||
Named retail:
|
||||
|
||||
- `CTransition::edge_slide` at `0x0050B3D0`
|
||||
- current-walkable branch at `0x0050B44A`
|
||||
- no-walkable back-probe at `0x0050B458–0x0050B50F`
|
||||
- `SPHEREPATH::precipice_slide` at `0x0050CC80`
|
||||
|
||||
Retail tests only the current `SPHEREPATH::walkable` pointer. If it is null,
|
||||
retail:
|
||||
|
||||
1. offsets the failed candidate back to the current sphere center;
|
||||
2. runs `step_down` there to rediscover the surface actually under the mover;
|
||||
3. restores the failed candidate;
|
||||
4. runs `precipice_slide` against the newly discovered polygon; or
|
||||
5. returns `COLLIDED_TS` when the back-probe found no walkable polygon.
|
||||
|
||||
Retail has no substitution of an older saved walkable polygon in either null
|
||||
case.
|
||||
|
||||
## ACDream divergence and root cause
|
||||
|
||||
`EdgeSlideAfterStepDownFailed` previously called
|
||||
`SpherePath.RestoreLastWalkable()`:
|
||||
|
||||
- before deciding whether to enter the retail back-probe; and
|
||||
- again when the back-probe found no current walkable polygon.
|
||||
|
||||
`LastWalkable` is a separate ACDream history used by the still-open
|
||||
CliffSlide compatibility path. At a staircase side wall it could describe the
|
||||
preceding tread rather than the surface below the current player position.
|
||||
Promoting it into the current slot bypassed retail's back-probe.
|
||||
`PrecipiceSlide` then projected the failed forward candidate along the stale
|
||||
tread edge, producing the backward/downhill displacement seen in the capture.
|
||||
|
||||
The fix removes both stale-history promotions from the edge-slide dispatch.
|
||||
Current walkable state still takes retail's direct precipice path; absent
|
||||
state now always takes retail's current-position back-probe.
|
||||
|
||||
## Deterministic regression
|
||||
|
||||
`Issue185OutdoorStairsSeamReplayTests` reuses the captured
|
||||
`0x01000AC5` staircase collision fixture and the exact quantum-310 position,
|
||||
contact plane, movement delta, player flags, and 1.5 m Setup step-down height.
|
||||
|
||||
Pre-fix:
|
||||
|
||||
```text
|
||||
out = (133.187790, 75.346481, 59.430882)
|
||||
```
|
||||
|
||||
Fixed:
|
||||
|
||||
```text
|
||||
out = (133.187790, 76.078186, 60.016247)
|
||||
```
|
||||
|
||||
The regression requires meaningful positive uphill progress and forbids a
|
||||
downhill Z displacement. The complete Core Release suite passes 4,108 tests /
|
||||
2 skips; the complete Release solution passes 10,062 tests / 5 skips.
|
||||
|
||||
## Live acceptance
|
||||
|
||||
The user repeatedly ran uphill while pressing into both sides of the affected
|
||||
staircase. Movement remained stable and the former rapid downhill reversal did
|
||||
not recur. The client then closed through the normal logout path, with ACE
|
||||
confirming graceful logout.
|
||||
Loading…
Add table
Add a link
Reference in a new issue