8.1 KiB
Modern Runtime Slice B — EnvCell geometry deduplication and full bake
Date: 2026-07-24
Status: Complete 2026-07-24; full installed-DAT gate passed
Parent: 2026-07-24-modern-runtime-architecture.md, Slice B
Prior implementation: ../superpowers/plans/2026-07-05-mp1b-pak-and-bake.md
Outcome
Complete the existing MP1b bake without changing runtime behavior. Every EnvCell file ID remains an independently addressable pak key, while cells with the same collision-resistant geometry identity share one serialized blob and one physical byte range. The client does not consume the pak in this slice.
The full gate must replace the failed 865 GB / 52 minute per-cell bake with a bounded artifact whose size and time scale with unique geometry, not with all 729,888 cell instances.
Fixed contracts
DatCollectionremains the only DAT reader.MeshExtractorremains the only mesh/texture interpreter used by both the live path and the bake.- Geometry identity is one deterministic hash of the complete typed tuple:
environmentId,cellStructure, surface count, then the ordered surface IDs. App and Bake call the same Core implementation. - The pure identity helper lives in
AcDream.Core.Rendering.Wb.EnvCellGeometryIdentity. It uses FNV-1a in a dedicated high-bit namespace and retains bit 33 for compatibility with existing synthetic-geometry diagnostics. WorldBuilder's originalhash = hash * 31 + valuecalculation remains as a conformance helper only. - Every EnvCell TOC key is still
PakKey.Compose(PakAssetType.EnvCellMesh, fileId). - Aliases share
offset,length, andcrc32. The pak format and reader do not gain an indirection table or a second lookup. - The shared payload carries the runtime geometry ID in
ObjectMeshData.ObjectId, matching the current livePrepareCellStructMeshData(geometryId, ...)path. - A geometry-ID collision whose full source tuple differs fails loudly. It may never alias silently.
- Blob and TOC order remain deterministic across worker counts.
- The destination pak is replaced only after a complete temporary artifact opens and validates. Cancellation or failure preserves the prior file and deletes the temporary file.
- The pak itself and raw bake logs are machine artifacts and are not committed. A compact, path-free bake report is committed.
Full-DAT correction (2026-07-24): the first guarded full-catalog run proved
that the original fixed contract was impossible. Installed retail DAT cells
0x00030175 (environment=0x277, structure 0, surfaces 0x013B,0x0034)
and 0x01BC0105 (environment=0x276, structure 0, surfaces
0x04FC,0x0034) both produce WorldBuilder ID 0x00000002020E8C13 despite
having visibly different geometry. The difference is algebraic:
one environment step contributes 31³, exactly canceled by the first-surface
difference 0x04FC - 0x013B = 31². The collision guard stopped the bake before
writing an artifact. B1 was therefore corrected at the root: the old polynomial
is retained and tested as historical evidence, while runtime and bake now share
the stronger namespaced identity. The full-catalog collision gate remains
mandatory.
Implementation checkpoints
B1 — One geometry identity seam
- Extract one pure identity calculation from the App transaction builder into
AcDream.Core.Rendering.Wb.EnvCellGeometryIdentity. - Retain the existing App entry points as delegates so production behavior and callers do not change.
- Add Core conformance tests for empty surfaces, ordered surfaces, the dedicated namespace, App/Bake shared values, and the installed-DAT collision in the legacy WorldBuilder polynomial.
Gate: existing App geometry-ID tests and new Core tests pass with the exact same values.
B2 — Pak blob aliases
- Make
PakWriterretain each written key's immutable TOC receipt. - Add
AddAlias(aliasKey, existingKey), rejecting a duplicate alias key, missing source key, alias after finish, and accidental self/duplicate use. - Emit a normal TOC row with the alias key and the source receipt's physical range and CRC.
- Keep the reader unchanged except for test-only receipt inspection.
Gate: primary and alias deserialize field-for-field equal, have identical offset/length/CRC, use one physical blob, preserve sorted TOC order, and isolate corruption consistently.
B3 — Deduplicated bake catalog
- Enumerate EnvCell file IDs exactly as today.
- Read each EnvCell header once and produce:
- a sorted
fileId -> geometryIdalias stream; - one full source descriptor per unique geometry ID.
- a sorted
- Validate equal geometry IDs against the complete tuple
(environmentId, cellStructure, ordered surfaces). - Extract only the unique descriptors through
MeshExtractor.PrepareCellStructMeshData(geometryId, ...). - Write the first sorted cell key as the physical blob and every remaining cell key as an alias.
- Keep GfxObj, Setup, and side-staged particle-preload assets in the same deterministic writer transaction.
- Report enumerated cells, valid aliases, unique geometries, dedup ratio, physical blobs, failures, wall time, output bytes, and peak working set.
Gate: a filtered real-DAT fixture containing duplicate cells produces more EnvCell keys than physical EnvCell blobs, and every key reads the same payload as a live unique-geometry extraction.
B4 — Transactional output and compatibility
- Bake beside the destination under a unique temporary filename.
- Pass cancellation through enumeration and parallel extraction.
- Open the completed temporary pak and validate its header, TOC count, source DAT iterations, bake-tool version, and every TOC range before replacement.
- Atomically replace the destination on the same volume.
- Add stale-version, corruption, cancellation, partial-write, existing-target preservation, and temporary-file cleanup tests.
Gate: no failure path damages or replaces a previously valid pak.
B5 — Full-scale gate
- Run Release build and the focused Content/Bake suites.
- Run two filtered bakes with different thread counts and require byte-identical output.
- Run the complete unfiltered bake against the installed retail DAT files.
- Open the result, validate every TOC entry, sample aliases across multiple landblocks, and run the existing live-vs-pak field equivalence suite.
- Record counts, dedup ratio, failures, elapsed time, peak working set, and
artifact size in
docs/research/. - Delete the generated pak after validation unless it is intentionally retained outside the repository for the later Slice C cutover.
Exit: the full bake completes in practical time and disk space, all equivalence and determinism gates are green, duplicate EnvCells demonstrably share physical offsets, and no runtime code consumes the pak.
Completion record
All checkpoints B1-B5 are complete. The full installed-DAT bake produced
751,141 addressable keys backed by 38,370 physical blobs with zero failures.
The 729,888 EnvCell keys resolve to 17,117 unique geometries and 712,771 aliases
(42.6×). The validated package is 28,192.4 MiB and publishes atomically in
81.4 seconds on the reference machine. A cross-landblock eight-key alias fixture
is byte-identical with one versus eight workers. Full evidence:
../research/2026-07-24-slice-b-full-bake-report.md.
No runtime code reads the pak in this slice. Slice C remains blocked by the physical-local Slice A baseline gate. Release build and the complete solution suite pass (8,059 passed, five skipped, zero failed); generated pak artifacts were deleted after validation.
Verification
Run:
dotnet test tests/AcDream.Content.Tests/AcDream.Content.Tests.csproj -c Release
dotnet test tests/AcDream.Bake.Tests/AcDream.Bake.Tests.csproj -c Release
dotnet build AcDream.slnx -c Release
dotnet test AcDream.slnx -c Release
Then run the full bake from the Release binary, capture its compact report, and
validate the output with PakReader. No visual gate is required because this
slice changes no runtime path.