feedback5: merge W5I — real i18n phase 1: shared/i18n.js (Chinese msgids, params, data names), English game texts from the official EN client data (data/i18n/en.json), the 中文 / English switch on the title screen and in 设置, title / lobby / room / settings converted, server toasts and ticker lines with msgid + params, tools/i18n.mjs, docs/I18N.md (PR #70's translations by @YuriRestia reused, credited)

Conflict: server/match/player/basics.js imports (W5G's checkNotOwned + W5I's msg / dn). data/i18n/en.json rebuilt on the merged data (tools/build-i18n.mjs --offline): the 自选 data adds texts of CN-only operators and modules the EN client lacks, so coverage is 97.6 % (skills 95.9, talents 95.1); the coverage floors in test/i18n-data.test.js and docs/I18N.md say so. Golden unchanged; i18n / lobby / match / ui suites 1144/1144 after the rebuild, i18n e2e 1/1.
This commit is contained in:
sganggs committed 2026-10-05 22:57:53 +08:00
commit a611cb013c
38 files changed
+4043 -194

No files matched your search

+2 -1
View File
@@ -23,6 +23,7 @@ import { DATA, makeMatch, give, giveItem, checkInvariants, chessOfTier } from '.
import { botPrep, planLayout, fieldModel } from '../../server/match/bot.js';
import { placementContext, canPlace as clientCanPlace, boardTargets, deployMap as clientDeployMap } from '../../public/js/ui/gameLogic.js';
import { makeBattle } from '../helpers/battleHarness.js';
import { renderMessage } from '../../shared/i18n.js';
const STAGE = 'act2autochess_m04';
const WATER = ['10,6', '11,6', '12,6'];
@@ -187,7 +188,7 @@ test('#9 hand and temp full: a re-orientation that would push 狼群 out is refu
assert.equal(stackOf(ps, WOLF), null, 'its only copy is placed: no stack left to return onto');
const toasts = [];
const toast = m.toast.bind(m);
m.toast = (p, kind, text) => { toasts.push(text); return toast(p, kind, text); };
m.toast = (p, kind, text) => { toasts.push(renderMessage(text)); return toast(p, kind, text); }; // string or msg()
const golden = Object.keys(DATA.items).find((id) => DATA.items[id].isGolden && DATA.items[id].itemType === 'EQUIP');
while (ps.hand.includes(null)) giveItem(m, ps, golden);
while (ps.temp.includes(null)) giveItem(m, ps, golden, 'temp');
+3 -1
View File
@@ -23,6 +23,7 @@ import {
import { planLayout } from '../../server/match/bot.js';
import { collectViolations } from '../../server/match/invariants.js';
import { DATA, makeMatch, give, chessOfTier, checkInvariants } from './harness.js';
import { renderMessage } from '../../shared/i18n.js';
const STAGE = 'act2autochess_m01';
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '../..');
@@ -115,7 +116,8 @@ describe('#7 the Final Assault prep deploys on the boss field', () => {
h.drive(() => m.phase === PHASE.PREP && m.round === m.gd.bossRound);
const toasts = [];
const toast = m.toast.bind(m);
m.toast = (ps, kind, text) => { toasts.push(`${ps.playerId}:${text}`); return toast(ps, kind, text); };
// a toast is a string or a shared/i18n.js msg(): compare its Chinese rendering
m.toast = (ps, kind, text) => { toasts.push(`${ps.playerId}:${renderMessage(text)}`); return toast(ps, kind, text); };
const fields = [];
m.deployFieldOf = ((orig) => function (ps) { const f = orig.call(this, ps); if (this.round === this.gd.hiddenRound) fields.push(f); return f; })(m.deployFieldOf);
const placed = {};