docs: #334 measured in game — a landblock-spanning object is registered by one sphere
The reach-filter theory I proposed is REFUTED by measurement, and the real cause is found. Probe evidence committed as 334-neftet-probe.log (8,401 lines, ACDREAM_PROBE_REACH atb61f5fd4). Standing INSIDE the formation, the collision system reports inCell=2 exempt=2 reached=0 rejectedReach=0 — two candidates, both the player's own body spheres. Nothing was rejected because nothing was there. That kills AP-158 as the cause: the formation is not in the candidate set at all. The blocking part the user found is what makes it diagnostic. One object does collide — gfx=0x010046D8, a BSP with objR=69.471, the landblock's baked rock geometry — and it appears in cells 0x8764000A and 0x87640012 while being absent from 0x87640011, 0x87640019 and 0x87630018. Same object, same landblock, present in one cell and missing from the one directly beside it (grid (2,1) versus (2,0)). Cause: BuildFloodSpheres derives cell membership from a single bounding sphere per part. A 69.471 m radius cannot reach every cell of a 192 m landblock, so cells beyond it get no registration and the player walks through. Retail does not use a sphere here — calc_cross_cells 0x00515230 routes BSP objects to find_bbox_cell_list 0x00510fc0 -> calc_cross_cells_static 0x00518160, a walk over the object's extent. Recorded explicitly because the null result was misleadable: AP-156 (b52967de) did NOT fix this and was never going to. AP-156 corrected the sphere's POSITION; this is about its COVERAGE. Sequential halves of one weakness, not competing explanations — and without that note the next reader would reasonably conclude AP-156 had failed. Process note worth keeping: I proposed the reach filter, and a DAT sweep would have "confirmed" it by finding exactly the oversized objects I predicted. The user insisted on measuring in game instead, which produced the opposite answer in one run. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b61f5fd4fc
commit
f0588725cf
1 changed files with 52 additions and 1 deletions
|
|
@ -10575,7 +10575,58 @@ did **not** resolve it either, which is itself a diagnostic clue (see below).
|
|||
formations, and no floor above it — jumping over lands you inside/through.
|
||||
"Solid near the middle, absent at the edges" is the shape to reason from.
|
||||
|
||||
### Leading candidate — AP-158 / #333, the broadphase reach filter
|
||||
### MEASURED IN GAME 2026-08-06 — cause found, and it is NOT the reach filter
|
||||
|
||||
**The reach-filter theory is REFUTED.** A live probe (`ACDREAM_PROBE_REACH`,
|
||||
commit `b61f5fd4`) was run with the user standing in front of, and then inside,
|
||||
a Neftet formation. Evidence: `334-neftet-probe.log`, 8,401 lines.
|
||||
|
||||
Standing inside the formation the collision system reported:
|
||||
|
||||
```
|
||||
[reach-q] cell=0x87640019 inCell=2 exempt=2 reached=0 rejectedReach=0 tested=0 blocked=0
|
||||
```
|
||||
|
||||
**Two candidates, both the player's own body spheres.** Nothing was rejected
|
||||
because there was nothing to reject — the formation is not in the collision
|
||||
candidate set at all. `rejectedReach=0` kills AP-158 as the cause here.
|
||||
|
||||
**The blocking part the user found is the discriminator.** One object does
|
||||
collide: `gfx=0x010046D8`, a BSP with `objR=69.471` — the landblock's baked
|
||||
rock geometry, one object spanning a large area. Its coverage:
|
||||
|
||||
| Cell | Rock object present? |
|
||||
|---|---|
|
||||
| `0x8764000A`, `0x87640012` | **YES** — `tested-collided` / `tested-slid`, player blocked |
|
||||
| `0x87640011`, `0x87640019`, `0x87630018` | **NO** — `inCell=2`, both entries the player |
|
||||
|
||||
**Same object, same landblock, present in some cells and absent from directly
|
||||
adjacent ones.** `0x87640012` is cell index 17 → grid (2,1); `0x87640011` is
|
||||
index 16 → grid (2,0), immediately beside it and empty.
|
||||
|
||||
### Cause: a landblock-spanning object is registered by a single bounding sphere
|
||||
|
||||
`ShadowObjectRegistry.BuildFloodSpheres` derives cell membership from one
|
||||
sphere per part. This object's own radius is **69.471 m** while a landblock is
|
||||
**192 m** across, so a single sphere cannot geometrically reach every cell the
|
||||
mesh occupies. Cells beyond its reach receive no registration and the player
|
||||
walks through.
|
||||
|
||||
Retail does not use a sphere here. `CPhysicsObj::calc_cross_cells` @`0x00515230`
|
||||
routes BSP-bearing objects to `find_bbox_cell_list` @`0x00510fc0` →
|
||||
`calc_cross_cells_static` @`0x00518160`, i.e. a walk over the object's
|
||||
**extent**, not a single enclosing sphere.
|
||||
|
||||
**Relationship to AP-156 (`b52967de`), which did not fix this and was not
|
||||
expected to:** AP-156 moved the flood sphere to the right *place* (it was
|
||||
centred on the part origin while sized from the geometry). That was necessary
|
||||
and is confirmed correct — but the sphere is also the wrong *shape* for objects
|
||||
whose extent exceeds their own radius. AP-156 fixed position; this issue is
|
||||
about coverage. Sequential, not alternative.
|
||||
|
||||
### Superseded — the original leading candidate, retained for provenance
|
||||
|
||||
### Superseded detail — AP-158 / #333, the broadphase reach filter
|
||||
|
||||
`TransitionTypes.cs:3898`-ish measures `currPos - obj.Position` (the part
|
||||
**origin**) against `obj.Radius`, admitting a contact only when the geometry
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue