acdream/docs/research/2026-07-24-slice-c-prepared-asset-cutover-report.md

123 lines
6 KiB
Markdown

# Slice C prepared-asset cutover report
**Date:** 2026-07-24
**Measured binary:** `b1ad4b7c0a0a519ab36d707baba74890634e6028`
**Result:** pass
Slice C moves production world-mesh preparation out of the live client.
`acdream-bake` converts installed retail DAT geometry and material metadata
into an immutable `acdream.pak`; production streaming now reads those prepared
records without reconstructing the same DAT object graphs during portals.
DAT remains authoritative for simulation, UI, animation, dynamic appearance,
physics, audio, and effects.
The user's connected screenshot review passed on 2026-07-24. Raw screenshot
differences against Slice A were caused by non-identical world lighting and
post-turn camera state; the user confirmed the prepared path's geometry,
materials, textures, and world presentation look correct. No tolerance was
widened and no world pixels were masked to obtain that result.
## Production package
| Measure | Result |
|---|---:|
| Format / bake-tool version | 1 / 3 |
| GfxObj keys | 15,318 |
| Setup keys | 5,935 |
| EnvCell keys | 729,888 |
| Total TOC keys | 751,141 |
| Portal / Cell / HighRes / Language iteration | 2072 / 982 / 497 / 994 |
| Artifact size | 29,562,150,456 bytes (27.53 GiB) |
| Header, TOC, ranges, aliases, CRCs, and iterations | pass |
Bake-tool version 3 persists each texture batch's exact translucency
classification. That lets the render thread consume the prepared record
directly instead of rebuilding a `GfxObjMesh` solely to recover material
metadata. The validated package is a required machine-local production input
beside the DAT files; it is not a repository artifact.
Focused installed-DAT validation passed 20 prepared-source, serializer, and
pak-equivalence tests plus two full-bake determinism/artifact tests. The
complete Release suite passed 8,076 tests with five skips and zero failures.
## Connected physical-display result
All three runs used the committed reference AMD display configuration, a
source-matched Release binary, the same deterministic routes as Slice A, and
normal retained gameplay UI. Every destination materialized, movement/jump/
combat exercises passed, and every client disconnected gracefully.
| Capture | CPU p50 / p95 / p99 | GPU p50 / p95 / p99 | Frame allocation max |
|---|---:|---:|---:|
| Capped Slice A | 4.287 / 6.972 / 9.404 ms | 1.702 / 3.261 / 3.847 ms | 203.5 MiB |
| Capped Slice C | 4.247 / 5.873 / 7.814 ms | 1.836 / 2.694 / 3.078 ms | 46.8 MiB |
| Uncapped Slice A | 1.520 / 5.694 / 7.825 ms | 0.897 / 3.239 / 3.406 ms | 202.9 MiB |
| Uncapped Slice C | 1.409 / 4.909 / 6.496 ms | 0.832 / 2.510 / 2.706 ms | 39.9 MiB |
| Dense Arwic Slice A | 3.672 / 6.561 / 14.121 ms | 2.476 / 3.284 / 3.752 ms | 28.5 MiB |
| Dense Arwic Slice C | 3.487 / 6.044 / 12.432 ms | 2.126 / 2.768 / 3.122 ms | 26.9 MiB |
The capped path improved CPU p95/p99 by 15.8%/16.9% and GPU p95/p99 by
17.4%/20.0%. The uncapped path improved CPU p95/p99 by 13.8%/17.0% and GPU
p95/p99 by 22.5%/20.6%. Dense Arwic improved CPU p99 by 12.0% and GPU p99 by
16.8%. Capped GPU p50 rose by 0.134 ms, but every capped GPU tail percentile
improved; neither the uncapped nor dense captures repeated that median cost.
## Allocation, GC, and probe result
| Capture | Process allocation | GC pause | Gen0 / Gen1 / Gen2 | Invalid Setup probe exceptions |
|---|---:|---:|---:|---:|
| Capped Slice A | 22.61 GB | 2.900 s | 191 / 159 / 54 | 4,851 |
| Capped Slice C | 10.21 GB | 1.368 s | 82 / 84 / 26 | 0 |
| Uncapped Slice A | 25.31 GB | 2.567 s | 278 / 143 / 58 | 4,659 |
| Uncapped Slice C | 14.74 GB | 1.325 s | 188 / 83 / 23 | 0 |
| Dense Slice A | 5.60 GB | 0.623 s | 53 / 34 / 14 | 331 |
| Dense Slice C | 2.14 GB | 0.286 s | 19 / 19 / 7 | 0 |
Process allocation fell 54.9% capped, 41.8% uncapped, and 61.9% in dense
Arwic. GC pause time fell 52.8%, 48.4%, and 54.1%, respectively. The explicit
prepared Setup presence probe eliminated the normal-control-flow
`ArgumentOutOfRangeException` storm without swallowing unexpected failures.
The largest frame-thread allocation fell 77.0% capped and 80.3% uncapped.
This slice therefore removed most of the portal decode spike even though the
2026-07-24 audit correctly assigned the remaining publication/retirement work
to cost-budgeted streaming Slice E.
## Residency interpretation
Both repeated-Caul routes passed the existing warm-return/plateau memory
assertion without changing its threshold:
- capped Caul return to plateau: +80.6 MiB working set, +53.8 MiB private;
- uncapped Caul return to plateau: +232.0 MiB working set, +183.7 MiB private.
Handles and threads also returned to their established bands. First-to-final
working set is higher than Slice A because Windows includes clean pages from
the 27.53 GiB memory-mapped package in process working set. Those pages are
discardable file cache, not private heap or retained world ownership. Private
memory remained bounded across warm revisits, while entity, animation,
particle, mesh-upload, teardown, and ownership invariants passed.
This is a correctness-first package, not the final disk/residency format.
Deduplication and compression may reduce its footprint later, but they were
deliberately excluded from the byte/field-equivalence cutover.
## Architecture closeout
- Production `ObjectMeshManager` reads only `IPreparedAssetSource`; it has no
live-DAT extraction fallback.
- `DatPreparedAssetSource` remains explicit tooling/equivalence infrastructure.
- GfxObj, Setup, and EnvCell identities are typed and validated.
- Missing, corrupt, canceled, and loaded reads remain distinct.
- Portal DAT wins the non-allocating preferred-ID lookup.
- Worker preparation and render-thread GL upload ownership remain unchanged.
- Mesh workers stop before the package is unmapped during shutdown.
- Prepared-source probe/read/result counters are exposed in the existing
render resource diagnostic record.
Machine-readable, path-free evidence is in
[`2026-07-24-slice-c-prepared-asset-cutover-report.json`](2026-07-24-slice-c-prepared-asset-cutover-report.json).
Raw frame histories, counters, reports, screenshots, and logs remain local
untracked diagnostic artifacts.