fix(physics): port retail slope landing stop
This commit is contained in:
parent
1d8371dbe5
commit
5a0f9868a6
13 changed files with 870 additions and 103 deletions
|
|
@ -142,7 +142,7 @@ remain in place (ride ACDREAM_DUMP_MOTION=1) until the user gate passes.
|
|||
|
||||
## #269 — Slope-stop slide runs too far (post-bounce-rework residual)
|
||||
|
||||
**Status:** OPEN (user live gate 2026-07-30 — "almost pass with merits")
|
||||
**Status:** DONE — 2026-07-31 (implementation + user live gate)
|
||||
**Severity:** LOW-MEDIUM (feel residual; bounce family otherwise accepted)
|
||||
**Component:** physics / landing slide decay
|
||||
|
||||
|
|
@ -162,14 +162,24 @@ cos(10°) with base 0.2); the jump chain end-to-end (`GetJumpHeight`
|
|||
Sledding auto-toggle (P2 finding re-confirmed; no `state |= 0x800000`
|
||||
writer exists).
|
||||
|
||||
**Next step (behavior question, not code):** live A/B per the cdb
|
||||
workflow — breakpoints on `calc_friction`/`handle_all_collisions` dumping
|
||||
velocity per tick while the retail client lands + slides on a slope, vs an
|
||||
`ACDREAM_CAPTURE_RESOLVE` capture of the same maneuver on the same slope.
|
||||
Compare the decay curves; the first diverging tick names the mechanism.
|
||||
Candidates the trace discriminates: hop-chain cadence (friction skips
|
||||
airborne micro-hop ticks), gravity-tangential rebuild timing, quantum
|
||||
alignment.
|
||||
**Resolution (2026-07-31):** a 2,184-quantum live capture isolated the
|
||||
first divergence. The landing tick produced retail's correct 5% reflect,
|
||||
but the following quanta repeatedly restored
|
||||
`LastKnownContactPlane` while retaining the reflected velocity. The body
|
||||
therefore remained Contact + OnWalkable with `v·n > 0.25`, where retail
|
||||
`calc_friction` intentionally does no work, and slid at full speed.
|
||||
|
||||
Named-retail `CTransition::validate_transition @ 0x0050AA70` revealed the
|
||||
omission: its non-OK remembered-plane recovery calls
|
||||
`OBJECTINFO::kill_velocity @ 0x0050CFE0` *before* the proximity test and
|
||||
plane restore (`0x0050AAED–0x0050AB42`). It also consumes the remembered
|
||||
plane only in that non-OK branch and overwrites last-known validity from
|
||||
the final contact plane at `0x0050ACFF`. ACDream now follows that exact
|
||||
ordering. Focused collision-recovery and clean-advance pins pass; full
|
||||
Core (4,107/2 skips) and Runtime (439/0) suites pass; the user repeated the
|
||||
slope-jump test and accepted the result (“Perfect! Works great!”).
|
||||
Capture and decode:
|
||||
`docs/research/2026-07-31-269-slope-stop-capture.md`.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -46,12 +46,14 @@ a ledger pass. Goal: zero physics TS rows, no unargued feel-affecting AP
|
|||
rows, one final batched connected visual matrix. Sonnet implements, Opus
|
||||
reviews. The plan is
|
||||
[`2026-07-29-physics-parity-campaign.md`](2026-07-29-physics-parity-campaign.md).
|
||||
The 2026-07-31 #268 stat-chain package is implemented pending its live visual
|
||||
gate: panel and Runtime movement share retail's complete augmentation ordering,
|
||||
The 2026-07-31 #268 stat-chain package is implemented and user-accepted:
|
||||
panel and Runtime movement share retail's complete augmentation ordering,
|
||||
the authored per-fragment vitae/buff/debuff colors are live, and AP-127 plus
|
||||
TS-8 are retired by focused and end-to-end packet tests. The remaining
|
||||
implementation target is #269's capture-driven slope-slide feel residual,
|
||||
followed by the unfinished live matrix rows.
|
||||
TS-8 are retired by focused and end-to-end packet tests. #269's
|
||||
capture-driven slope-slide residual is also closed and user-accepted:
|
||||
`CTransition::validate_transition` now performs retail's non-OK-only
|
||||
remembered-plane restore with the preceding `OBJECTINFO::kill_velocity`.
|
||||
Campaign P now continues with the unfinished live matrix rows.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -380,13 +380,19 @@ root-caused, retail-ported, and user-accepted in the same session:
|
|||
authored 0x1B palette exactly: #7FFFFF vitae, #00FF00 buff, #FF0000
|
||||
debuff. TS-8 is also retired: a real live 0x02C2 payload carries its full
|
||||
StatMod through dispatch and changes the effective skill immediately.
|
||||
- **#269 filed** — slope-stop slide sometimes runs long. `calc_friction`
|
||||
(0x0050ee70) and the complete jump chain (`GetJumpHeight` 0x006b09b0,
|
||||
`InqJumpVelocity` vz=sqrt(h·19.6), 1.0 s/0.8 s powerbar charge) are
|
||||
byte-verified identical — the user's jump-height hypothesis is
|
||||
refuted; next step is the live cdb A/B decay-curve trace.
|
||||
- **#269 closed 2026-07-31** — the live 2,184-quantum trace proved the
|
||||
landing reflect and friction math were correct. ACDream omitted retail's
|
||||
`OBJECTINFO::kill_velocity` before restoring a remembered contact plane
|
||||
in `CTransition::validate_transition @ 0x0050AA70`, retaining full
|
||||
downhill velocity while repeatedly re-grounding the mover. The exact
|
||||
non-OK-only restore/kill order and final last-known validity overwrite
|
||||
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`.
|
||||
|
||||
Matrix rows accepted so far: speed parity, roof slide, downhill bounce,
|
||||
flat pop, uphill landing (rows 3/4/5-partial/12-partial). Remaining
|
||||
rows: 1, 2, 6, 7, 8, 9, 10, 11 plus #269's slide feel. Suite at this
|
||||
checkpoint: 10,031 passed / 5 skips / 0 failures.
|
||||
flat pop, uphill landing, and #269's slope-stop feel
|
||||
(rows 3/4/5-partial/12-partial). Remaining rows: 1, 2, 6, 7, 8, 9, 10,
|
||||
and 11. The #269 checkpoint passes 4,107 Core tests / 2 skips and 439
|
||||
Runtime tests / 0 skips; the complete Release suite passes 10,061 tests /
|
||||
5 skips / 0 failures.
|
||||
|
|
|
|||
104
docs/research/2026-07-31-269-slope-stop-capture.md
Normal file
104
docs/research/2026-07-31-269-slope-stop-capture.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# Issue #269 — slope-stop capture and retail correction
|
||||
|
||||
**Date:** 2026-07-31
|
||||
**Status:** implemented; user live gate passed
|
||||
**Scope:** landing-bounce follow-up, `CTransition::validate_transition`
|
||||
|
||||
## Symptom
|
||||
|
||||
After the retail 5%-elasticity landing reflection was restored for #265,
|
||||
the character could retain too much downhill speed after landing on a
|
||||
walkable slope. The user described the residual as “slides too far on
|
||||
landing.”
|
||||
|
||||
## ACDream live capture
|
||||
|
||||
`ACDREAM_CAPTURE_PLAYER_QUANTA=<jsonl-path>` records the local player's
|
||||
complete admitted object quantum without changing simulation order:
|
||||
|
||||
1. quantum start;
|
||||
2. root/PositionManager composition;
|
||||
3. pre- and post-`UpdatePhysicsInternal`;
|
||||
4. transition result;
|
||||
5. final collision-response commit.
|
||||
|
||||
The accepted repro contained 2,184 quanta. The clearest landing was:
|
||||
|
||||
| Quantum | Event | Velocity |
|
||||
|---|---|---|
|
||||
| 1740 | final airborne quantum | `(-12.316, 8.187, -26.266)` |
|
||||
| 1741 | slope collision, normal `(-0.236, 0.236, 0.943)` | |
|
||||
| 1741 post-response | correct 5% reflect | `(-17.391, 13.262, -6.576)` |
|
||||
| 1742–1758 | still Contact + OnWalkable, no new collision normal | velocity unchanged |
|
||||
| 1759+ | contact relationship changes | friction finally begins decaying |
|
||||
|
||||
The reflected velocity had `dot(v, normal) = +1.0252`: it pointed away
|
||||
from the slope. Retail `calc_friction` correctly skips while this value is
|
||||
at least `0.25`, so friction was not the defect. ACDream was repeatedly
|
||||
restoring the remembered slope plane and re-grounding the body without
|
||||
performing retail's accompanying velocity stop.
|
||||
|
||||
## Retail oracle
|
||||
|
||||
Named-retail:
|
||||
|
||||
- `CPhysicsObj::check_contact` `0x0050F5B0`
|
||||
- `CPhysicsObj::get_object_info` `0x00511CC0`
|
||||
- `CTransition::validate_transition` `0x0050AA70`
|
||||
- `OBJECTINFO::kill_velocity` `0x0050CFE0`
|
||||
|
||||
The exact `validate_transition` order at
|
||||
`0x0050AAED–0x0050AB42` is:
|
||||
|
||||
1. enter only for a non-OK collision/adjusted/slid result;
|
||||
2. if `last_known_contact_plane_valid`, call
|
||||
`OBJECTINFO::kill_velocity`;
|
||||
3. test the current sphere center against the remembered plane using
|
||||
`radius + 0.0002`;
|
||||
4. restore the contact plane only when still within that distance;
|
||||
5. later, at `0x0050ACFF`, overwrite last-known validity with final
|
||||
contact-plane validity.
|
||||
|
||||
`OBJECTINFO::kill_velocity` calls
|
||||
`CPhysicsObj::set_velocity({0,0,0}, 0)`. ACDream had ported the proximity
|
||||
test and plane restore but omitted this call. It also allowed the
|
||||
last-known plane to re-ground clean accepted moves, although retail only
|
||||
consumes it in the non-OK recovery branch.
|
||||
|
||||
## Correction
|
||||
|
||||
`Transition.ValidateTransition` now:
|
||||
|
||||
- calls `ObjectInfo.StopVelocity()` before the remembered-plane
|
||||
proximity/restore test on a non-OK recovery;
|
||||
- performs that restore only in the retail branch;
|
||||
- overwrites last-known validity from final contact validity, so a clean
|
||||
move away cannot be re-grounded from stale memory.
|
||||
|
||||
The existing `PhysicsEngine.ResolveWithTransition` consumption of
|
||||
`VelocityKilled` applies the zero to the canonical `PhysicsBody` before
|
||||
the collision-response tail. The initial 5% landing reflection remains;
|
||||
only a following collision recovery performs the retail stop.
|
||||
|
||||
## Gates
|
||||
|
||||
- New focused pins:
|
||||
- collision recovery with a remembered plane kills velocity;
|
||||
- clean advance with a remembered plane neither kills nor re-grounds.
|
||||
- Full `AcDream.Core.Tests`: 4,107 passed / 2 skipped.
|
||||
- Full `AcDream.Runtime.Tests`: 439 passed.
|
||||
- `AcDream.App` Release build: 0 warnings / 0 errors.
|
||||
- Complete Release suite: 10,061 passed / 5 skipped / 0 failed.
|
||||
- User live gate: **PASS** — repeated slope jumps now settle correctly
|
||||
(“Perfect! Works great!”).
|
||||
|
||||
## Diagnostic tools retained
|
||||
|
||||
- `tools/analyze_269_slope_stop_capture.py`
|
||||
- `tools/cdb/run-issue269-slope-stop.ps1`
|
||||
- `tools/cdb/issue269-slope-stop.cdb`
|
||||
|
||||
The cdb runner refuses to attach unless the live retail executable matches
|
||||
the Sept 2013 named PDB. The locally installed 2015 retail executable does
|
||||
not match; the static named-retail decode above is therefore the retail
|
||||
oracle used for this correction.
|
||||
Loading…
Add table
Add a link
Reference in a new issue