2.7 KiB
Lossless game content packaging
npm run web:prepare and npm run android:prepare include all 84 regular
dungeon packs, the existing core packs, and the dungeons' dependency closure.
Manastorm packs keep their optional install flag even when a regular dungeon
uses the same map. Manastorm-only maps and extra character packs stay optional.
The staging directories contain one object per original SHA-256 and extension
under content/bundled. Gzip is used only when it saves space. The packager
expands each compressed object and compares every byte with its source before
writing the bootstrap catalog. Source GLBs, texture resolutions, animations,
and audio are unchanged. No media is generated by this pipeline.
Compressed objects end in .gzip, not .gz: Android's asset packager expands
and renames .gz inputs. The .gzip extension is explicitly stored without
additional ZIP compression so the manifest and APK preserve identical bytes.
Each logical asset keeps its original byte count and SHA-256 in the manifest.
An optional download record describes its gzip representation, including a
separate compressed hash and byte count. The schema remains compatible with
existing catalogs. Remote publishing retains original objects for older apps;
new clients prefer the compressed representation and verify both hashes.
The Node server and Vite preview middleware resolve bundled logical URLs on first launch. The browser service worker does the same after activation. Android streams bundled gzip through its WebView asset handler, including the companion display, without writing an expanded copy to app storage. Deploy the browser build with the project's Node server so first-launch asset aliases work.
Browser optional installs store compressed objects once and keep small logical aliases. Legacy uncompressed cache entries remain readable. Removing a pack removes an object only after its last installed reference is gone. Android optional downloads resume the compressed transfer, verify it, expand and verify the original, and atomically activate the existing shared native object file.
content/storage-report.json inside each staging/build directory records actual
unique object bytes and duplicate savings. These are packaged asset sizes, not
GPU memory estimates. Optional Android downloads occupy their expanded size;
bundled Android assets stay compressed inside the APK.
Validation: npm run content:test, the content/avatar Vitest suites, the
bundled-content server tests, npm run build, Android compilation, and a live
roster plus dungeon screenshot check. Run npm run release:check before handoff.
Android build commands also run scripts/content/verify-android-package.py
against the resulting APK, checking every stored object and every original hash.