diff --git a/docs/ISSUES.md b/docs/ISSUES.md index d991f721..4ed75097 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -10554,6 +10554,67 @@ missing is the plugin-API surface. --- +## #334 — Large static formations lose collision at their boundaries (Neftet) + +**Status:** OPEN +**Severity:** HIGH — walk-through and fall-through on world geometry. +**Filed:** 2026-08-06, user-reported in live play. +**Component:** physics / collision / broadphase + +**User report, verbatim in substance:** *"In Neftet I miss collision on the +large stone formations. I can run up to them, but then at a boundary between +I can run through. I can jump over it but then I just fall through."* + +**NOT a regression from the 2026-08-06 collision work.** Confirmed by A/B: the +user reproduced it on a purpose-built client at `52175aa1` — before AP-22, +AP-152, AP-156, AD-10 and #276's remainder — and the behaviour was identical. +It is pre-existing and was simply never filed. AP-156's cell-membership fix +did **not** resolve it either, which is itself a diagnostic clue (see below). + +**The signature:** solid on approach, permeable at a boundary *between* two +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 + +`TransitionTypes.cs:3898`-ish measures `currPos - obj.Position` (the part +**origin**) against `obj.Radius`, admitting a contact only when the geometry +sits within roughly `movement + 2 m` of that origin. Retail has **no distance +pre-filter at all**: `CObjCell::find_obj_collisions` @`0x0052b750` dispatches +unconditionally, its only early-out being `INITIAL_PLACEMENT_INSERT`. The 2 m +slack is acdream invention; retail's own epsilon in this family is 0.0002 m. + +**118 of 477 unique BSP GfxObjs exceed that ~2.5 m budget; 46 exceed 5 m.** A +"large stone formation" is precisely the class that would: geometry extending +many metres from its part origin. Near the origin you collide; past the budget +the broadphase rejects the object before its mesh is ever consulted — solid in +the middle, permeable at the edges, no floor overhead. That matches the report +without needing a second mechanism. + +This also explains why AP-156 did not help: AP-156 put the object in the right +**cells**; AP-158 is why it is still rejected *within* those cells. AP-156 was +a prerequisite, not a cure — the two are sequential, and this issue is the +observable that proves the second half still bites. + +### Second candidate, if the first is disproved + +Static-object collision registration at EnvCell seams — the per-cell shadow +list family (#98's architecture, closed `b3ce505`, and #137's door/wall-opening +work, closed 2026-07-08). Both are closed, so this would be a new gap rather +than a regression of either. + +### How to settle it + +1. Identify the specific Setup/GfxObj of a Neftet formation that reproduces, + and measure its BSP root-sphere origin offset. If it exceeds ~2.5 m, AP-158 + is confirmed as the cause and this issue closes with AP-158's fix. +2. If the offset is small, the reach filter is exonerated and the second + candidate takes over. + +**Do not attempt a fix before step 1.** The reach filter's `+ 2f` slack has no +retail counterpart, so "widen the budget" would be tuning an invented constant +— the fix is to remove the filter, which needs AP-158's own gate. + ## #32 — Retail edge-slide / cliff-slide / precipice-slide incomplete **Status:** REMOTE HALF CLOSED — fixed `204d0ae0`, **user-passed 2026-08-04**