acdream/docs/research/2026-07-31-cell-availability-semantics.md

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:

  1. no visible cell payload is loaded;
  2. a malformed raw/prepared payload has no containment root;
  3. 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 CellBSP objects, 0 null CellBSP.Root, 729,888 valid roots;
  • prepared acdream.pak: 0 missing aliases, 0 corrupt payloads, 0 ContainmentBsp.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::GetVisible resolves the active seed at 0x0052B50C..0x0052B515;
  • the outdoor branch still calls CLandCell::add_all_outside_cells at 0x0052B53F, even when that seed lookup returned null;
  • the complete growing-array transit walk and containing-cell pick are gated by seed != null && num_spheres != 0 at 0x0052B576;
  • 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

  • PhysicsDataCache publishes 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.HasCellContainment tests Root / RootIndex.
  • Both raw and prepared EnvCell.PointInCell paths apply the zero-portals guard before containment. CellTransit applies the same guard to its CellPhysics representation.
  • CellTransit.BuildShadowCellSet still seeds all overlapped outdoor cells, but skips the transit walk when the active outdoor seed cannot be resolved from CellGraph. Every later outdoor candidate independently resolves via GetVisible before 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.