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

2.8 KiB

Retail cell availability and null-root containment — 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 bug was one collapsed state. acdream treated all three of these as “containment unavailable”:

  1. no visible cell payload is loaded;
  2. a loaded CellStruct has a null containment root;
  3. a loaded CellStruct has an authored containment root.

Retail distinguishes (1) from (2). A failed visible-cell lookup is unavailable. A loaded CellStruct remains a real cell even when its BSPTREE root is null, and the containment query's null-node base case is inside.

Retail oracle

CObjCell::find_cell_list @ 0x0052B4E0 in docs/research/named-retail/acclient_2013_pseudo_c.txt:308742 establishes the availability gate:

  • 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.

CCellStruct::point_in_cell @ 0x005338F0 delegates directly to BSPTREE::point_inside_cell_bsp @ 0x005398C0. The already-ported graph and flat BSP queries preserve the retail null-root base case: a negative/null root returns true. Root presence is therefore not an availability predicate.

Ported behavior

  • PhysicsDataCache now publishes a CellPhysics record whenever an authored raw or prepared CellStruct payload exists, even if its physics BSP and/or containment BSP root is absent.
  • CollisionTraversal.HasCellContainment tests representation payload availability, not Root / RootIndex. PointInsideCell then lets the graph or flat query return true for the null-root base case.
  • CellTransit.BuildShadowCellSet still seeds all overlapped outdoor cells, but skips the transit walk when the active outdoor seed cannot be resolved from CellGraph. A separately cached building can no longer promote an object through an unavailable landcell.
  • The existing reflood lifecycle remains the recovery mechanism. Once terrain or an indoor CellStruct publishes, the next reflood walks the same authored portal/building relationships without reconstructing a different rule.

Gates

Focused tests cover raw graph and prepared flat cache publication, absent versus loaded-null-root containment, indoor and outdoor seeds, preservation of outside-cell seeding, suppression of spurious building promotion, and hydration/reflood recovery. Final Release gates passed: Core 4,162 / 1 skipped, Runtime 440 / 0 skipped, App 4,002 / 3 skipped, plus the complete solution build with zero errors.