acdream/docs/research/2026-08-30-cathedral-review-datformat.md
Erik 6d990d38b3 docs: the cathedral seven-report synthesis + adjudicated FW4 plan
Files the independent review corpus (fable/opus/external + audit,
DAT-format, F418 DAT-geometry, retail decomp reconstruction) and the
synthesis that adjudicates their disagreements: retail roots INTERIOR
at the posed terrace defect pose with a ONE-CELL flood and ov=1 (the
free captures rooted outdoor - both were real); the falls are outdoor
landblock emitters 0xCF418000-13; the "thin seam bands" claim is
DAT-refuted (full-size exits; the seam is a coincident double
exit-to-outside plane at y=48); clear+seals live inside retail''s ov>0
block with a one-frame seal latch. Carries the instrument-first plan
(falls-owner trace, depth checkpoints, pose conformance) and the
decomp-pinned repair sequence toward FW4''s single-owner goal.

Also sweeps in the probe scaffolding slice 5''s path-limited add had
missed (RenderingDiagnostics field + the launch-options row wording).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 20:52:14 +02:00

4.6 KiB
Raw Blame History

Cathedral review — DAT-format facts (companion report)

Delivered 2026-08-30 by the DAT-format verification agent (decompiled the actual Chorizite.DatReaderWriter 2.1.7 NuGet binary with ilspycmd and cross-checked against docs/research/named-retail/acclient.h). Key facts for the cathedral synthesis; flagged caveats preserved.

Sourcing caveats

  • Our DAT parser is the CONSUMED NuGet Chorizite.DatReaderWriter 2.1.7 (no vendored source; facts below come from decompiling the exact linked DLL).
  • references/WorldBuilder is an uninitialized submodule in THIS worktree (read from the main worktree at a different SHA — flagged).
  • references/ACViewer does not exist in either worktree (claims about ACViewer: UNVERIFIED).

EnvCell record (read order, decompiled Unpack)

Flags (int) → self-Id (uint, duplicate) → NumSurfaces (byte) → NumPortals (byte) → NumVisibleCells (ushort) → Surfaces[]ushort) → EnvironmentId (ushort) → CellStructure (ushort) → Position (Frame) → CellPortals[] → VisibleCells[] (ushort) → [HasStaticObjs 0x2] StaticObjects (count + Stab{Id,Frame}[]) → [HasRestrictionObj 0x8] RestrictionObj.

EnvCellFlags: SeenOutside=0x1, HasStaticObjs=0x2, HasRestrictionObj=0x8. 0x4 is unclaimed.

Retail cross-check: CEnvCell : CObjCell (acclient.h:32072-32091) maps 1:1; retail's stab_list lives on the BASE CObjCell (acclient.h:30914-30932) and is the PVS list of CELL IDS — NOT placed objects. The DatReaderWriter Stab{Id,Frame} placed-object struct is a coincidental homonym (zero matches for Stab in the named-retail header).

CellPortal / BuildingPortal

CellPortal { PortalFlags Flags; ushort PolygonId; ushort OtherCellId; ushort OtherPortalId; }PortalFlags: ExactMatch=1, PortalSide=2. No 0x4 member anywhere (package, our code, WorldBuilder, and retail's own CCellPortal decode exactly two semantic fields: portal_side, exact_match). NOTE: this contradicts the earlier campaign note "CCellPortal DAT flag 0x4 = leads outside" — the outside link is the OtherCellId == 0xFFFF sentinel, not a flag bit.

  • ExactMatch consumers: PortalVisibilityBuilder.cs:1168-1183 (skips reciprocal clip — decomp:433689), Walk factories (WalkBuildingFactory.cs:76, WalkCellFactory.cs:94).
  • PortalSide convention: (Flags & 0x2) == 0 → normal points INTO the owning cell (CellPortal.cs:23-24, PortalInfo.cs:22-44); WalkCellFactory.cs:93: PortalSide = (Flags & 0x2) != 0 ? 0 : 1.
  • OtherCellId == 0xFFFF = the outdoor-exit sentinel (18+ consumers); the walk world remaps it to 0xFFFFFFFFu.

BuildingPortal (BuildingInfo.Portals) is a DISTINCT dat type — carries its own packed StabList of cell ids (retail CBldPortal with num_stabs/stab_list + sidedness). The walk's WalkBuildingFactory.cs:81 reads it directly; the older Wb.BuildingLoader path DISCARDS it and recomputes by BFS.

LandBlockInfo

NumCells → Objects[Stab] → Buildings[BuildingInfo{ModelId, Frame, NumLeaves, Portals[BuildingPortal]}] → [flag] RestrictionTable. Confirmed field-for-field; consumer LandblockLoader.cs:69-103.

Water / waterfall (part d)

  • LandDefs::WaterType is COMPUTED client-side from terrain paint (types 0x10-0x14 WaterRunning..WaterDeepSea); AcDream already computes it for physics (TerrainSurface.cs:92-128). It is NOT packed in the records.
  • SurfaceTexture.Textures is a multi-frame list (the structural shape of a flip-book animation) but EVERY consumer in both repos freezes one fixed index (Textures[0], WB [^1]) — no water/texture animation is implemented anywhere; whether retail animates via this list is UNVERIFIED.
  • Which object IS "the waterfall" near the cathedral: UNVERIFIED from source — two old bug comments treat it as OUTDOOR landscape-alpha content (PortalVisibilityBuilder.cs:730-736, RetailPViewRenderer.cs:714-726), consistent with a translucent stab — but note the live probes identified the terrace falls PARTICLE owners as EnvCell StaticObjects of cell 0xF4180106 (ids 4f418012-15), which is the HasStaticObjs list above; both can be true (mesh stab outdoors + emitter stabs in cells).

Notable corrections this report makes to campaign lore

  1. "DAT flag 0x4 = leads outside" (PV campaign memory) — REFUTED: no 0x4 exists; outside = OtherCellId 0xFFFF.
  2. "stab list" ambiguity — retail stab_list = PVS cell ids on CObjCell; placed objects are a different structure; docs/comments conflating the two should be read carefully.
  3. Building portals carry authored per-portal cell StabLists in the dat — the old Wb path recomputes what the dat already provides.