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>
4.6 KiB
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/WorldBuilderis an uninitialized submodule in THIS worktree (read from the main worktree at a different SHA — flagged).references/ACViewerdoes 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 to0xFFFFFFFFu.
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::WaterTypeis 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.Texturesis 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 theHasStaticObjslist above; both can be true (mesh stab outdoors + emitter stabs in cells).
Notable corrections this report makes to campaign lore
- "DAT flag 0x4 = leads outside" (PV campaign memory) — REFUTED: no 0x4 exists; outside = OtherCellId 0xFFFF.
- "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.
- Building portals carry authored per-portal cell StabLists in the dat — the old Wb path recomputes what the dat already provides.