Release Healer Man 0.1.14

This commit is contained in:
phenom committed 2026-09-05 11:40:50 -04:00
1 parent 67d7a8ebe7
commit 7b41b102fa
147 files changed
+169892 -1342

No files matched your search

+66 -33
View File
@@ -1,10 +1,12 @@
# Local-first content updates and Android releases
# Local-first content updates for browser and Android
Healer Man separates the installed game client from large game content. The
Android APK contains the React/Three.js runtime, native Android bridge, menus,
local profile and save support, UI assets, and the Wailing Caverns starter
pack. Other GLBs, textures, audio, character packs, dungeons, and Manastorm
stages are published by TrueNAS as optional content.
Healer Man separates the installed game client from large game content. Both
the production browser build and Android APK contain a compact required set:
the React/Three.js runtime, menus, local profile and save support, UI assets,
starter equipment, Wailing Caverns starter content, and the basic Human
character model with its default male and female appearances. Android also
contains its native bridge. Other GLBs, textures, audio, character/skin packs,
dungeons, and Manastorm stages are published by TrueNAS as optional content.
Single-player is local-first. Starting the game, loading a character, entering
installed content, simulating combat, and saving progress never require the
@@ -27,16 +29,12 @@ UI behavior, shaders or loaders, native Android code, permissions, or the
content-manifest schema. A manifest can set `minimumAppVersion` so an older APK
will not activate incompatible content.
The browser build remains a full build served by TrueNAS. It receives client
code when the app checkout is pulled, rebuilt, and restarted. The Android build
is deliberately separate and compact so the APK does not inherit the complete
multi-gigabyte browser asset catalog.
Measured on August 14, 2026, the production browser `dist` is 3.88 GiB across
18,895 files; GLBs account for 3.75 GiB. The compact Android `dist-android` is
148.0 MiB across 5,561 files, including 47.8 MiB of starter GLBs. The final
signed APK will be smaller because Android packages compress eligible files;
record its exact size after the first release build.
Production builds deliberately stage only required content. `npm run build`
prepares `.web-public` and emits the compact browser `dist`; Android prepares
`.android-public` and emits `dist-android`. The development server continues to
use the source `public` tree so asset-pipeline work remains convenient. The
complete source catalog and published immutable objects stay on TrueNAS, not in
every player's initial browser or Android installation.
## Content manifest
@@ -56,8 +54,9 @@ The runtime continues to request stable paths such as:
```
The content resolver maps that path to a verified file in Android app-private
storage. Filenames are therefore not used as version numbers and runtime code
does not need to know the hash.
storage or, in production browsers, to the app-managed content cache through a
same-origin service worker. Filenames are therefore not used as version numbers
and runtime code does not need to know the hash.
## Safe publication and activation
@@ -68,17 +67,34 @@ Publication order is intentionally atomic:
3. Write the versioned manifest.
4. Replace `manifest.json` only after all referenced objects exist.
On a device, the client fetches the small manifest and compares it with its
installed manifest. Only missing or hash-mismatched objects are downloaded.
Android streams each object to a `.part` file, supports HTTP range resume,
verifies its size and SHA-256, then renames it into the object cache. The active
logical-path map changes only after the complete pack verifies. An interrupted
or corrupt update leaves the previous pack playable.
The client fetches the small manifest and compares it with its bundled and
installed file identities. Only missing or hash-mismatched objects are
downloaded. Browsers download into a temporary Cache Storage staging area,
verify every object's byte count and SHA-256, and promote the pack to the active
cache only after the complete pack succeeds. Android streams each object to a
`.part` file, supports HTTP range resume, verifies its size and SHA-256, then
renames it into the object cache. An interrupted or corrupt update leaves the
previous pack playable on either platform.
The starter pack is bundled into the APK. Downloaded packs live under Android's
app-private files directory, outside the packaged web bundle, and survive an
APK update. Players may remove optional packs through the content manager; save
data is stored separately and is never removed with content.
The Downloads screen uses the same lifecycle in browser and Android. A missing
pack offers **Download**, an installed pack with changed files offers
**Update**, and an installed optional pack offers **Remove**. Required packs are
marked as included and cannot be removed. Browser packs live in the app-managed
cache; Android packs live in app-private storage and survive APK updates. Save
data and roster identities are stored separately and are never removed with
content.
Character packs are presentation-only. When a selected race's pack is absent,
removed, disabled, or fails to load, the shared character renderer uses the
matching-gender basic Human model and default appearance. The saved race, class,
equipment, progression, and appearance choices remain intact and become visible
again after the pack is installed.
Generated spell effects and synthesized combat cues are the default. The
`core:combat-media` pack containing packaged original spell visuals and sounds
is never part of required bootstrap content. Original mode becomes available
only after an explicit download and falls back to generated effects if the pack
is later removed.
## Offline behavior
@@ -87,6 +103,8 @@ data is stored separately and is never removed with content.
- The last verified content map is read synchronously from local storage.
- A failed update check is silent outside the content manager.
- A failed or interrupted download never replaces active content.
- Missing optional character packs fall back to the basic Human model.
- Generated spell effects remain available without original spell media.
- Local saves are authoritative during play and cloud synchronization retries
when connectivity returns.
- Content that has never been downloaded is clearly marked as unavailable
@@ -104,9 +122,10 @@ Keeping the runtime in the APK is what makes offline startup reliable.
/mnt/usbssds/apps/healer-man/backups Database backups
```
The Node server exposes the content volume at `/content`. Manifests use
`no-cache`; immutable hashed objects use long-lived cache headers and support
byte ranges for resumed downloads.
The Node server exposes the compact production browser client at `/` and the
complete downloadable-content volume at `/content`. Manifests use `no-cache`;
immutable hashed objects use long-lived cache headers and support byte ranges
for resumed downloads.
After pulling source on TrueNAS, publish content before restarting the app:
@@ -121,15 +140,29 @@ discover a manifest whose files have not been published.
## Pack policy
Packs are player-facing groups while files remain individually addressable.
This permits a fast initial pack install and small later patches. Current pack
IDs are derived predictably:
This permits a compact initial install and small later patches. Required pack
IDs include:
```text
core:runtime
core:ui
core:equipment
core:character-basic
dungeon:wailing-caverns
```
`core:character-basic` owns the two basic Human rigs, the character manifest,
and only the default texture selections needed by the fallback. The remaining
human customizations and every non-Human character model/skin are optional.
Downloadable pack IDs include:
```text
dungeon:forsaken-abbey
characters:wow335a-v1
characters:ascension-v1
characters:runewaker-v1
core:combat-media
manastorm:<stage-id>
shared:creatures
```