feedback5 WAD: docs for language packs and content packs — docs/PACKS.md (the manifest, the two layouts, discovery and the index, what is served, the types and how a later type plugs in), docs/I18N.md §5 "Adding a language" (step by step for a translator) with the fallback chain, placeholder validation and plural categories, CONTRIBUTING / README pointers, DEPLOY §7 (packs/ and packs/index.json in the zips), ARCHITECTURE, docs/history/0.2.0.md §25.16; build-i18n --dict (a community dictionary for a language without an official client); the browser check of a pack file and a pack folder dropped in while the server runs (test/ui/i18n.e2e.test.js); golden unchanged
This commit is contained in:
1 parent
25b2a87b26
commit
1ee39a79b5
11 files changed
+466
-64
No files matched your search
+64
-2
@@ -25,7 +25,8 @@ settled (泥岩's 闭锁; 忍冬, 深靛, 阿) → §25.11; release packaging an
|
||||
with no Spine model) → §25.12; round 18 — 拟态物质 at the copy cap (GitHub #207), 华法琳's 7 / 14 (GitHub #175, PR #192),
|
||||
a merged elite 拉普兰德 as a new one (GitHub #169), the leader pool per player alive (PR #209), the flying lift and two
|
||||
model quirks (PR #211) → §25.13; the community reports of 2026-10-06 (the 孤岛风云 prisoners drawn freed, 忍冬's trigger, a
|
||||
bounty burned to death by the 活性源石, 枯朽之种 paying a bounty) → §25.14.
|
||||
bounty burned to death by the 活性源石, 枯朽之种 paying a bounty) → §25.14; the rebindable shortcuts → §25.15; language packs,
|
||||
the first type of content packs (a language is a file in the language folder) → §25.16.
|
||||
|
||||
Decisions of the owner: 2026-10-04 — the server stays on plain `node:http` + `ws`, no web framework (§25.1);
|
||||
2026-10-05 — the 补位 plan (§25.3); the 自选编队 rules, the collab operators out of the pool, ISW-A refused (§25.4);
|
||||
@@ -38,7 +39,8 @@ a melee 突袭 member lands where it can block (§25.11); 华法琳's granted tr
|
||||
lock (§25.13.2); a newly merged elite 拉普兰德 counts as a new 拉普兰德 (§25.13.3); the leader pool = bloodPoint × the players
|
||||
alive at the fight's start, adopting PR #209 and replacing 「保持固定血量」 (§25.13.4); flying units at 1.3 tiles and the two
|
||||
model quirks of PR #211 (§25.13.5); the bounty pays whenever its enemy dies (relayed with the community
|
||||
reports, §25.14.3).
|
||||
reports, §25.14.3); 2026-10-07 — a language is a file in the language folder, and the language pack is the first type
|
||||
of a general content-pack mechanism (§25.16).
|
||||
|
||||
### 25.1 Refactor and tooling: the big files split, golden results, lint, types, import boundaries (refactor plan; owner's decision of 2026-10-04: no web framework) — `server/http/`, `server/match/match/`, `server/match/player/`, `server/sim/battle/`, `content/enemies/`, `kits/ops/`, `public/js/ui/gameLogic/`, `render/fx/`, `render/app/`, `screens/game/`, `tools/golden.mjs`, `tools/check-imports.mjs`, `eslint.config.js`, `jsconfig.json`
|
||||
|
||||
@@ -1092,3 +1094,63 @@ fixed (W5AA's commits name every golden scenario moved); two were already fixed
|
||||
`test/ui/gameLogic.test.js` (sanitizeSettings), `test/ui/hotkeys.e2e.test.js` (SP_E2E=1: 撤退 rebound to W with the
|
||||
keyboard only in the mock match — Q then does nothing, W retreats, the choice survives a reload; phone width). Docs:
|
||||
docs/PLAYING.md §11, README 操作, DESIGN §10 (design/client.md).
|
||||
|
||||
### 25.16 Language packs: a language is a file in the language folder, the first type of content packs (W5AD; the owner's decisions of 2026-10-07) — `shared/packs.js`, `shared/i18nPacks.js`, `shared/i18n.js`, `shared/i18nData.js`, `server/packs.js`, `server/http/static.js`, `public/js/ui/lang.js`, `public/js/data.js`, `tools/i18n.mjs`, `tools/packs.mjs`, `tools/build-i18n.mjs`, `tools/package.mjs`, docs/I18N.md §5, docs/PACKS.md
|
||||
|
||||
- **Seen**: after §25.2 English was wired in by name — the language list `['zh', 'en']`, the switch's labels, English
|
||||
checks in the title screen, `fmtNum`, the tab title, a CSS rule, the overlay URL pattern — so another language meant
|
||||
editing code, and players asked to translate into their own languages.
|
||||
- **Decision**: the owner's decision of 2026-10-07 — putting an adapted language file into the language folder is all
|
||||
it takes for the game to offer that language, so the community can add languages themselves; the same day, design the
|
||||
language pack as the first type of a general content-pack mechanism (later: resource packs for art / audio, then
|
||||
server-side data packs) with one manifest, one registry and one index.
|
||||
- **Now** (docs/I18N.md §5 for translators, docs/PACKS.md for the mechanism):
|
||||
- **A pack** is a manifest plus its files, in one of two layouts the same registry reads: the single file
|
||||
`public/i18n/<code>.json` (manifest: its `_meta` block; optional game texts `data/i18n/<code>.json`) — the
|
||||
translator's way and how English ships — or a folder `packs/<id>/pack.json` naming its files (every future type).
|
||||
The manifest: type (`lang`; `assets` and `data` planned: parsed, listed as not supported, never served), version,
|
||||
the app versions it targets (a range; outside it a language pack still loads and is flagged), its name in its own
|
||||
language and in English, authors / credits / licence, and the type's fields (`lang`, `base`, `fallback`, `complete`,
|
||||
`numberUnits`). English carries one like any pack (`complete: true`).
|
||||
- **Discovery**: `server/packs.js` scans the language folders and `packs/` at start and again when their files
|
||||
change (looked at on each index or pack-file request, at most once a second), validates the manifests, and answers
|
||||
`GET /packs/index.json` (live, never cached; packs of supported types with the URLs of their files) and
|
||||
`GET /packs/<id>/<file>` (only a file a manifest names, with its role's extension, inside the pack folder). A static
|
||||
host uses `node tools/packs.mjs index` (packs/index.json); the release zips ship packs/ and that file. A broken
|
||||
manifest, a planned type, a second pack for an id or a language: skipped with the reason in the server log and
|
||||
`node tools/packs.mjs list`.
|
||||
- **The client** lists every `lang` entry under its own name (title screen and 设置: buttons up to four languages, a
|
||||
list beyond); `?lang=<code>` and the stored choice resolve to a listed pack (`en-US` → `en`; a pack that is gone →
|
||||
Chinese); without an index the stored pack still loads by its code. Nothing in the client names English: the title
|
||||
screen lays out by the script of the pack's title (`scriptOf`: an alphabetic title takes English's layout), the tab
|
||||
title and `<html lang>` follow the pack, `fmtNum` takes `numberUnits` (Chinese 万 / 亿; without them K / M / B).
|
||||
- **Fallback chain** per string: the pack → its base (`pt-BR` → `pt`; `zh-TW` none) → the packs `_meta.fallback`
|
||||
names (English) → the Chinese msgid; game texts per text (each from the first overlay of the chain that has it:
|
||||
`applyFileOverlay(json, overlay, onto)`, `data.setLocale(lang, chain)`).
|
||||
- **Placeholders**: a translation that drops a plain placeholder of its msgid, uses one the caller does not pass, or
|
||||
has a broken plural form is skipped like a missing one (the next language of the chain shows; a development page
|
||||
warns once on the console; `tools/i18n.mjs check` checks the call sites). **Plurals**: `{n|one|other}` picks by
|
||||
`Intl.PluralRules` (English exactly as before), and named categories serve other languages
|
||||
(`{n|one:…|few:…|many:…|other:…}`).
|
||||
- **Tools**: `node tools/i18n.mjs template <code>` (a skeleton: `_meta` and every msgid; on an existing pack only
|
||||
the msgids it lacks), `check <code> | --all` (coverage; errors; a complete pack must have every msgid);
|
||||
`node tools/build-i18n.mjs --lang ja | ko | zh-TW` builds a pack's game texts from the official JP / KR / TW client
|
||||
(ArknightsAssets/ArknightsGamedata `jp/`, `kr/`, `tw/`, each with both 盟约 seasons, checked 2026-10-07: ja 96.5 %,
|
||||
ko 97.4 %, zh-TW 91.1 % of 22 114 texts); a language without a client uses `--dict` (a community dictionary) or no
|
||||
game texts at all (they follow the chain). No language but English ships: there is no Japanese, Korean or
|
||||
Traditional Chinese UI pack yet, and a game-text file without its UI pack is not listed.
|
||||
- **The output in Chinese and English did not change**: `test/i18n-packs.test.js` renders every msgid of
|
||||
`public/i18n/en.json` in both languages with sample params and compares it with the renderer of 0.2.0 before packs;
|
||||
`node tools/build-i18n.mjs --check` still finds `data/i18n/en.json` up to date. One English entry was added, the tab
|
||||
title (`卫戍协议:盟约 · STRONGHOLD PROTOCOL`, the same text as before).
|
||||
- [ASSUMED]: the menu turns into a list above four languages; two plain plural forms follow the language's rules (only
|
||||
-1 renders differently from before in English, "-1 second"); a regional code falls back to its language's pack before
|
||||
the declared fallbacks; with two packs for one language the language folder's file wins; a pack outside its app range
|
||||
still loads; a development page is a dev build or one served from localhost.
|
||||
- Golden: unchanged. Tests: `test/i18n-packs.test.js` (12: discovery of both layouts and of broken / planned /
|
||||
duplicate packs, a pack dropped in or removed while the server runs, the file allowlist, manifests and app ranges,
|
||||
the chain, placeholders, plurals in English and Russian, the per-text game-text fallback, the client loader and menu,
|
||||
the template / check / index tools, build-i18n's `--lang` and `--dict`, zh / en unchanged), `test/package.test.js` (both layouts ship, a local pack does
|
||||
not, the generated index), `test/ui/i18n.e2e.test.js` (`SP_E2E=1`: a pack file and a pack folder dropped in while the
|
||||
server runs show in the menu and switch, English filling the gaps; a removed pack sends the stored choice back to
|
||||
Chinese); `test/i18n.test.js`, `test/i18n-data.test.js`, `test/i18n-server.test.js` unchanged and green.
|
||||
Reference in new issue
Block a user