95 lines
4.2 KiB
Markdown
95 lines
4.2 KiB
Markdown
# Issue #273 — Holtburg tight-gap support validation
|
|
|
|
**Date:** 2026-07-31
|
|
**Status:** implementation, automated gates, and exact live gate pass
|
|
**Scope:** grounded player step-down support at a floor edge beside a static
|
|
cylinder
|
|
|
|
## Captured scene
|
|
|
|
The reproducible gap is in outdoor cell `0xA9B40032`, between:
|
|
|
|
- building shell GfxObj `0x01000F69`, placed at
|
|
`(158.178, 37.7055, 94.0)` with quaternion
|
|
`(w=.939319, x=0, y=0, z=-.343045)`;
|
|
- static post `0xCA9B4027`, placed at `(160.173, 34.487, 95.975)`,
|
|
represented by its Setup-authored cylinder (`radius=.282`,
|
|
`height=5.564`);
|
|
- the local player Setup's exact two spheres (`radius=.48`, origins
|
|
`z=.475` and `z=1.35`).
|
|
|
|
The building's supporting ledge terminates at local `x=4`. The first
|
|
post-side response moved the player's foot-sphere center to approximately
|
|
local `x=4.33`. The full `.48` movement sphere still overlapped the floor, so
|
|
the existing step-down path accepted the candidate. Repeated frames then
|
|
carried the player around the post and outside the building shell.
|
|
|
|
The fixture
|
|
`tests/AcDream.Core.Tests/Fixtures/issue273/0x01000F69.gfxobj.json` preserves
|
|
the installed DAT PhysicsBSP. The replay in
|
|
`Issue273HoltburgTightGapReplayTests` uses the captured object placement,
|
|
player spheres, static posts, and movement offsets.
|
|
|
|
## Retail mechanism
|
|
|
|
The missing rule is not extra collision padding and is not a larger player
|
|
sphere. It is retail's second-stage support validation:
|
|
|
|
1. `CTransition::step_down` (`0x0050B2A0`) performs the ordinary downward
|
|
collision probe.
|
|
2. After finding a walkable contact plane, an EdgeSlide mover that is not in
|
|
StepUp calls `CTransition::check_walkable` (`0x0050AFF0`). The binary
|
|
sequence is `test ah,2` at `0x0050B36A`, which is state bit `0x200`
|
|
(`EdgeSlide`), followed by the `step_up == 0` test and call at
|
|
`0x0050B380`.
|
|
3. `CTransition::check_walkable` first calls
|
|
`SPHEREPATH::check_walkables` (`0x0050C3E0`).
|
|
4. `SPHEREPATH::check_walkables` halves the saved foot-sphere radius and
|
|
calls `CPolygon::check_walkable` (`0x00538E60`).
|
|
5. If the remembered polygon does not support that smaller sphere,
|
|
`CTransition::check_walkable` performs a downward CheckWalkable insertion.
|
|
BSP leaves require both `walkable_hits_sphere` and
|
|
`CPolygon::check_small_walkable` (`BSPLEAF::hits_walkable`,
|
|
`0x0053D670`).
|
|
6. If neither check finds support, `CTransition::step_down` rejects the
|
|
candidate and the existing edge-response chain handles it.
|
|
|
|
ACDream already had the small-radius BSP-leaf test, but
|
|
`DoCheckWalkable` treated the mere presence of a remembered polygon as
|
|
success, and the ordinary `DoStepDown(..., runPlacement:false)` path never
|
|
called it. This let a full-radius overlap stand in for actual foot support.
|
|
|
|
## Port
|
|
|
|
- `BSPQuery.CheckWalkableSupport` is the shared resolved-polygon form of
|
|
retail `CPolygon::check_walkable`.
|
|
- `SpherePath.CheckWalkables` implements the retail half-radius remembered
|
|
polygon check without mutating canonical sphere state.
|
|
- `Transition.DoCheckWalkable` now tests the remembered polygon rather than
|
|
treating a non-null polygon as sufficient.
|
|
- `Transition.DoStepDown` restores the EdgeSlide/non-StepUp support gate
|
|
before the existing placement-policy seam.
|
|
|
|
There are no location checks, object IDs, guessed radii, widened collision
|
|
shapes, or gap-specific tolerances in the production fix.
|
|
|
|
## Regression impact
|
|
|
|
The existing #271 staircase-side replay begins with its center `.288 m`
|
|
outside a tread whose retail half-radius support boundary is `.24 m`.
|
|
Retail may therefore stop that exact candidate. The test now preserves the
|
|
original user-visible invariant—never reverse or accelerate downhill—without
|
|
requiring forward progress beyond retail's support boundary. The ordinary
|
|
continuous staircase replay still requires and achieves forward progress.
|
|
|
|
## Gates
|
|
|
|
- issue #273 fixture/replay: 3 passed;
|
|
- focused BSP, step-up, edge-slide, #185/#271 family: 42 passed / 1 skipped;
|
|
- complete Core tests: 4,111 passed / 2 skipped;
|
|
- Release solution build: passed;
|
|
- complete Release solution tests: 10,068 passed / 5 skipped.
|
|
|
|
The user accepted the exact in-client Holtburg gap gate on 2026-07-31: the
|
|
gap blocks from the tested approach, and the adjacent movement checks remain
|
|
healthy.
|