4.2 KiB
Retail cell availability and containment-root validation — 2026-07-31
Scope
This note closes divergence rows AD-3 and AD-4. It does not begin AD-6's atomic streaming-generation work.
The corrected port distinguishes these states:
- no visible cell payload is loaded;
- a malformed raw/prepared payload has no containment root;
- a loaded CellStruct has a valid authored containment root (its physics root may independently be absent).
Only (3) is published. State (1) remains unavailable and retryable. State (2) is quarantined atomically so a later valid hydration can retry; it must not become a world-wide containing cell.
Installed-data audit
The complete installed EoR catalog and matching prepared package were audited before choosing this invariant:
- enumerated EnvCells: 729,888;
- raw: 0 missing EnvCells, 0 missing Environments, 0 missing CellStructs,
0 null
CellBSPobjects, 0 nullCellBSP.Root, 729,888 valid roots; - prepared
acdream.pak: 0 missing aliases, 0 corrupt payloads, 0ContainmentBsp.RootIndex < 0, 729,888 valid roots; - 6,940 raw EnvCells have zero portals, so the retail portal-pointer guard is a real catalog path rather than dead defensive code.
There are therefore no root-null record IDs to preserve in either source.
Retail oracle
CObjCell::find_cell_list @ 0x0052B4E0 in
docs/research/named-retail/acclient_2013_pseudo_c.txt:308742 establishes the
availability gates:
CEnvCell::GetVisible/CLandCell::GetVisibleresolves the active seed at0x0052B50C..0x0052B515;- the outdoor branch still calls
CLandCell::add_all_outside_cellsat0x0052B53F, even when that seed lookup returned null; - the complete growing-array transit walk and containing-cell pick are gated
by
seed != null && num_spheres != 0at0x0052B576; - each later candidate is independently skipped when its stored cell pointer
is null at
0x0052B58E.
CEnvCell::point_in_cell @ 0x0052C300 first returns false when
this->portals == 0, then transforms the point and calls
CCellStruct::point_in_cell.
CCellStruct::point_in_cell @ 0x005338F0 calls
BSPTREE::point_inside_cell_bsp @ 0x005398C0, which immediately invokes
BSPNODE::point_inside_cell_bsp(this->root_node, ...). The BSP node method at
0x0053C1F0 dereferences this before walking positive children. Only a
missing positive child below a valid root is the inside terminal case. A
missing root is not.
Ported behavior
PhysicsDataCachepublishes graph, collision, and prepared records only after a valid raw/prepared containment root is present. A missing physics root is retained as a valid non-colliding cell. Invalid containment publication changes no cache, so later hydration can retry.CollisionTraversal.HasCellContainmenttestsRoot/RootIndex.- Both raw and prepared
EnvCell.PointInCellpaths apply the zero-portals guard before containment.CellTransitapplies the same guard to itsCellPhysicsrepresentation. CellTransit.BuildShadowCellSetstill seeds all overlapped outdoor cells, but skips the transit walk when the active outdoor seed cannot be resolved fromCellGraph. Every later outdoor candidate independently resolves viaGetVisiblebefore building transit, so a stale building cannot promote an object through an unavailable adjacent landcell.- The existing reflood lifecycle remains the recovery mechanism. Once terrain or a valid indoor CellStruct publishes, the next reflood walks the authored portal/building relationships without reconstructing a different rule.
Gates
Focused tests cover raw/prepared rootless quarantine and valid retry, valid containment with missing physics, raw/prepared zero-portal parity, indoor and outdoor seeds, preservation of outside-cell seeding, per-candidate adjacent landcell availability, suppression of stale-building promotion, and hydration/reflood recovery. The corrective checkpoint passes:
- focused cell-availability suite: 54/54;
- Core Release: 4,165 passed / 1 skipped;
- Runtime Release: 440/440;
- App Release: 4,002 passed / 3 skipped;
- complete Release solution: 10,122 passed / 4 skipped;
dotnet build AcDream.slnx -c Release: 0 warnings / 0 errors.