tryFetchManifestPair sceglie l'estensione in base a resolveJsonMode():
json5 -> .json5, legacy -> .json, auto -> entrambi. Evita le richieste
manifest.json fallite a ogni avvio in modalita json5.
Three improvements on top of duckietm/Dev's new JSON5 + split-aware
gamedata loader:
1. Parallel fetches inside loadGamedata: every file declared in a
tier's manifest is now fetched with Promise.all. The merge step
still walks the parts in declared order so override semantics
(core -> custom -> seasonal, and within-tier declaration order)
are preserved. Root-manifest files and per-tier manifest discovery
also run concurrently.
2. tryFetchManifest distinguishes 404 from other failures. The
previous tryFetchOrNull silently treated parse errors and 5xx as
"manifest missing", so a malformed manifest.json5 made an entire
tier vanish from the boot. Now only HTTP 404 returns null; every
other failure propagates.
3. New ConfigJsonError class with phase ('fetch' | 'parse'),
sourceUrl, and optional httpStatus. Exported isMissingResource()
helper lets callers check for 404 without string-matching.
Also:
- mergeGamedata warns via NitroLogger when an array looks keyed by
id/classname/name on >=80% of items but a few are missing the
key (the previous behavior fell back to concat() and produced
silent duplicates).
- Removed the dead text === null/undefined branch in parseConfigJson
(Response.text() never returns null).
Verified: tsgo clean, 138/138 tests pass on the renderer, 207/207
tests pass on the client (no behavioral change to existing callers).
Introduces loadGamedata(url, options?) and mergeGamedata(a, b) in
@nitrots/utils. The loader transparently accepts:
- a single-file URL (legacy) -> parsed as before
- a directory URL ending with '/' -> tier-merged from core/custom/seasonal,
each tier driven by its own manifest.json5
Merge rules:
- arrays of objects sharing an id key (id, classname, name): merged by id,
later layers overriding earlier ones
- arrays without an id key: concatenated
- plain objects: recursive merge per key
- anything else: later value wins
All gamedata consumers (FurnitureDataLoader, ProductDataLoader,
EffectAssetDownloadManager, AvatarRenderManager actions+figuredata,
LocalizationManager) are migrated to loadGamedata. Behaviour is unchanged
for single-file URLs, so existing deployments need no config changes;
opt-in to split mode by appending '/' to the URL once the layout is in
place.
README updated with the directory layout, merge table and programmatic
usage example. The companion CLI splitter that produces the core/ tier
from legacy files lives in the Nitro V3 client repo.