forked from phenom/healer-man
55 lines
3.3 KiB
Markdown
55 lines
3.3 KiB
Markdown
# Lossless game content packaging
|
|
|
|
`npm run web:prepare` and `npm run android:prepare` include exactly five packs:
|
|
`core:ui`, `core:equipment`, `core:character-basic`, `core:runtime`, and
|
|
`dungeon:wailing-caverns`. The complete publication catalog retains all 54
|
|
regular dungeons. Internal `manastorm:*` environment packs remain dependency
|
|
targets for the 53 regular dungeons that reuse those maps, but they and
|
|
`core:arenas` are hidden from the Downloads screen.
|
|
|
|
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 and
|
|
persists each immutable bootstrap object by hash after its first use.
|
|
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.
|
|
|
|
Normal release verification rejects unexpected bootstrap packs, more than 80
|
|
MiB of stored bootstrap objects, arena assets, and shelved client modules.
|
|
Eligible JavaScript, CSS, and JSON responses are precompressed with Brotli and
|
|
gzip; hashed Vite files and bundled content objects use immutable one-year
|
|
caching, while HTML, service workers, and manifests revalidate.
|
|
|
|
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.
|