201 KiB
DESIGN §25 — 0.2.0
Part of DESIGN.md (the index; section numbers are global).
25. 0.2.0 — the maintainability refactor, two languages, 补位, 自选编队, fidelity fixes, the 0.1.4 ports, release packaging
0.2.0 was built on feedback5, branched from feedback4 at 583899d (0.1.3, the golden-result harness and part of 0.1.4);
later merges of feedback4 brought the rest of 0.1.4 in. The workstreams, each on its own fb5-* branch, each merged
after review with its golden scenarios named: R1–R6 (refactor, tooling), W5A (golden results), W5B / W5D / W5G /
K1–K3 / W5N (补位), W5H / W5K / O1–O24 (自选编队 and its operator kits), W5I / W5S (languages, phases 1 and 2), W5C /
W5E / W5F / W5J / W5L (fidelity, wave 1), WE1 / WE2 (the follow-ups the kit waves reported), W5M, W5R and the feedback4
merges (the 0.1.4 ports), W5V (the owner's items of 2026-10-06), W5U (packaging), W5T (the docs), W5Y (round 18:
three GitHub issues and three community PRs), W5AA and CB1–CB5 (the community reports of 2026-10-06), W5AC
(rebindable shortcuts) and W5AD (language packs). Each rule was checked against the official data and PRTS; anything no
source backs is marked ASSUMED.
The normative sections were rewritten with the streams: §0 (the DIY slots), §2 (the layout), §5.5 (the enemy damage
frame, the block-count target rule, 自制投石机's 索敌不受阻挡影响), §5.6 (the trigger rules), §8.1 / §8.3
(welcome.diyKitted, standIns, diy, diyBanned), §10 (the rebindable shortcuts), §16 (干员持有, 自选编队). Where each
is handled: refactor and tooling → §25.1; Chinese and English →
§25.2; 补位 → §25.3; 自选编队 and the 71 operator kits → §25.4; trigger rules (the larger-range rule, AUTO skills) →
§25.5; fidelity fixes of wave 1 (GitHub #41, #49, #82, #96 / #137, #107, #116; 伺夜's 狼群; Touch) → §25.6; WE1, sim
rules (GitHub #181, #187 / #170, follow-ups) → §25.7; WE2, data / match / UI (follow-ups, GitHub #148) → §25.8; the
0.1.4 ports → §25.9 (the last two, W4D's sleep rule and W4C's board tap → §25.9.1 / §25.9.2); the settled decisions,
what stays ASSUMED and the questions left to the owner → §25.10. The closing additions: the owner's decisions of
2026-10-06 (望's stock, skill triggers through summon areas, the 突袭 landing, GitHub #148) and the items the sources
settled (泥岩's 闭锁; 忍冬, 深靛, 阿) → §25.11; release packaging and the asset manifest (the 自选 voices, the summons
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; the rebindable shortcuts → §25.15; the
second batch of community reports of 2026-10-06, one section per stream: CB2, healers, summons, timers (刺玫's S2 heals,
琳琅诗怀雅 healing herself and her 破财消灾 cost after a redeploy, 赫默's drone at full SP, the countdown summons' 无敌 /
禁疗 / timer bar, stacked alchemy zones; the chain heal, DoT damage, 伺夜's 狼影 and the 吟游者 trait answered) → §25.16;
CB3, operator kits and triggers (砾's double hit, 乌尔比安's S3 landing behind the 联防 red gate, the 「受到攻击时」
counters on every enemy damage instance, a 突袭 member's jump after an in-place 复活, 银灰's sound; 铃兰's trigger,
琳琅诗怀雅's champagne, the 突袭 玛恩纳, 归溟幽灵鲨 devoured and 荒芜拉普兰德 / 叙拉古 already answered; 乌尔比安's revive
tile on his deployment tile, the owner's deviation) → §25.17; CB4, enemies, bosses, waves, movement (the 突袭 landing on the 临时整备区 row and the
other half of the 联防 map, a silenced 萨卡兹枯朽战士's death pollution, 萨卡兹穿刺手's speed after a stun and its first
hit, 自制投石机 blocked on the 排气格栅; the briefing types' 7–9 waves, 新硎's 断刃, a freed prisoner in 联防 and 鸭爵's two
swaps in one wave already answered; the moving leaders' routes checked; 野鬃, 锏's pulls, 昆图斯's footprint and the leaders' attack rate not
reproduced) → §25.18; CB5, match flow and UI (a module's 特性追加 line after the class trait, the new shop slot filled at
the upgrade, an eliminated player following a player through every round, the boss field and its leader in a watcher's
boss prep, the pair together in the boss prep with the official green frames; PRs #189 / #191 reused, not merged; the
battle-history request postponed by the owner, the hotkey request built in §25.15) → §25.19; language packs, the first
type of content packs (a
language is a file in the language folder) → §25.20; the last stream of that batch, CB1, bonds, strategies and items (the
谢拉格 wind's endless freeze, 埃芒加德's and M3茧甲's 复活 as a knock-out and a free redeploy, 佩佩's paid refresh, the 炎佑 on
the medic's slot, 凯瑟琳's offer, the hidden layers on the result card; the official behaviours pinned) → §25.21.
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);
Chinese by default with an English switch, official English game texts, PR #70's translations reused with credit
(§25.2); the larger-range trigger rule on the basic strategy, the SEARCH row and 深巡 S2, every 自选 重装 cast with an
enemy in range, 纯烬艾雅法拉 S1 at full SP, 伺夜 S1 only with his pack on the field (§25.5); 2026-10-06 — a chess the player
does not own shows as its stand-in everywhere (the owner's recall of the official mode, §25.3); the enemy damage frame
kept (§25.7.2); 望's placed 棋子 count in her stock, skills that act through summons cast on an enemy in a summon's area,
a melee 突袭 member lands where it can block (§25.11); 华法琳's granted trait at the data's 7 / 14, replacing the 12 / 24
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); 2026-10-07 — the in-match shortcuts rebindable in 设置 (§25.15); a language is a file in the
language folder, and the language pack is the first type of a general content-pack mechanism; Japanese, Korean and
Traditional Chinese ship with the official game texts and fallback UIs — the Traditional one's in Simplified Chinese
(§25.20); 乌尔比安 knocked
out during his S3 comes back on his deployment tile, a deliberate deviation from PRTS's "where it fell" (§25.17.3);
烛煌's 绝处重燃 before 坚固维式重锤's lock and the official tier cap of 寻呼模块 / 简易通讯机 kept as they are (§25.21.1,
§25.21.10).
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
- Why: the files every fix touched had grown to thousands of lines (
Match.js3237,enemies.js3162,Battle.js2465,fx.js2259,render/app.js2046,gameLogic.js1913,PlayerState.js1673, the six kit tiers 864–3362 each), and the new operator kits needed one file per operator. Official: none — nothing a player sees changes (refactor plan rule 1). - Safety net first (W5A, merged on feedback4 before the refactor;
test/golden/README.md):tools/golden.mjsruns a seeded corpus through the production BattleSpec path andMatchwith aVirtualSchedulerand reduces every scenario to a digest — familiesroster(every chess record × skill × module, every stage and enemy kind),bonds(every bond at 1 and 999 layers),fields(every leader, 联防 with 1 and 2 helpers),matches(bot matches to the end), and since 0.2.0standins(§25.3) anddiy(§25.4).npm testchecks the fast subset,GOLDEN_FULL=1/npm run goldeneverything; a refactor never changes the files, a gameplay change regenerates them in the same commit and names every scenario that moved (the rule every 0.2.0 stream followed). - Now (R1–R5, each a pure move listed in
.git-blame-ignore-revs, then a docs commit; golden unchanged after each):- R1:
server/index.js(786 lines → 110) keepsstartServer()and the same 15 exports; the code is inserver/http/(config, websocket, static, media, files, buildTag, routes, common, boot). Still plainnode:http+ws(the owner's decision of 2026-10-04: no Hono); response header order, the /healthz keys, the banner and the/data.jsstand-in text are byte for byte the same (a scripted fingerprint of 51 requests matched). - R2:
Match.js(3237 → 383) andPlayerState.js(1673 → 239) keep the class, the constructor and the interface header; their 167 / 87 members moved verbatim into 16 / 9 per-concern method containers (server/match/match/,server/match/player/— W5K addeddiy.jslater; shared constants incommon.js), installed on the prototype in a fixed order — a name defined twice throws. - R3:
Battle.js(2465 → 189) the same way intoserver/sim/battle/(131 methods, 14 containers +util.js);content/enemies.js(3162 → 321) intocontent/enemies/(helpers, archetypes, one file per special type, leaders) with theKITSorder kept. - R4: the 129 kits of
kits/tier1..6.jsbecamekits/ops/<chessId>-<codename>.js(the code name = the charId withoutchar_<n>_; the chess id is the unique key — 锡人, 耶拉, 华法琳 are two chess each), helpers shared by a tier inkits/shared/tierN.js, the registrykits/index.js(a guarded dynamic import per file: a broken file only drops its own kit to the generic one);kits/README.mdis the kit guide with the fidelity checklist. Thetier*.jsre-export shims were removed in WE2 (§25.8.8). - R5: the client —
ui/gameLogic.js(1913 → 47) andrender/fx.js(2259 → 45) became barrels overui/gameLogic/(18 modules) andrender/fx/(15); the field view's helpers moved torender/app/and the match screen's standalone parts toscreens/game/(same exports).
- R1:
- Tooling (R6):
npm run lint— a correctness-only ESLint (eslint.config.js; no formatter, warnings allowed);npm run typecheck—tsc --checkJsover a first slice (jsconfig.json:shared/butprotocol.js/bandBonds.js,sim/rng.js,dir.js,constants.js, the typedefs oftypes/core.js;types/README.mdsays how to widen it);npm run check:imports—tools/check-imports.mjs:server/sim/(served to browsers) imports neither the match, the lobby, the entry, the net layer,public/nor a Node builtin,server/match/neitherpublic/nor the net layer; the one listed exception issim/nodeData.js, the Node-only loader (test/check-imports.test.jspins the list);tools/package.mjs(+--lite) builds the release zips from a runtime allowlist (W5U, §25.12). CI gained a tooling job (lint, imports, typecheck; once, not per matrix entry). - Measured: a match now loads about 340 small script modules; over HTTP/1.1 at 100 ms latency a cold load took 13.4 s instead of 9.8 s, so docs/DEPLOY.md recommends HTTP/2 at the reverse proxy (the browser sim warms up during the band draft, so play is not delayed).
- Tests:
test/content/kits_layout.test.js(everyops/file listed once, named after its chess id and charId, one registry key, no Node-only import, no clock orMath.random),test/check-imports.test.js,test/version.test.js(reads the banner //healthzfrom their new files),test/docs-consistency.test.js(reads the classes as their façade plus method modules);GOLDEN_FULL=1 node --test test/golden.test.jsafter every refactor commit. - Docs: docs/ARCHITECTURE.md (the map of the code after the split) and CONTRIBUTING.md (setup, tests, the fidelity rules, conventions) are new in 0.2.0; §2 lists every file.
25.2 Chinese by default, an English switch (W5I, phase 1; W5S, phase 2; PR #70 by @YuriRestia; the owner's decision of 2026-10-05) — shared/i18n.js, shared/i18nData.js, tools/build-i18n.mjs, tools/i18n.mjs, public/i18n/en.json, data/i18n/en.json, public/js/ui/lang.js (sentText), docs/I18N.md
- Seen: English-speaking players asked for an English interface. PR #70 (@YuriRestia) translated by replacing the strings in place across every file, logic included; the owner did not merge it (reply on PR #70, 2026-10-05) and asked for real i18n instead.
- Official: the English game texts exist in the official EN client data (the EN tables carry act2autochess with the zh_CN ids); the YoStar repository the plan first named is archived and has no 盟约 season.
- Decision: the owner's decision of 2026-10-05 — Chinese stays the default (an English browser still opens in Chinese), English is a switch; game texts from the official EN data; PR #70's translations reused with credit; no i18n framework.
- Now (docs/I18N.md is the reference): UI strings go through
t('中文')— gettext style, the Chinese text is the message id, so an untranslated string shows Chinese, never a key ({name}parameters, one plural form,tc()for context,N_()marks module-level tables); their English ispublic/i18n/en.json, seeded from PR #70's translations. Game texts (operators, skills, talents, modules, traits, enemies, bonds, items, effects, strategies, 特质, 机变 cards, modes, stages, tokens) come from an overlay,data/i18n/en.json, whichtools/build-i18n.mjsbuilds by walking the zh_CN and EN tables side by side (exact, template and composite matches; fallbacks: the remake's own strings, PR #70's, the UI table) andpublic/js/data.jsapplies: 97.6 % of 22 183 texts with the 自选 data (the CN-only operators and modules are what is missing). Server toasts and ticker lines travel asmsgid+params(wireMessage;textkeeps older clients working) and each client renders its own language. The switch: the title screen (top right) and 设置,?lang=enonce, kept insp.pref.lang, re-rendered in place. Phase 1 converted the title screen, lobby, room, settings, the app shell and every server message;tools/i18n.mjs(extract / check / codemod / seed) finds what is left. - Phase 2 (W5S, 2026-10-06; docs/I18N.md §4): of the 1 128 Chinese literals
extractstill listed, 1 056 go throught(),N_()or the newtParts()(a sentence with markup or a component inside: the translation split at its placeholders, vnode params kept) — the screens (band draft, briefing, the game screen and its overlays, 干员调配 / 干员持有, the result), the HUD, shop bar, detail card, bond strip and popup, 机变 overlay, enemy drawer, team panel, guide, emotes, components and the client models, the phase banners, refusal reasons and formats ofui/gameLogic(fmtNumwrites K / M / B in English, 万 / 亿 in Chinese), the canvas, 2D-fallback and facing-wheel labels and the msgid tables ofshared/constants.js; the other 72 are marked as no player text and skipped by the audit (error details and logger lines, the invariant reports, the bilingual HTTP error pages, the AI seats' names, the dev STUB match, data keys).extractnow reports 0 andcheck1 002 msgids, every one translated (public/i18n/en.json1 015 entries; the 64 fragments the sweep replaced dropped). Game texts the server copies into the match views in Chinese — a 机变 card, an effect entry, the draft's name, a reward offer's label, the result title — show the localized record when the sent text is that record's own (data.lookupRaw,ui/lang.js sentText; names throughtName); a text the server reworded (the multi-round 悬赏's two-battle text,choices.js bountyText) stays as sent. A language switch in the middle of a screen re-reads the game texts (useGameData(), the 干员调配 / 干员持有 rosters, the strategy list and the open detail card listdata.locale()among their memo dependencies). What stays Chinese in English: player names (the AI seats' too), that reworded 悬赏 text, the game texts the official EN client lacks (some 自选 operators, newer modules) and the 玩法说明 pictures (their titles translated). The 虫动 emote set follows the official EN name (Slug Style). The Chinese output did not change: a render of every converted file in Chinese equals the code before the sweep, and the few rewrites it cannot follow were checked by hand. - ASSUMED: the English of the remake's own strings (排气格栅 "Exhaust Grille" as PR #70 has it, the 联防 map names, the server's own templates, the 126 msgids phase 2 added).
- Golden: unchanged. Tests:
test/i18n.test.js(since phase 2 it scans the whole client, shared and the server messages: no Chinese literal left unwrapped, every msgid translated —extract0 andcheck --strictas a test; floors 1 000 catalog entries, 1 350 msgid uses),test/i18n-data.test.js(coverage floors),test/i18n-server.test.js(also the sent data texts),test/ui/i18n.e2e.test.js(SP_E2E=1).
25.3 补位: an operator the player does not own fights as its official stand-in (W5B, W5D, W5G, K1–K3, W5N; the approved plan, the owner's decision of 2026-10-05; the owner's recall of 2026-10-06) — tools/build-data.mjs buildBackups, data/backups.json, shared/standIn.js, sim/simdata.js getStandIn, content/index.js kitOf, kits/ops/standin-*.js, shared/protocol.js room.ownership, screens/ownership.js, ui/gameLogic/standIn.js
-
Seen: the official mode fills an operator the player does not own with a stand-in; the remake always fielded the real operator, and the data build dropped the official backup fields.
-
Official: act2autochess — 133 chess: 74 PRESET (特许, always available), 55 NORMAL (each naming a backup: charId, template, skill, module, potential), 4 DIY; PRTS 卫戍协议 — a missing operator is filled by a prototype of its class with a fixed skill, and the bonds and 特质 stay the chess's. The 17 stand-ins: the eight 4★ 预备干员 and nine elite prototypes (郁金香, Sharp, Mechanist, Stormeye, Pith, Touch, Raidian, Misery, 领主·Sharp).
-
Decision: the approved 补位 plan (2026-10-05): only the 55 NORMAL chess can be marked not owned, everything is owned by default, no borrowing from friends, bots own everything; the 重装 stand-ins (预备干员-重装, Mechanist) cast with an enemy in range, like §21.29. The owner's first-hand recall of 2026-10-06: the shop, the hand, the board and the result screen show the STAND-IN — this replaced the first build's cards that kept the chess with a 「替补:X」 badge.
-
Now: data (W5B): every chess.json record keeps
backup; data/backups.jsonunitsholds the 17 stand-ins in every form (DATA.md §18). Battle (W5D):getChess(id, { standIn: true })= the chess's ids, bonds and tier with the stand-in's body (def.standInFor); its kit is the stand-in's own (kits/ops/standin-<codename>.js,STANDIN_KIT_FILES), never the replaced operator's; without one, the generic kit plusgenericTalents— the eight 预备干员 get their talents, 一击即退 for 10 s from every deployment and 冲锋号令 +12 DP; the browser battle loads data/backups.json too. Match (W5G): C→Sroom.ownership { notOwned }(the 55 droppable chess only; fixed for the match);battleInputmarksstandIn: truein every field — the rules read the chess (price, bonds, 特质, merges, pools), the body is the stand-in's (placement by its own position, range, no summons). Client: the 干员持有 tab of 干员调配 (export / import,sp.pref.ownership); since W5N the stand-in is drawn everywhere — shop and reward cards, hand, 临时整备区, board, detail card, bond popups, result lineup, bench scouting, tickers — with a small ice 「替补」 mark and the chess's tier, price and bonds. It speaks with its own voice (the §21.30 port; a 预备干员 stays silent). -
Kits (K1–K3; every skill on every form, the numbers from the composed record, the data's trigger):
stand-in kit ( kits/ops/)stands in for notable ASSUMED Sharp standin-acguad.js忍冬, 银灰, 百炼嘉维尔, 隐德来希, 归溟幽灵鲨, 佩佩 — 领主·Sharp standin-sharp2.js水月, 玛恩纳, 维娜·维多利亚, 妮芙 陷阵勇气 counts targetable enemies; LOR-X's 流失 follows a shielded hit Misery standin-acspec.js缄默德克萨斯, 山, 新约能天使, 锏 四维分离 counts her own tile and air units; S3's drag area is its x-4; S1 / S2 deploy-timed duration skills (WE1) Stormeye standin-acnipe.js空弦, 莫斯提马, 百炼嘉维尔, 妮芙, 蕾缪安, 异客 风雨欲来's delay = no attack for 2 s, counted from deployment Pith standin-accast.js烛煌, 焰影苇草, 迷迭香, 荒芜拉普兰德 two Piths' 授我所授 / S2 never add up Raidian standin-acsupo.js灵知, 夕, 安洁莉娜, 浊心斯卡蒂, 仇白 诱引 rolls at an attack's first damage instance; new applyStatusoptionstackAs郁金香 standin-acpion.js瑕光, 焰尾, 凛御银灰, 圣聆初雪, 缪尔赛思, 耀骑士临光 the 集成战略 备注 applies; S3's 8 slashes at the clip's OnAttack events Mechanist standin-acfend.js星熊, 号角, 余 S3 pulses from 1 s after the cast Touch standin-acmedc.js塞雷娅, 塑心, 纯烬艾雅法拉 shares the 外勤医疗 strategy's Touch code (§25.6.6); S2's 所有医疗干员 = her own player's -
ASSUMED: a stand-in is placed by its own position (melee tiles for a melee stand-in); without accounts any of the 55 may be dropped, also one the player owns; AI 托管 values a dropped chess by the chess record; the detail card names 「X的替补」 in place of the English name; the 「替补」 mark's look.
-
Golden: new family
standins(10 battles: every NORMAL record, normal and elite, fielded as its stand-in) and the matchcoop2-NORMAL-14-standins(a human seat on AI 托管 owning none of 7 NORMAL chess); nothing else moved. -
Tests:
test/backups.test.js,test/content/standin.test.js(the plumbing and the eight 预备干员),test/content/standin_*.test.js(the nine kits),test/match/standin-ownership.test.js,test/lobby-ownership.test.js,test/ui/standin-ui.test.js,test/golden-standins.test.js,test/ui/standin.e2e.test.js(SP_E2E=1).
25.4 自选编队: the four DIY slots field the player's own 6★, and 71 operator kits (W5H, W5K, O1–O24; the owner's decisions of 2026-10-05) — data/backups.json diy, shared/diy.js, sim/simdata.js getDiy, server/match/player/diy.js, shared/protocol.js room.diy, screens/diy.js, kits/index.js OPERATOR_KIT_FILES, kits/ops/op-*.js, kits/shared/summoner.js
- Seen: the four DIY chess were removed from the shared pool (§0). A first attempt (PR #71) had put them in the shared pool, one chess id meaning a different operator per player — the shape to avoid.
- Official: act2autochess
diyChessDict/shopLevelDisplayDataDict— two slots at tier 5 (from 调度中心 level 5), two at tier 6 (level 6), price 4, sold for 1; PRTS 盟约 下半 — the player's own 6★ or a 6★ prototype, no 特质, the core bonds its factions meet (else 协防); forms: normal = E2 Lv1 with skills at rank 4, elite = E2 Lv60 rank 7 with its module at stage 1 (tier 5) or 3 (tier 6). - Decision: the owner's decisions of 2026-10-05 — two plus two slots per player; an owned 6★ with a kit, any of its
three skills, any elite module; a prototype keeps the skill and module of its 补位 rows; a per-player shop; levels
follow the chess forms; the six collab 6★ are out (copyright), and so is 焰狐龙梓兰 (MH05, a Monster Hunter 联动寻访
operator the team list does not name:
DIY_EXCLUDED_NUMBER_PREFIXES) — 71 owned picks; the 集成战略-only ISW-A modules are refused (WE2 adds SO-A / SO-B / RA-A, §25.8). - Now: data (W5H): data/backups.json
unitsadds the 71 owned picks in the three slot forms,tokenstheir 38 summons,diythe slots, the prototypes (15 at tier 5, 9 at tier 6), their locked loadouts,ownedPooland the derived bonds (DATA.md §18);shared/diy.js(diyPool,validateDiyPicks,diyRecordOf); the sim fields a pick (getDiy; kitKITS[charId]). In play (W5K): C→Sroom.diy { picks }(checkDiyPicks;welcome.diyKittedlists the operators with a kit); the player's data view makes a slotted DIY slot its operator everywhere — bonds, placement, summons, AI 托管 — with no 特质; a per-player stock never enters the shared pool and the player's own shop draws it from the slot's 调度中心 level; a piece whose every bond is off this match leaves the shop (m.private.diyBanned, shown since WE2); a placed operator's summons go to the hand (official counts since WE2, §25.8). Client: the 自选编队 tab of 干员调配 (two tier-5 and two tier-6 slots, the picker with skill and module, export / import,sp.pref.diy) and a mint 「自选」 badge on cards and pieces. - The kits: 推进之王 first (W5H, the worked example of kits/README.md "How to add an operator (自选)"), then O1–O24 in
three waves — every skill at ranks 4 and 7, every talent, every module at stages 1 and 3, the range while a skill
runs, triggers, targeting, damage typing, summons and statuses, per the kit checklist; potential 0 for every pick
[ASSUMED: no account]. Engine additions, each additive (only the
diygolden family moved):palsyTrigger(O3,ai.js: a 麻痹 stack interrupting an enemy attack), thehpDamagehook after the shields (O5,damage.js), target priorityheaviestand the boomerang hooksboomerangCaught/boomerangOnward(O7), shields limited to damage types (shieldType, O8 / O16) and a profile'sskipEnemy(O8), enemy shots carryingisProjectileand priorityelite(O11), a healer profile'shealThrough(O16), the 缚地 statusgroundbind(O20), theenemyAttackStarthook, thenoNewBlockflag andholdsUndyingreading anundyingbuff (O22), ally attack targets (Battle.setAllyTarget, O23), the air-block modblockRadiusScale(O24);kits/shared/summoner.js(O21) holds the 召唤师 deck of 麦哲伦 / 令 / 电弧. Match: a placeable summon's hand count reads the active module's variant (O19: 望's TRP-X 7). Client: visuals for the 13 fx kinds the new kits emit (render/fx/kinds.js); the picks' art comes with the asset plan (tools/fetch-assets.mjs --add-only; their battle voices and the summons with no Spine model: §25.12).
| 干员 (summons) | kit (kits/ops/) |
stream | notable ASSUMED (and later changes) |
|---|---|---|---|
| 推进之王 | op-siege.js |
W5H | S2 跃空锤 reaches ground enemies only (no source says air); SOL-Y's extra SP goes to a random deployed other 【先锋】 |
| 陈 | op-chen.js |
O4 | S3's ten slashes = the first ten of the clip's eleven OnAttack events; S3 refused with no ground enemy in its 技能范围 |
| 艾丽妮 | op-irene.js |
O4 | S3's first bombardment 0.3 s after the opening strike, an empty one skipped; ISW-A refused in 自选 (W5K) |
| 赫拉格 | op-helage.js |
O4 | 运筹帷幄 is the 生命回复速度 attribute (no PRTS 备注); the 武者 heal per damage instance (WE1) |
| 闪灵 | op-shining.js |
O8 | S2's DEF bonus ends with her last barrier on that unit; PHY-X heals ×1.15 at or below 50 % (WE1) |
| 夜莺 (幻影) | op-cgbird.js |
O8 | a held 幻影 returns after 20 s for 5 DP whether or not 夜莺 stands; 3 hand pieces (WE2) |
| 嵯峨 | op-saga.js |
O8 | 清明 is a 生命回复速度 (hpRegenRatio) buff; SOL-Y stage 3 takes the blackboard's 6.5 % (the text says 6 %) |
| 艾雅法拉 | op-amgoat.js |
O2 | S3's lava has no splash; 乱火 maxima 15 / 15; S3 now casts by the larger-range rule (「攻击范围增大」) |
| 刻俄柏 | op-cerber.js |
O2 | 剥壳's ramp restarts per deployment |
| 霍尔海雅 | op-heyak.js |
O2 | S3's whirlwinds hit air units, nearest first; one not yet released drops when she leaves; ISW-A refused |
| 早露 | op-poca.js |
O7 | S3's strikes are her attacks, the first one tick after the cast; SIE-Y's distance bonus is linear |
| 提丰 | op-typhon.js |
O7 | S3's arrows are skill damage, not attacks (no SIE-X / SIE-Y bonus) |
| 娜仁图亚 | op-narant.js |
O7 | S1 (切换) stays on until she leaves; S3's boomerangs fly together and its blast is no attack |
| 逻各斯 | op-logos.js |
O3 | 语汇演化 rolls once per attacked target and may draw the attacked enemy |
| 真言 | op-mantra.js |
O3 | S2's first shot keeps the engine's bolt speed 11 (备注 10); only operators starting a skill grant 麻痹 |
| 维伊 | op-veen.js |
O3 | 战争技艺 restarts its 5 s with every stack; her energy store is now the engine's 秘术师 rule (WE1) |
| 左乐 | op-zuole.js |
O5 | S3's 7 slashes resolve at the cast and reach air units |
| 重岳 | op-chyue.js |
O5 | S2's second segment always fires; 止戈 rolls only on hits that leave the target alive |
| 煌 | op-huang.js |
O5 | S3's cuts deal 100 % ATK once a second (no blackboard key); the card keeps her 1-1 (the game shows 3-6) |
| 黑 | op-shwaz.js |
O6 | 正前方 = her straight line ahead, her own tile included; S3 DEFAULT (「攻击范围改为」 is a range change) |
| 鸿雪 (打字机) | op-bgsnow.js |
O6 | the 打字机 returns only while 鸿雪 stands and keeps its 25 s when she falls |
| 伊芙利特 | op-ifrit.js |
O1 | BLA-Δ's extra 元素伤害 also follows 灼地 ticks (_targetFamilyMask 31); 灼地's 2 % 流失 as stated |
| 谬因 (中继器) | op-aphris.js |
O1 | a huge enemy counts on every tile it covers; the 中继器's 无敌 / 孤立 / 禁疗 are kit flags; S2 area trigger (WE2) |
| 林 | op-lin.js |
O1 | the 琉璃璧 sits in the buff order (an earlier shield absorbs first); its burst comes before a knock-out |
| 年 | op-nian.js |
O14 | PRO-Y counts a teammate's 重装 on a shared field; 铁御 skips summons |
| 斩业星熊 | op-hsgma2.js |
O14 | AST-X's extra damage with or without a running skill; 我执 on the engine's 1-HP floor; normal attack physical (WE2) |
| 珊比 | op-thumpy.js |
O14 | the conveyor moves 0.533 tile/s (20 frames read per game second); S2 / S3 cast by the area rule |
| 森蚺 | op-zumama.js |
O15 | a blockee turning 无敌 + 无法选中 loses the S2 stun after one pulse; RA-A refused in 自选 (WE2) |
| 斥罪 | op-judge.js |
O15 | her barrier is spent oldest first (the client's priority −1000 would put it last); the thorns cannot be dodged |
| 黍 | op-shu.js |
O15 | the 【播种标记】 and the teleport end with S3; S3's TRY_SEARCH_ALLY_SKILL is now resolved in the data (WE2) |
| 帕拉斯 | op-pallas.js |
O9 | 休谟斯's own 精力充沛 is not merged with hers; S2 casts by the larger-range rule (「向前延伸」) |
| 止颂 | op-lessng.js |
O9 | S3 casts nothing under 晕眩 / 冻结 / 沉睡; S2's strike spacing is not modelled |
| 贝洛内 (牵绊) | op-demetr.js |
O9 | several 贝洛内 on one enemy share one 【手段】; every move is instant |
| W (此面向敌) | op-cqbw.js |
O12 | no cap on mines; 此面向敌 cannot be targeted; her knock-out withdraws the mines |
| 菲亚梅塔 | op-phenxi.js |
O12 | S1 follows the current client (no air targets, no range growth, trigger DEFAULT — PRTS 备注 of 2026-08-01) |
| 维什戴尔 (魂灵之影) | op-wisdel.js |
O12 | aftershocks 0.3 s apart; S3's last shell loses the +ATK (the engine's ammo rule) |
| 棘刺 | op-thorns.js |
O10 | the spikes carry the LOR-X addition; his poison keeps ticking after he left |
| 赤刃明霄陈 | op-chen3.js |
O10 | the first slash at the cast; a hiding target counts as gone; the 【移动】 lands at once |
| 司霆惊蛰 | op-leizi2.js |
O10 | currents outlive the skill, bounce off the field edge, use screen directions; S1 by the larger-range rule |
| 薇薇安娜 | op-vvana.js |
O11 | enemy content projectiles carry no isProjectile (melee for 散华); S3 area trigger (WE2) |
| 怒潮凛冬 | op-headb2.js |
O11 | the hammers are skill damage, lost while she is stunned; 高台 = the HIGH tiles of the field |
| 赫德雷 | op-hodrer.js |
O11 | S3's 流失 may knock him out; attack riders land even on a dodged hit |
| 假日威龙陈 | op-chen2.js |
O13 | the slime shot's selector range is her attack range at the attack; it outlives her |
| 莱伊 (沙地兽) | op-ray.js |
O13 | the 沙地兽 scouts 25 s, attacks nothing, returns after its redeploy time for 3 DP while she stands |
| 阿斯卡纶 | op-ascln.js |
O13 | 高台 = the level's HIGHLAND tiles (the forbidden rim too); separate 命中率 cuts roll apart |
| 涤火杰西卡 (机动盾牌) | op-jesca2.js |
O16 | a 机动盾牌 not next to her gets no turn, mark or aura |
| 机械师 (结构性原理) | op-mcnist.js |
O16 | the S3 charge lands free of DP; _ignoreTriggerOnce read as nothing |
| 凯尔希 (Mon3tr) | op-kalts.js |
O16 | S2 / S3 are heal skills on DEFAULT (no injured ally, no cast); PHY-X Lv3's half-HP blast once per deployment |
| 琴柳 | op-sleach.js |
O17 | 精神感召 saves DP only on a redeploy (the battle-start deployment is free here) |
| 可露希尔 (指挥中心) | op-closur.js |
O17 | 部署费用下限 has no counterpart (costs never drop below 0); her own tile counts beside the 指挥中心 |
| 澄闪 | op-gdglow.js |
O17 | her own attack stops in every skill (all drones out); S2 fires at full SP |
| 阿 | op-haak.js |
O18 | S2 / S3 keep the data's DEFAULT: with no ally in range the cast does nothing (settled by the data and the skill prefabs, §25.11.5) |
| 傀影 (镜中虚影) | op-phatom.js |
O18 | S3's push and status land on a dodged hit too; the twin is readied at his redeploy (WE1) |
| 弑君者 | op-crosly.js |
O18 | S2's blast lands at once; any action-stopping state or 缴械 cancels it |
| 老鲤 | op-lmlee.js |
O19 | 周围八格 = the 3 × 3 with his tile, flyers counted |
| 温蒂 (工程蓄水炮) | op-weedy.js |
O19 | S2 reaches air units; the cannon's forced skill fires once per deployment (data DEFAULT, re-checked in WE2) |
| 望 (棋子, 跟子) | op-wang.js |
O19 | 跟子 are kit records, no unit; placed 棋子 take and return her stock, so S1 / S2 keep cycling (the owner's decision of 2026-10-06, §25.11.1); 棋子 on any tile (WE2) |
| 多萝西 (共振装置) | op-doroth.js |
O20 | a used-up piece returns 5 s after the LAST trap deployment; the hand holds at most 9 |
| 予愿安洁莉娜 (“一会儿见!”) | op-aglna2.js |
O20 | flight 2 tiles/s, landing clips not modelled; the marker is no hand card (WE2); new status 缚地 |
| 黑键 (旧日残影) | op-ebnhlz.js |
O20 | his energies land with the main bolt; S2 at full SP with a free tile (WE2) |
| 麦哲伦 (龙腾) | op-mgllan.js |
O21 | 龙腾.F makes no attack (ATK 0); 3 summon pieces, 4 with SUM-Y (WE2); S1 casts on an enemy in a drone's range (§25.11.2) |
| 令 (清平 / 逍遥 / 弦惊) | op-ling.js |
O21 | her summons strike during S2 even when stunned; 3 pieces (WE2); S3 casts on a ground enemy in a summon's x-5 (§25.11.2) |
| 电弧 (戴乌 / 赛柯 / 桑特拉) | op-radian.js |
O21 | 桑特拉's link is its own attack with its own ATK; SO-A / SO-B refused in 自选 (WE2); S2 / S3 cast on an enemy in a summon's range (§25.11.2) |
| 淬羽赫默 (夜灯) | op-slent2.js |
O22 | 丰润羽翼 as 生命回复速度 rests on the client template (kept, §25.11.5; owner question) |
| 遥 | op-haruka.js |
O22 | her bubbles outlast her; the T2 heal uses the ATK of the grant (kept, §25.11.5; owner question) |
| 酒神 (本能的召唤, 迷狂牢笼) | op-phatm2.js |
O22 | 本能的召唤 lures at most 4 in all; its redeploys cost no DP; the 迷狂牢笼 blocks no sleeper (§25.9.1) |
| 白铁 (支援装置, 铁钳号) | op-ironmn.js |
O23 | the 铁钳号 is charged only by attacks that select it; 2 devices in hand (WE2) |
| 娜斯提 (支援装置) | op-nasti.js |
O23 | the built 高台's operator bonus (m4–m6_bonus) never applies |
| 死芒 (悲叹的仆役) | op-necras.js |
O23 | the servant consumed is the earliest made; S3's strikes are skill damage; S2's sleepers leave her servants' block (§25.9.1) |
| 凯尔希·思衡托 (战术锚点) | op-kalts2.js |
O24 | S2's shot flies at the engine's orb speed 10 (official 12); 战术锚点 placement (WE2) |
| Mon3tr (重构体) | op-monstr.js |
O24 | the 路标形态 marker is not placed; 重构体 placement (WE2); the chain heal jumps in the 3×3 (WE1) |
- ASSUMED (besides the table): the per-player stock, 8 at tier 5 and 5 at tier 6 (no table gives it); bots field no 自选 piece; 信标 sends no 自选 piece to a teammate; a prototype in a tier-5 and a tier-6 slot counts as two bond members; the reward offers' temporary refresh draws the player's 自选 pieces from the slot's level on.
- Golden: new family
diy(138 battles: every kitted owned operator in each form × module × skill at tiers 5 and 6, then the prototypes) and the matchcoop2-NORMAL-70-diy(a human seat on AI 托管 slotting 推进之王 and prototypes); each kit wave added its own scenarios, no other family moved. - Tests:
test/backups.test.js,test/diy.test.js,test/content/diy.test.js,test/content/kits_layout.test.js,test/content/op_*.test.js(71: one per kit, every form × module × skill),test/match/diy-shop.test.js,test/match/diy-bonds.test.js,test/lobby-diy.test.js,test/ui/diy-ui.test.js,test/golden-diy.test.js,test/assets-diy.test.js,test/ui/diy.e2e.test.js(SP_E2E=1).
25.5 Trigger rules: a larger running range casts as soon as an enemy is inside it; AUTO skills that need no target fire at full SP (W5C, W5F, the kit waves; the owner's decisions of 2026-10-05) — tools/build-data.mjs resolveTrigger / ACTIVE_RANGE_OVER / ATTACK_RANGE_CHANGE / UNIT_TRIGGER_CORRECTIONS / TRIGGER_ALLY_RULES, sim/skills.js setTrigger, §5.6
- Seen (community report): a skill that enlarges the attack range waited for an enemy inside the normal range, as the official basic strategy does (§20.2); the 0.2.0 audit after GitHub #124 found 35 AUTO skills among the 112 visible chess that never fired alone with full SP and no enemy.
- Official: PRTS 卫戍协议/帮助 技能策略 — DEFAULT casts on an enemy in the initial range; SEARCH on an enemy in the initial range; AUTO skills take no strategy row, so DEFAULT waits for the unit's own attack.
- Decision and now (the normative text is §5.6):
- ACTIVE_RANGE — the owner's deliberate deviation of 2026-10-05, like §21.29: a MANUAL skill whose running
range strictly contains the operator's own checks the DEFAULT condition on that running range every tick, no
attack needed (
rawRulekeeps the official row). First on the basic strategy (W5C: 33 skills / 66 records, e.g. 野鬃 S2, 银灰 S3, 莫斯提马 S3), then the SEARCH row and 深巡 S2 (W5F: 薄绿 S1, 蜜蜡 S1, 卡涅利安 S3, 玛恩纳 S2, 安洁莉娜 S3, 深巡 S2 — 39 skills / 78 records). The wording of a range change was widened as the kit reports found misses: 「攻击范围增大」 (艾雅法拉 S3), 「攻击范围改为」 (黑 S3: DEFAULT, not a 技能范围), 「攻击范围向前延伸」 / 「攻击范围朝…扩大」 (帕拉斯 S2, 司霆惊蛰 S1);UNIT_TRIGGER_CORRECTIONSfollows a live-client change the text misses (菲亚梅塔 S1 is DEFAULT since the 2026-08-01 client, PRTS 备注: no range growth, no air targets). A range the data cannot express is set by the kit: 珊比 S2 / S3 (her tile plus the glue / conveyor area), 谬因 S2 (the beam path,addTriggerRange), 薇薇安娜 S3 (3-2 from her second cast, the newskill.setTrigger). - 重装 of data/backups.json — the owner's decisions of 2026-10-05: the 重装 stand-ins and every 自选 重装 (森蚺, 涤火杰西卡, 斩业星熊, 年, 黍, 斥罪, 机械师, 珊比; 48 skill forms) cast with an enemy in range — DEFAULT, or ACTIVE_RANGE when the running range is larger — instead of the class row's TAKE_DAMAGE.
- AUTO skills that need no target fire at full SP (
SP_FULL; kits/README.md checklist item 5): 浊心斯卡蒂 S2 and 伺夜 S2 (W5C, after GitHub #124's 引星棘刺 S1), 纯烬艾雅法拉 S1 (the owner's decision of 2026-10-05, W5F), and in the 自选 kits every AUTO skill that acts on the operator itself, its allies or its summons (e.g. 谬因 S1, 维伊 S1, 莱伊 S2, 澄闪 S2, 多萝西's three). Skills that need a target keep waiting (a "next attack / next heal" skill, attack buffs). 伺夜 S1 / S2 cast only while his pack is on the field (PRTS 备注; the owner's decision of 2026-10-05 for S1, W5F; the 战术点形态, §25.6.5 and §25.7.9), 黑键 S2 only with a free deployable tile in range (§25.8.4). - Data aliases: 黍 S3's TRY_SEARCH_ALLY_SKILL resolves to SKILL_RANGE with
allieson its x-2 (TRIGGER_ALLY_RULES, §25.8.4). - Through summons — the owner's decision of 2026-10-06, the larger-range rule read through the summons' areas:
麦哲伦 S1, 令 S3 and 电弧 S2 / S3 also cast on an enemy in a standing summon's area the skill acts through
(
kits/shared/summoner.js summonTriggerArea, §25.11.2).
- ACTIVE_RANGE — the owner's deliberate deviation of 2026-10-05, like §21.29: a MANUAL skill whose running
range strictly contains the operator's own checks the DEFAULT condition on that running range every tick, no
attack needed (
- Kept on their rows: 烛煌 S2 / S3 (their ranges do not contain her 3-1), TAKE_DAMAGE 重装 skills of the chess pool but the §21.29 six, CUSTOM_RANGE skills, AUTO skills that need a target, SEARCH skills whose range does not grow.
- Golden: each step names its scenarios in its commit (the SEARCH / 深巡 step: roster-001 / 002 / 016 / 026 / 027 / 041
/ 042 / 044, bond-egirShip-low, bond-suntShip-high, boss-boss_2-pair, boss-boss_6-pair and the bot matches fielding
them; 纯烬艾雅法拉 S1: roster-038; 伺夜 S1: roster-028; the range-wording fixes: only
diy). - Tests:
test/sim/feedback5-active-range.test.js,test/sim/feedback1-tank-triggers.test.js,test/sim/feedback1e-skillrange.test.js,test/data.test.js(the counts),test/content/kits_alt_t3.test.js(伺夜),test/content/kits_alt_t6.test.js(浊心斯卡蒂, 纯烬艾雅法拉),test/content/feedback5-we2-area-triggers.test.js.
25.6 Fidelity fixes, wave 1 (W5C, W5E, W5J, W5L)
25.6.1 琳琅诗怀雅 S2 “见面礼” throws onto an enemy's tile on x-6, with no enemy needed (GitHub #116 item 2) — kits/ops/chess_char_3_04-swire2.js (installS2)
- Seen: the bomb landed only in front of her or nowhere. Official: PRTS S2 备注 — bomb range x-6; an enemy in range
gets it on its tile, else a random deployable tile (the client needs a free x-6 tile and her coin buff). Now: with a
coin and a free x-6 tile her attack turn throws: onto the first ground enemy's tile in her target order, else a random
free tile (in the field, empty, walkable melee ground, not a knocked-out operator's tile); damage, 停顿 and the 3 s
second hit unchanged. Item 1 of #116 (the solo 标准 shop prices) is not a bug. ASSUMED: the throw is instant and costs
one tick of her attack. Tests:
test/content/kits_t3.test.js(3 cases),summon_loadout_conflicts.test.js.
25.6.2 新硎 / 沉沙: one ATK layer while a 断刃 is held, gone with the last one (GitHub #107) — content/enemies/times.js (kitBlades)
- Seen: 新硎's ATK kept climbing (1350 → 3510 after two hits). Official: PRTS talent — ATK +80 % (沉沙's
blackboard 0.7) while holding 4 【断刃】, one spent per attack; the attack spending the last drops the bonus and clears
its cooldown; unspent blades become 矛头 on death (at least 1). Now: one layer from the spawn, removed by the
attack that spends the 4th blade, which is followed at once by the next (unbuffed) attack; death spawns max(1,
unspent) 矛头 at once (the 0.7 s delay is not modelled). Tests:
test/content/enemies_bosses.test.js.
25.6.3 A full 整备区 buys nothing; a freed slot pulls the 临时整备区 in (GitHub #82, second part, reported by Hucxious) — PlayerState.buy / pickReward / _fillHandFromTemp, match/invariants.js, match/bot.js
- Seen: a full hand still bought a third copy (it merged), and a freed slot did not pull the overflowed operator
back. Official: PRTS 卫戍协议/帮助 §手牌区 — with the 10 regular slots full, 招募 / 购入 are refused, merge or not;
temp pieces move in when a slot frees; board ↔ hand swaps stay allowed. Now:
buy/pickRewardrefuse withHAND_FULL(client: 整备区已满); everyrecompute()moves temp pieces into free slots (invariant: temp is non-empty only while the hand is full); bots never buy into a full hand and shed their weakest single for a third copy. ASSUMED: temp empties right → left into the hand's next free slot right → left. Golden: coop2-NORMAL-3, solo-HARD-9-boosted, coop2-ABYSS-10-boosted. Tests:test/match/feedback5-hand.test.js.
25.6.4 联防 plays on its own official map (GitHub #41 item 3, reported by Hucxious and shanzhaikabi) — tools/build-data.mjs buildStages, data/stages.json kind: 'unite', unite.js uniteStageId, match/unitePhase.js _uniteOpts
- Seen: the 联防 field showed the round's battlefield (water pools, crates) opened to both halves. Official:
act2autochess
level_act1autochess_escaped_single/_multi— one 19 × 21 road grid, no devices, runes or terrain; the right half is the own board + 8 columns. Now: twokind: 'unite'stage records (1 / 2 helpers,active: false) carry the 联防 battle in both combat modes; the client draws that map and restores the board after. No water, crates, devices or terrain in 联防; the BGM (PR #110) is unchanged. ASSUMED: the records' names 联防阵地(1名玩家) / (2名玩家). Golden: unite-1, unite-2 and the co-op matches. Tests:test/match/feedback5-unite-map.test.js.
25.6.5 伺夜's 狼群 has the official 战术点形态; S1 acts by the pack's state (PRTS 备注; the owner's decision of 2026-10-05) — content/tokens.js wolfPack / installWolfTacticalPoint / wolfReturnNow, kits/ops/chess_char_3_19-vigil.js
- Seen: a pack losing its last 狼影 died and came back after 10 s with 2 狼影; S1 fired and paid its DP with no pack
on the field. Official: PRTS 伺夜 talent and 狼群 备注 — the last 狼影 lost or a 撤退 turns the pack into its
战术点形态 (无敌, no attack) for the 25 s talent interval, then back with 1 狼影; S1 casts only with the pack on the field:
① the form returns at once, ② +1 狼影, ③ at the cap HP to max. Now:
installWolfTacticalPointkeeps a 'killed' / 'retreat' pack as a knocked-out piece (tile reserved) while 伺夜 stands, back after 25 s at full HP with 1 狼影; S1 is the kit's own cast in either form (+cost DP, ① ② ③). S2 in the form: §25.7.9. ASSUMED: the return is a redeploy (仇恨 order, deploy hooks); a form at the combat's end enters 联防 fresh. Golden: roster-007 / 009 / 026 / 028 / 040, bond-siracusaShip-high and the bot matches fielding 伺夜. Tests:test/content/kits_alt_t3.test.js,kits_t3,tokens_devices.
25.6.6 Touch: S3's extra heal, 「低于」 half HP, 攫升 on every heal, 超脱 on a dying exit (review of the stand-in kits) — content/tokens.js touchGospel / mapCharTalents, kits/ops/standin-acmedc.js
- Seen: S3's extra heal copied the boosted main heal; the boost applied at exactly 50 %; 攫升 missed self / zero
heals; 超脱 missed 余烬 exits. Official: PRTS Touch (卫戍协议) — the extra heal is 30 % of the main heal on x-5,
lowest ratio first, boosted itself on units 「低于」 half HP; 攫升 3 SP for any heal; 超脱 5 SP on dying exits too.
Now: the extra heal =
battle.heal(Touch, recipient, base × 0.3)once per heal action with its own boost; the boost strictly belowhp_ratio; 攫升 on every heal she outputs; 超脱 on a knock-out orBattle.retreat(…, { dying: true })(the 外勤医疗 strategy's Touch shares the code). ASSUMED: equal ratios go to the main target; 骑士戒律 + 竞技旗's exit counts as dying. Golden: roster-041, standin-03 / 04 / 08 / 09 / 10, coop2-NORMAL-14-standins. Tests:test/content/standin_acmedc.test.js,tokens_devices.test.js.
25.6.7 突袭: a passive skill that is on counts as 技能就绪 (GitHub #49) — content/bonds/addon/battle.js raidPoll
- Seen: 突袭 members with passive skills (缄默德克萨斯, 宴, 斯卡蒂 S2 …) waited for the 10 s idle trigger. Official:
PRTS 【突袭】 — idle 10 s or 技能就绪, no enemy in range → redeploy beside a ground enemy; nothing on passives. Now:
raidPollcounts a passive that is on, and since the PR #109 port a deploy-timed duration skill while its window runs (§25.9); §22.2's landing rule kept. ASSUMED: 「技能就绪」 = the skill is running. Golden: roster-039 / 046, bond-raidShip-low / high, boss-boss_2 / 4 / 6-pair, standin-01 / 06, coop2-HARD-4, coop2-NORMAL-14-standins. Tests:test/content/bonds_addon.test.js.
25.6.8 生命回复速度 is not 治疗 (GitHub #96 / #137; the separation proposed in PR #135 by @SpiritedAwayCN) — sim/damage.js (heal regen), professions.js bardRegen, kits of 魔王 ×2, 浊心斯卡蒂 (+ 海嗣), 调香师, 瑕光, 铃兰, 锡人
- Seen: per-second HP effects were heals, refused on 无法被友方治疗 / 禁疗 units (#96: 隐德来希 got nothing from 浊心斯卡蒂;
#137: 折桠 and 圣约送葬人 from 调香师). Official: PRTS 吟游者 raises 生命回复速度; the 备注 of 调香师, 瑕光 S2, 铃兰 S3, 锡人 S2 —
unaffected by 治疗加成 and 禁疗. Now: hpRegen buffs the provider refreshes, applied as the target's own regen tick (no
healing multiplier, no heal hook): the 吟游者 trait (
bardRegen), 调香师, 瑕光 S2, 铃兰 S3, 锡人; direct heals unchanged (引星棘刺 S1 / S2, 塞雷娅 S3, 流明's and 纯烬's HoTs stay heals). kits/README.md checklist item 11. ASSUMED: the buffs refresh from the start; two providers add up. Golden: 50 scenarios that field a converted operator (listed in the merge). Tests:test/content/feedback5-regen.test.js, the kits' tests,test/sim/professions.test.js.
25.7 WE1 — engine-fidelity follow-ups (sim rules)
25.7.1 秘术师 store energy at the attack check, not one interval later (GitHub #181, reported by Paper-Yuan) — professions.js installMystic (storeEnergy / releaseEnergy / hitsFn), ai.js updateAlly / performAttack
- Seen: 深靛 stood 4.2 s after binding the only enemy; with no enemy the first energy came after 6 s. Official:
PRTS 分支特性信息 §秘术师 — storing shares the attack interval: at the check, a target → attack; none and energy not full
→ store (an attack action); idle only when full. Now:
updateAllystores at the check when nothing is valid and restarts the interval;releaseEnergyspends the energies with the next attack, one arts hit each; 维伊 and 黑键 use the shared check. ASSUMED: a redeployment holds no energy. Golden: roster-003 / 021 / 022, bond-preciShip-high, diy-032, diy-114 and 13 matches fielding 深靛. Tests:test/sim/feedback5-mystic-store.test.js.
25.7.2 Enemy attacks strike at their damage frame; a short stun before it cuts the swing (GitHub #187 point 1, #170) — ai.js updateEnemy / enemyAttack / attackWindup / attackTargets, battle/spawns.js (enemy.swing)
- Seen: short stuns never stopped an enemy attack (忍冬 S3's stun showed, the hit still landed): a stun only paused
the cooldown. Official: PRTS 异常效果 — STUNNED cannot attack, DISARMED interrupts; the damage lands at the clip's
strike frame (data/enemies.json
attackAnim.hit). Now: an enemy with an attack clip strikes at its damage frame; stun / freeze / sleep / 浮空 / 缴械 / 恐惧 or losing every target before it cut the swing (restart from the wind-up), a stun in the cooldown only pauses it, shots in flight land; 36 of 249 kinds without a clip keep the old rule (§5.5; withdraws §22.14's ASSUMED). ASSUMED: targets re-taken at the frame; an interrupted swing keeps its cooldown. Golden: 275 of 283 scenarios moved (solo-HARD-2 now wins, coop2-NORMAL-8-serverrun loses in round 13). The owner kept the rule on 2026-10-06 (follow-up 29, §25.10). Tests:test/sim/feedback5-enemy-swing.test.js,feedback2-enemy-attack-stand.test.js.
25.7.3 武者: the trait heal on every damage instance, through the own 禁疗 (follow-up 1) — professions.js installMushaHeal / installReaperHeal, kits/ops/op-helage.js, op-zuole.js
- Seen: a 武者 healed once per enemy struck (a double strike healed once). Official: PRTS §武者 — 常态持有禁疗,
ignored by the unit's own trait / talent / skill heals; the trait heal follows every damage output. Now: one heal
per damage instance dealt to an enemy (skill, item and bond damage too; not dodged hits, 流失, element 损伤, talent or
DoT damage), passing
ignoreHealFree; 收割者 keeps its own rule. Golden: diy-007 / 008 / 009 (赫拉格), diy-033 / 034 / 035 (左乐); 宴 unchanged. Tests:test/sim/feedback5-musha-heal.test.js.
25.7.4 庇护 is one effect per unit, the strongest counts (follow-up 18) — kits/shared/tier1.js PROTECT / holdProtect, kits 宴, 余, 缪尔赛思, 赫拉格, 左乐, 赫德雷
- Seen: the older kits used private 庇护 multipliers, so two sources multiplied (25 % + 18 % → 38.5 %). Official:
ba.protect — same-name 庇护 take the highest (遥's bubbles use another key). Now:
holdProtectapplies the sharedPROTECTeffect (applyStrongest), refreshed by each kit; the 自选 kits already did. Golden: unchanged. Tests:test/content/feedback5-protect.test.js.
25.7.5 "治疗生命值低于50%…" compares as each module's client buff does (follow-up 19) — kits/shared/tier4.js installLowHpHealBonus, kits/shared/tier5.js lowHpHealUp
- Official: the client module buffs — LT for 瑕光 / 古米 / 塞雷娅 / 录武官 / Touch, LE for 华法琳 / 闪灵 / 黍 / 凯尔希.
Now: 华法琳's and 闪灵's PHY-X heal ×1.15 at or below 50 % (不高于), the LT ones strictly below; 黍 and 凯尔希 were
already ≤. Golden: unchanged. Tests:
test/content/feedback5-lowhp-heal.test.js.
25.7.6 链愈师: the heal jumps within the 3×3 around the last one healed (follow-up 27) — ai.js chainHealNext / doHeal, kits/ops/op-monstr.js
- Seen: 莎草's chain jumped within 2.5 tiles, Mon3tr's kit within the 3×3. Official: PRTS §链愈师 — jump range x-4
(3×3), no repeat, ×75 % per jump, lowest HP ratio first then the latest deployed, full-HP allies selectable, bound by
禁疗. Now:
chainHealNextserves the profession and Mon3tr. ASSUMED: a 禁疗 unit is never a jump target. Golden: roster-004 / 005 / 023 / 024, bond-sargonShip-low, diy-133 / 134. Tests:test/sim/feedback5-chain-heal.test.js.
25.7.7 One reading of charge_token[born]: the owner's redeployment readies a waiting summon (follow-up 20) — kits/ops/op-phatom.js, op-kalts.js
- Official: the client buff template —
charge_token[born]on the owner's birth (NORMAL timing); the other summoner kits read it so. Now: 傀影's (re)deployment readies a waiting 镜中虚影 at once, as 凯尔希's does Mon3tr. ASSUMED: NORMAL = usable now. Golden: unchanged. Tests:test/content/feedback5-summon-recharge.test.js.
25.7.8 Misery's S1 / S2 are deploy-timed duration skills (follow-up 12) — kits/ops/standin-acspec.js
- Now: 物理的服从 / 战争的恭顺 (PASSIVE / ON_DEPLOY, 10 s) are
kind: 'duration'withactivateOnDeploy— a start and an end at every deployment, the PR #109 contract; numbers unchanged. Golden: standin-01, standin-06. Tests:test/content/standin_acspec.test.js.
25.7.9 伺夜 S2 casts while the pack is in its 战术点形态 (follow-up 2) — kits/ops/chess_char_3_19-vigil.js (installGift)
- Now: S2 casts when ready while the pack is on the field in either form and holds no unused gift; in the form it
pays its DP at once and the gift waits for the returning pack. ASSUMED: S2's 备注 uses S1's words, so the form counts
as on the field. Golden: unchanged. Tests:
test/content/kits_alt_t3.test.js.
25.7.10 「同时攻击阻挡的所有敌人」 takes up to the block count of targets (the queued centurion question; Mon3tr S3) — ai.js acquireTargets / targetCount (hitAllBlocked)
- Official: PRTS §强攻手 / 重剑手 / 推击手 — max targets = the block count (≥ 1), blocked enemies first; the client
flag
_limitedMaxTargetNumToBlockedCnt. Now: an attack withhitAllBlockedtakes max(1, ⌊block count⌋) +maxTargetsmods targets from its range, blocked first (§5.5); Mon3tr S3 drops itsmaxTargets: 1. ASSUMED: the mods add to the block count. Golden: 52 scenarios with such an attacker. Tests:test/sim/feedback5-block-targets.test.js.
25.8 WE2 — fidelity follow-ups (data, match, UI)
25.8.1 Summon hand counts from the tokens' own talents (follow-up 21) — tools/build-data.mjs tokenTalentDeckBonus, match/player/diy.js placeableTokens
- Seen: placing 麦哲伦 or 令 gave one summon piece, 白铁 one device, 夜莺 one 幻影. Official: PRTS 卫戍协议/帮助
§战斗部署 — the hand gets as many summons as the deploy limit, not the initial stock; the owners' talents give 3 at once /
5 held (麦哲伦, 令, 电弧), 2 / 3 (白铁, 娜斯提), 幻影 3. Now: the token talents'
max_deploy_count/max_deck_stack_cntjoin the variant stats; hand counts 麦哲伦 / 令 3 (4 with SUM-Y), 电弧 3, 白铁 2, 夜莺 3, 娜斯提 2, 望 6 (TRP-X 7), 多萝西 9 (the hand's cap), others 1. Golden: unchanged. Tests:test/content/feedback5-we2-summon-hand.test.js.
25.8.2 望's 棋子 on any tile; no hand card for 予愿安洁莉娜's “一会儿见!” (follow-ups 22, 24) — tools/build-data.mjs TOKEN_POSITION_CORRECTIONS / summonRecord
- Official: PRTS 棋子 部署位置 全部位 (its 备注: the in-game summon info is wrong); PRTS “一会儿见!” is not selectable and
her
displayTokenDictis empty. Now: the 棋子'spositionis ALL (a 高台 too); a summon isplaceableonly when an owner displays it, so the marker stays out of the hand (the kit places it). Golden: unchanged. Tests:test/match/feedback5-we2-placement.test.js,test/content/op_aglna2.test.js.
25.8.3 Where 重构体 and 战术锚点 may stand (follow-up 26) — tools/build-data.mjs summonRecord, match/board.js positionClass / canPlace, match/player/placement.js _legal / summonExcluded / _liftOutOfRange
- Official: Mon3tr's 自我修复 — 重构体 on the ground inside her attack range; PRTS 战术锚点 — only ranged tiles outside
凯尔希·思衡托's attack range. Now:
ownerRangefrom the owner's talent, newownerRangeOutside/rangedTilesOnly; an owner turned or promoted so that her range covers the 战术锚点 sends it back with a toast; client and bot follow. ASSUMED: "ranged operators may stand on melee tiles" does not widen the 战术锚点. Tests:test/match/feedback5-we2-placement.test.js.
25.8.4 Triggers re-checked: 黑键 S2 at full SP with one free tile; 黍 S3's ally rule in the data (follow-ups 23, 17) — kits/ops/op-ebnhlz.js, tools/build-data.mjs TRIGGER_ALLY_RULES, sim/simdata.js normalizeSkill
- Official: 黑键 S2 (AUTO) 备注 — no deployable tile in range → no cast, so the condition is a free tile, not an enemy;
act2autochess
TRY_SEARCH_ALLY_SKILL(黍 S3) = an injured ally on the skill range. Now: 黑键 S2 is the kit's cast at full SP with a free attack-range tile; 黍 S3 resolves to SKILL_RANGE +alliesin the data (the kit override is gone); 温蒂's cannon (DEFAULT) and 凯尔希·思衡托 S2 (ACTIVE_RANGE on an injured ally) stay. Golden: diy-114 / 115 / 116. Tests:test/content/op_ebnhlz.test.js,op_shu.test.js.
25.8.5 Kit-side larger-range triggers: 谬因 S2 and 薇薇安娜 S3 (follow-up 16) — kits/ops/op-aphris.js, op-vvana.js, sim/skills.js setTrigger
- Now: the scan of the 41 kitted 自选 MANUAL skills found two whose running range the data cannot hold (§25.5): 谬因
S2's beam path is a content trigger range; 薇薇安娜 S3 switches to ACTIVE_RANGE 3-2 after its first cast of a
deployment (new additive
skill.setTrigger). ASSUMED: the owner's rule read through these kit ranges. Golden: diy-045, diy-078. Tests:test/content/feedback5-we2-area-triggers.test.js. The skills that act through their summons' areas (麦哲伦 S1, 令 S3, 电弧 S2 / S3) waited for the owner: §25.11.2.
25.8.6 自选 rosters refuse SO-A / SO-B / RA-A like ISW-A (follow-ups 25, 10) — shared/diy.js DIY_EXCLUDED_MODULE_TYPE
- Official: their texts name other modes (集成战略 / 生息演算); battle_equip_table gates them (
validInGameTag). Now:/^(?:ISW|SO|RA)-/modules are refused byvalidateDiyPicks, dropped bycheckDiyPicksand hidden by the picker. ASSUMED: the reason of the owner's ISW-A decision applies. Tests:test/diy.test.js,test/ui/diy-ui.test.js.
25.8.7 自选 in the match: random grants draw 自选 pieces, the banned line, AI 托管 (follow-ups 9, 11, 13) — match/player/diy.js diyStockEntries, effectsMeta.js rollChess / rollPool, ui/gameLogic/diy.js diyBannedPieces, ui/matchInfo.js, match/bot.js buyScore / levelUp
- Official: PRTS / the season notes — 自选 pieces widen the 调度中心's random range. Now: bands, items, 特质, 机变 cards
and reward pools that grant a random operator also draw the player's own 自选 stock (never another player's); a
slotted piece left out of the shop (every bond banned) is named under 本局禁用干员 in the briefing, the draft's match info
and the in-game tab; AI 托管 scores the player's own 自选 piece higher and levels 调度中心 one round earlier for its tier.
ASSUMED: the 托管 preference (bonus 12, one round). Golden: coop2-NORMAL-70-diy. Tests:
test/match/feedback5-we2-diy-grants.test.js,test/ui/feedback5-we2-diybanned.test.js,test/match/feedback5-we2-bot-diy.test.js.
25.8.8 Smaller items: 塑心's cap, 斩业星熊's normal attack, GitHub #148, the shims (follow-ups 30, 15, 3, 5) — content/garrisons/battle.js fireGain, tools/build-data.mjs classifyAttack, content/bonds/addon/battle.js raidTile
- 塑心 (garrison_90): the per-battle cap (10 / elite 20) is the trait instance's whichever bond is highest — a new highest
bond no longer opens a fresh cap (found in the PR #178 review;
test/content/feedback5-we2-garrison90.test.js). - 驭法铁卫 (斩业星熊): the data's normal attack is physical — arts only while a skill runs (display and AI only).
- GitHub #148 reproduced: a melee 突袭 member never lands on a 高台; on 战场#08 it lands on a 围墙 tile (deployable, drawn
raised), so no rule changed here (
test/content/feedback5-we2-raid-148.test.js); the owner then chose a landing tile where it can block (2026-10-06, §25.11.3). - The
kits/tier1..6.jsre-export shims andshared/standIn.js diyRecordare removed.
25.9 Ports from 0.1.4 (W5M, W5R and the feedback4 merges)
0.1.4 (§24, CHANGELOG 0.1.4) shipped from feedback4 while the refactor ran; every fix was ported by hand into the split
layout, with the golden moves each named: PRs #150, #66, #146, #74, #72, #103, #149, #109, #160 and W4A (高台 by the
trait, the 阿戈尔 revive slots, the 联防 devour) in W5M; PR #129 (teammate scouting); the restarted-cast events and 伊内丝's
影哨 before 不屈; PR #73 (operator battle voices, §21.30) and the settlement line's speaker; PRs #186, #134, #185, #24, #183
(their 42 new strings through t()); W4B (阿戈尔's devoured ATK as a 最终加算, a fallen marker's marks, 缇缇 S2's pulses,
§24.7 / §24.8); W4D (a sleeping enemy cannot be blocked, §24.9; W5R, §25.9.1) and W4C (a tap on the board stays on
its tile, §18.1; §25.9.2). Where a 0.1.4 change met 0.2.0 work:
- 突袭 × PR #109: deploy-timed skills became duration skills, which the #49 rule (a passive that is on) missed;
raidPollcounts a skill that needs no SP while its window runs (test/content/bonds_addon.test.js). - 一击即退 × PR #109: the generic deploy-timed passives (the 预备干员-特种 stand-in) are
kind: 'duration'too (content/generic.js; numbers unchanged). - The invite line (PR #103) × i18n: the copied line goes through
t(), Chinese byte-identical to the PR's. - 高台 by the trait × 补位: a stand-in is placed by its own trait (
placeClass,piecePosition); of the 自选 picks only 温蒂 carries the line. - Voices × 补位 / 自选: the stand-in or the 自选 operator on screen speaks for itself; the settlement line, which never
played (it looked up chess ids as character ids), now names the record the own piece shows (
screens/game.js ownShown).
25.9.1 沉睡 frees the block slot on the split layout; 酒神's 迷狂牢笼 skips a sleeper too (W4D, GitHub #140; ported by W5R) — sim/battle/blocking.js _checkBlock, sim/battle/status.js applyStatus, sim/ai.js updateEnemy, sim/buffs.js (sleep), kits/ops/chess_char_3_12-blemsh.js (瑕光 S2), kits/ops/op-phatm2.js cageBlock
- Port: §24.9 (the rule, PRTS 异常效果 SLEEPING = 无法行动+无敌+不可阻挡, the owner's decision of 2026-10-06), its §24
intro entry, the §5.5 Blocking sentence and §22.8's "(since §24.9)" came over from feedback4 unchanged; §24.9's heading
now names the 0.2.0 files above (0.1.4 had them in
sim/Battle.jsandkits/tier3.js). On the split layout_checkBlock(battle/blocking.js) refusesflags.sleepandapplyStatus(battle/status.js) releases an enemy that falls asleep. WE1's swing cut (§25.7.2) runs beforeenemyAttack, but a plain-buffflags.sleepstill makes the enemystun(units.js), so its release stays inupdateEnemy's cannot-act branch, after the cut: the swing is cut, the enemy is let go, and it stands until it wakes. - New on feedback5: 酒神's 迷狂牢笼 (O22,
cageBlock) blocked every unblocked enemy on its tile but the old three 不可阻挡 flags; it now skips a sleeper too (PRTS BLOCK_FREE 「无法阻挡/被阻挡」: no blocker of any kind). Before, the 牢笼 held the sleeper, refreshed its own HP and block count for it and lost it on the enemy's next update. 予愿安洁莉娜's S3 helper needed no change (canTargetEnemynever returns a sleeper). Followed without code:blockedTargets, the 要塞 branch ofacquireTargets(u.blocking), “庞贝”'s clock (blockedBy), the snapshot'sUF.BLOCKEDand the client's block marker; 死芒 S2 折朽 (自选) sleeps the enemies it links — one her 悲叹的仆役 held is let go, and SOC-X's ×atk_scale on "an enemy one of her summons blocks" no longer applies to it. - Golden (feedback5's own list; a probe over all 283 scenarios counted the sleeps of blocked enemies, in brackets,
and every scenario that moved has some; the outcomes differ from §24.9's because feedback5's baselines differ, WE1's
damage frame first): roster-003 (小满 S2 [5]: the same fight,
blocked27 → 29 and the snapshot hashes); roster-005 (elite 小满 S2 [3]: the 140 s timeout with 83 kills and 1 leak, where it cleared at 135.43 s with 84); roster-013 (缇缇 S3 [11]: the same kills,blocked22 → 33); roster-032 (缇缇 S1 [10]: 71 kills instead of 68, 8 leaks instead of 11, 4 knock-outs instead of 8, 萨尔贡 layers 41 → 35); roster-038 (elite 缇缇 S2 [1]: ends at 197.40 s instead of 197.27 s); roster-039 (瑕光 S2 normal + elite [31 + 12]: the same kills and counted leaks, the 窃贼 gets away,blocked53 → 87); roster-042 (缇缇 S2 [3]: ends at 168.77 s instead of 166.93 s); bond-maniShip-high (小满 [1]:blocked29 → 30, the snapshot hashes); solo-FUNNY-1 (ai_0's 缇缇 [3]: only ai_0's damage dealt); coop4-FUNNY-6 (ai_0's 缇缇 [15 + 56]: from round 9 ai_0's 精准 / 萨尔贡 layers and boss damage move, ai_1 loses no LP from round 11, team LP 124 → 130); coop4-ABYSS-7 (ai_2's 小满 [18]: ai_2 one kill fewer, ai_0 one more LP lost in round 9); coop2-NORMAL-8-serverrun (ai_1's 缇缇 [83]: only ai_1's damage dealt — WE1 had already turned this match into a loss); coop2-NORMAL-70-diy (the 自选 seat h_0's 缇缇 [171], ai_0's 缇缇 [74] and 小满 [19 + 21]: h_0's layers move from round 4, then its AI 托管 buys differently, boards from round 7; ai_0 246 kills instead of 233, the same end); diy-131 (死芒 S2 at tiers 5 and 6 [1 + 1]: the snapshot hashes only); diy-132 (elite 死芒 S2 [2]: ends at 199.50 s instead of 198.13 s, the same kills). coop2-HARD-4 sleeps a blocked enemy [1] and did not move: the sleeper wakes with no room and is blocked further on, and a match digest has no snapshot hashes (its kills, leaks, damage and funds are the same).fieldsandstandinsdid not move; no scenario spawns a 牢笼 over a sleeper. - Tests:
test/sim/feedback4-sleep-unblock.test.js(5 cases, from feedback4) passes unchanged on the split layout; every case fails with the three sim hunks reverted, case 3 (the plain-buff sleep) with only theai.jsrelease reverted.
25.9.2 A tap on the board stays on its tile; long browser waits poll in slices (W4C, the 0.1.4 release candidate; PR #149) — render/app.js onTapTarget, test/e2e/client.mjs waitForFunctionLong
- Seen (the 0.1.4 release candidate,
test/render/models.browser.test.js#4.1 touch): at 844×390 a tap on the row-12 unit opened the bond popup instead of selecting it. Cause: the browser's touch adjustment moves a tap onto a nearby element that responds to clicks (pointer listeners do not count) when the finger's contact area reaches one, and PR #149's 收起 toggle (§10) had pushed the bond discs one button (≈ 55 px) to the right, over row 12. Now (§18.1 Touch): the field canvas is a click target of its own (a no-opclicklistener,app.js onTapTarget), so a tap on the board stays on its tile; the browser test passes with #149's client diff reverted and fails with it. Ported as is (render/app.jskeepscreateFieldView, §25.1). - Test harness: the real-server browser suites' long waits poll in slices under the browser's 90 s CDP protocol
timeout (
waitForFunctionLong,PROTOCOL_TIMEOUT_MS). Puppeteer runs a wholewaitForFunctionpoll inside oneRuntime.callFunctionOn, so watch-bonds' 240 s wait died with a bare "Waiting failed" whenever the own battle outlasted 90 s (playtest2.real's 120 s wait had the same gap) — a harness timing flake, no product change. - Golden: unchanged (client and tests only). Tests:
test/ui/playtest2.test.js,test/e2e/client-wait.test.js; browser:test/render/models.browser.test.js(RENDER_E2E=1),test/ui/watch-bonds.e2e.test.jsandtest/ui/playtest2.real.e2e.test.js(SP_E2E=1).
25.10 Settled decisions, what stays ASSUMED, and the questions left to the owner
| Decision | Settled |
|---|---|
No web framework: plain node:http + ws (§25.1) |
the owner, 2026-10-04 |
| The 补位 plan: the 55 NORMAL chess droppable, all owned by default, no borrowing, bots own everything (§25.3) | the owner, 2026-10-05 |
| A not-owned chess shows as its stand-in everywhere (§25.3) | the owner's recall, 2026-10-06 |
| 自选编队: 2 + 2 slots, owned 6★ with a kit, any skill / module, prototypes locked, per-player shop, levels by the chess forms (§25.4) | the owner, 2026-10-05 |
| The collab 6★ out of the 自选 pool, 焰狐龙梓兰 included; ISW-A refused (§25.4) | the owner, 2026-10-05 |
| Chinese default, English switch, official EN game texts, PR #70 credited (§25.2) | the owner, 2026-10-05 |
| The larger-range rule (ACTIVE_RANGE) on DEFAULT, on SEARCH and for 深巡 S2 (§25.5) | the owner, 2026-10-05 (deliberate deviation) |
| The 重装 stand-ins and every 自选 重装 cast with an enemy in range (§25.5) | the owner, 2026-10-05 (deliberate deviation) |
| 纯烬艾雅法拉 S1 at full SP; 伺夜 S1 only with his pack on the field (§25.5, §25.6.5) | the owner, 2026-10-05 |
| Enemy attacks strike at their damage frame; a short stun before it cuts the swing (follow-up 29, §25.7.2) | the owner, 2026-10-06 (kept) |
| 望's placed 棋子 take and return her stock, so S1 / S2 keep cycling (§25.11.1) | the owner, 2026-10-06 (deliberate deviation from 「不消耗持有数量」) |
| Skills that act through summons cast on an enemy in a summon's area: 麦哲伦 S1, 令 S3, 电弧 S2 / S3 (§25.11.2) | the owner, 2026-10-06 (the larger-range rule) |
| A melee 突袭 member lands on a tile where it can block before one where it cannot (GitHub #148, §25.11.3) | the owner, 2026-10-06 |
| 华法琳's granted trait stops at the data's 7 / 14 (PRTS 3/27: lowered from 12 / 24; GitHub #175, PR #192, §25.13.2) | the owner, 2026-10-06 (replaces the 12 / 24 lock) |
| A newly merged elite 拉普兰德 is a new 拉普兰德: +8 on its first manual refresh of the round (GitHub #169, §25.13.3) | the owner, 2026-10-06 (was ASSUMED: the copies' count carried) |
| The leader pool = bloodPoint × the players alive when the fight starts, solo × 1 (PR #209, §25.13.4) | the owner, 2026-10-06 (replaces 「保持固定血量」; config restores it) |
| Flying units hover 1.3 tiles; 帝国炮火先兆者 ×2 drawn 1.263× taller, 木制瑞印 mirrored (PR #211, §25.13.5) | the owner, 2026-10-06 |
| A bounty pays whenever its enemy dies — terrain and other 无来源 deaths included, in 联防 too (§25.14.3) | the owner, 2026-10-06 (relayed with the community reports) |
Settled by the sources in W5V, no longer questions: 泥岩 S3's dormancy is 闭锁 — she lets go and blocks nobody (PRTS, §25.11.4); 阿 S2 / S3 keep the data's DEFAULT, 忍冬 S2's and 深靛 S1's notes are what the kits do (§25.11.5).
Still ASSUMED (each also in its code comment): potential 0 for every 自选 pick; the per-player 自选 stock 8 / 5;
bots field no 自选 piece; SO-A / SO-B / RA-A refused for ISW-A's reason; the AI 托管 preference for 自选 pieces; a
stand-in placed by its own position; the 联防 map names; 伺夜 S2 in the 战术点形态; the enemy swing's re-taken targets and
kept cooldown; a woken sleeper re-blocked in the enemy update order where it stands (§24.9); 望's card back in her hand
the moment a 棋子 leaves, a 棋子 over the cap lost, TRP-X's 7th placed 棋子 taking none, her stock kept through her
redeployment; 电弧 S2's area = 赛柯's 3-2 range, standing summons only; the official 突袭 landing taken as random among the
legal tiles, ranged members on the old order, the target's own tile counted as a blocking tile; 泥岩's 反制 during 闭锁
not modelled; the English of the remake's own strings; the lite zip without public/fonts, the zips' unchanged
package.json (maintainer scripts fail there); the 联防 payee of a bounty death no operator caused — the helper of the half
it fell on (§25.14.3); the stand-in and operator kit items of the tables above.
Left to the owner (none changed in 0.2.0): 淬羽赫默's 丰润羽翼 as 生命回复速度 (the client template, no PRTS note) and 遥's break heal on the ATK cached at the grant (both kept, §25.11.5); whether a passive counts as 技能就绪 for the whole deployment or its window only (§25.6.7); Stormeye S2 / Pith S1 (AUTO attack buffs) on DEFAULT or at full SP; 赫默 S2 and 巫恋 S2 (wasted with nobody to heal / no enemy); the AUTO cast of an attacker of 白铁's 铁钳号. Answered on 2026-10-06 and moved to the table: 望's stock and 阻回, the 突袭 landing (GitHub #148), the trigger areas through summons; settled by the sources: the ally condition for 阿 S2 / S3, 泥岩 S3's 闭锁.
Open polish (no rule): 34 or more of the 38 summons of the 自选 kits have no Spine skeleton in the online sources, so the
field draws them as the avatar placeholder (§25.12); scripts/make-windows-bundle.mjs still copies every tracked file
but test/ (it could reuse the package selection); the THIRD-PARTY-NOTICES "In the release bundle" column does not tell
the lite zip (no fonts) apart; the enemy prefabs whose default clips differ from the manifest's roles (猎狗pro, 大鲍勃,
碎骨, “斩胄之剑” / “破胄之锤”, §25.14.1).
25.11 The owner's decisions of 2026-10-06 and the items the sources settled (W5V) — kits/ops/op-wang.js, kits/shared/summoner.js summonTriggerArea, content/bonds/addon/battle.js raidTile, kits/ops/chess_char_4_18-mudrok.js
The questions WE2 and the kit waves had left open went to the owner as one batch on 2026-10-06; W5V implemented the answers and checked the remaining items against PRTS and the client (W5V's commits name every golden scenario moved).
25.11.1 望's placed 棋子 take and return her stock (the owner's decision of 2026-10-06) — kits/ops/op-wang.js
- Seen (O19, follow-up 22): in this mode her 棋子 are hand pieces deployed with the board, 「无视所属干员的持有状态, 不消耗持有数量」, so her stock stayed at 6; one S1 / S2 cast (「立即获得两枚棋子」) reached the cap 7, and 阻回 held her SP for the rest of the battle — the skill cast once.
- Official: PRTS 卫戍协议/帮助 §作战阶段 (placed summons ignore the holding; one that leaves is redeployed in place once the conditions are met); PRTS 望 铸子 (6 usable, 7 at most) and the S1 / S2 备注 (阻回 at the stock cap); the client's charge_token templates (the stock = cnt at her deployment, the skills' +cnt, S3's overflow built as 跟子); a summon that leaves returns to its owner's card while its redeploy time runs.
- Decision: the owner's decision of 2026-10-06, a deliberate deviation from 「不消耗持有数量」 — the placed 棋子 count in her stock, and a 棋子 that goes off or returns replenishes it by the official rules, so her skills keep working.
- Now: every deployment of one of her 棋子 (the battle start's and each in-place return) takes one from her stock (never below 0); a 棋子 that leaves the field (set off, or gone with her) puts one back at once, at most the cap; the in-place return also waits for one in stock. At the cap a 棋子 that goes off is lost to the cap and its return takes one, so the stock drops to 6, 阻回 lifts, her SP recovers and the next cast fills it again — S1 / S2 keep cycling. S3's "+8, the overflow as 跟子" starts from the lower stock (2 placed: 4 + 8 → 7 with 5 跟子, was 7).
- ASSUMED: the card is back in her hand the moment the piece leaves (its redeploy time is the return's own wait); a piece over the cap is lost; 7 placed 棋子 (TRP-X's deploy limit) on a stock of 6 — the 7th takes none; the stock carries through her mid-battle redeployment.
- Golden: unchanged (no corpus battle places her 棋子). Tests:
test/content/op_wang.test.js(9: the stock after the placed pieces, a piece set off and its return, casts up to the cap, 阻回 only at the cap, a piece set off at the cap, TRP-X's 7). Docs: docs/SIM.md (token pieces).
25.11.2 Skills that act through summons cast on an enemy in a summon's area: 麦哲伦 S1, 令 S3, 电弧 S2 / S3 (the owner's decision of 2026-10-06) — kits/shared/summoner.js summonTriggerArea, sim/skills.js (addTriggerRange { keys, profile }), kits/ops/op-mgllan.js, op-ling.js, op-radian.js
- Seen (WE2's scan, §25.8.5): their effects reach through the summons' areas, but the data's DEFAULT waits for an enemy in the operator's own 3-1 (no data range can carry the larger area).
- Official: no trigger row (DEFAULT). The areas (PRTS, the client): 麦哲伦 S1 — 停顿 / 束缚 on her range and each drone's range, air units too; 令 S3 — the x-5 around each summon, ground only (备注 「不可对空」); 电弧 S2 — 赛柯's bullets, ground only; S3 — 停顿 + 法术脆弱 before her summons' damage, air units too (备注 「召唤物可对空」).
- Decision: the owner's decision of 2026-10-06, the larger-range rule (§25.5) read through the summons: cast when an enemy is in the operator's range or in a deployed summon's area that the skill acts through.
- Now:
summonTriggerArea(battle, owner, skillId, area)registers a content trigger range (checked every tick, on top of the data's DEFAULT) built from the owner's standing summons, each giving{ keys, profile }— tile keys with the enemy profile the effect selects by (canHitFlyfalse: ground enemies only), a new additive entry form ofaddTriggerRange. 麦哲伦 S1: each drone's range, air units too; 令 S3: each summon's x-5, ground only; 电弧 S2: each summon's range (赛柯's 3-2), ground only; S3: each summon's range (桑特拉's 3-1), air units too. The other skills of the three get no area. - ASSUMED: 电弧 S2's area is 赛柯's 3-2 range, not its S2 bullets' longer flight (0.8 s ≈ 4 tiles at rank 7); only summons standing on the field count.
- Golden: unchanged (no corpus battle places a 自选 summon). Tests:
test/content/feedback5-wv-summon-triggers.test.js(an enemy in a summon's area outside her range casts the skill; a flyer there does not for 令 S3 / 电弧 S2 and does for 麦哲伦 S1 / 电弧 S3; nobody in an area, or the drone off the field: no cast; all three fail with the helper switched off). Docs: docs/SIM.md (content trigger ranges), theskills.jsheader.
25.11.3 A melee 突袭 member lands where it can block (GitHub #148; the owner's decision of 2026-10-06) — content/bonds/addon/battle.js raidTile
- Seen (GitHub #148, reproduced in WE2, §25.8.8): a melee member never lands on a 高台, but it lands on a 围墙 tile (drawn raised; it blocks nothing there) when that is the nearest tile covering its enemy, even with a road tile covering it too.
- Official: 「再部署至一名地面敌人周围」 — no tile preference stated.
- Decision: the owner's decision of 2026-10-06 — prefer a landing tile where it can block an enemy over a tile where it cannot; keep the rest of the landing rule.
- Now: for a melee member (position not RANGED) with a block count,
raidTileranks first the tiles where its block applies — ground units pass the tile (not a 围墙 / 围栏:Battle._blockerFor) and an enemy ground path runs through it (Battle.groundPathTiles) or its enemy stands on it — then the old order (nearest, then the facing frame). The rest of §22.2's rule is unchanged: the 8 most advanced targets in turn, a tile from which its range covers the target,grid.canStand(never a 高台, never the 深水区), free tiles, no useless jump. A 围墙 landing remains where nothing else covers the enemy. §24.2's note on #148 points here. - ASSUMED: the official landing picks among the legal tiles at random (the preference is the owner's); ranged members keep the old order; "its enemy stands on it" counts as a tile where it blocks (a target off the computed paths).
- Golden: fields
boss-boss_2-pair,boss-boss_3-pair,boss-boss_4-pair,boss-boss_6-pair,boss-boss_7-pair,hidden-boss_10-pair— their 突袭 members (伊内丝, 缄默德克萨斯, 仇白) now land on a road tile of the enemy path instead of a 围墙 tile (6 of the 8 changed landings) or an off-path road tile (2); roster / bonds / matches / standins / diy unchanged. Tests:test/content/feedback5-we2-raid-148.test.js(updated on purpose: every stage × every low enemy tile — never a 高台; whenever a tile where it blocks covers its enemy it lands on one; the old code fails at act1 m02).
25.11.4 泥岩 S3's 10 s dormancy is 闭锁: she lets go and blocks nobody (PRTS) — kits/ops/chess_char_4_18-mudrok.js
- Seen: the kit kept her blocking through the dormancy of S3 秽壤的血脉 ("keeps blocking").
- Official: PRTS 泥岩 S3 备注 — the first 10 s are 闭锁, not 无法行动, with 眩晕 / 冻结 / 沉默 反制; PRTS 异常效果 — 闭锁 (SHELTERING) = 强制缴械 + 无敌 + 不可阻挡, and 不可阻挡 (BLOCK_FREE) 「无法阻挡/被阻挡,自动解除阻挡」: on an operator, it blocks nobody and lets go of what it held (the enemy side of the same state: §24.9).
- Now: the dormancy adds the flag
noBlock(with invulnerable and disarm): the enemies she held walk on (ai.jslets go of anoBlockblocker) and she blocks none until she wakes. ASSUMED: the 备注's 反制 are not modelled. - Golden:
roster-040(it fields 泥岩 S3: the enemies she held walk on during the 闭锁). Tests:test/content/kits_alt_t4.test.js(updated on purpose: the 闭锁 releases the three walkers and blocks none — enemies placed on her tile neither —, awake she blocks again once their stun ends).
25.11.5 Settled by the sources with no rule change: 忍冬 S2, 深靛 S1, 阿 S2 / S3; the shared 庇护 — kit comments, test/content/feedback5-wv-sources.test.js, test/content/feedback5-protect.test.js
- 忍冬: PRTS's 「无法选中被自身阻挡而没有位于技能范围内的敌人」 is the 备注 of S2 坠刃拷问 (技能范围 3-12), not of S3 (its only 备注 is the ASPD update; the client's S3 selector is the standard 「同时攻击阻挡的所有敌人」 one); the S2 kit already selects on the 3-12 keys only — pinned.
- 深靛 S1: the S1 「每次攻击的攻击倍率」 applies to her stored energies (PRTS S1 备注; the client's ChargeAttackS1 reads the
same
atk_scale), as the kit does (ai.js resolveHit) — pinned. - 阿 S2 / S3: the data's DEFAULT — no trigger row names him; the skill prefabs cast with no target and keep the SP spent
(
_allowNoTarget1,_checkHasTargetBeforeDoCast0,_recoverSpIfNoTarget0); PRTS has no ally condition. With no ally in his range the cast spends its SP and does nothing; the kit comment records the sources. - 庇护: 淬羽赫默, 黍, 斥罪, 森蚺 and 娜斯提 grant it through the shared
holdProtect(kits/shared/tier1.js, §25.7.4), 遥's bubbles (their own key) through the sharedprotectMods; a guard test keeps kit-local copies out — a pure refactor. - Kept as they are: 淬羽赫默's T2 丰润羽翼 as 生命回复速度 (the client's buff template atk_to_hp_recovery: 禁疗 does not stop it, no 治疗加成) and 遥's T2 break heal on the ATK cached when the bubble is given (§25.10 keeps both open).
- Golden: unchanged.
25.12 Release packaging and the asset manifest (W5U; the 自选 voices) — tools/package.mjs (npm run package / package:lite), docs/DEPLOY.md §7, tools/assets/plan.mjs, tools/assets/manifest.mjs, tools/fetch-assets.mjs, data/assets.json
- Seen: 0.1.x releases came from a maintainer script outside the repository that zipped every tracked file (tests,
design docs, research notes, dev pages, the Windows-bundle maker) plus all of
public/assetsas it lay on the maintainer's disk; there was no smaller download. 焰狐龙梓兰 left the 自选 pool (§25.4) but her art stayed in data/assets.json, because fetch-assets refuses to shrink the manifest. The first real build found bothmodule/dec-X.pngandmodule/dec-x.pnglisted — one file on Windows / macOS, so a zip built there carries one. - Official: no game rule (release tooling). The collab exclusion is the owner's decision of 2026-10-05 (copyright);
the uniequip table spells one DEC X module
dec-X(uniequip_003_aglina) and the othersdec-x, andWAH-Yis the other mixed-case type id. - Now:
tools/package.mjsbuildsStronghold-Protocol-v<version>.zip(full) and…-lite.zip, each holding oneStronghold-Protocol/folder, from an allowlist overgit ls-files:server/,shared/,data/,public/(notpublic/dev/), the start scripts and the tools a player runs (setup, vendor, fetch-assets +tools/assets/, doctor, and what setup starts:tools/local-extract/, crop-board-atlas), the four research tables the server and fetch-assets read (03-operators,05-enemies,05-maps,07-assets), package.json / lock, LICENSE / NOTICE / THIRD-PARTY-NOTICES, README, CHANGELOG, docs/PLAYING.md and docs/DEPLOY.md;npm ci --omit=devin the stage adds node_modules and public/vendor. The full zip adds the files data/assets.json and data/local-assets.json list,public/fontsandpublic/assets/local/— nothing else on disk, so her 15 files and other orphans never ship. Every check also runs in--dry-run: the refusal list (0.1.x's plus test, .github, AGENTS.md, public/dev,.env/.venvanywhere); imports and the player npm scripts resolve to shipped files; all listed art is present; no two paths differ only in case; no shipped file holds a home-directory path or the machine's account name (text and binary, the name read from the OS at run time); no shipped tracked file has uncommitted changes; a real build also checks the stage against the plan. Measured on the 0.2.0 tree (before the voices below): full 421 421 613 bytes, 14 910 files, 589 MB unpacked; lite 22 088 912 bytes, 6 430 files, 85 MB; the 0.1.x layout of the same tree zipped to 429 644 767 bytes (569 files more, 25 MB more unpacked). Both stages boot;setup --checkpasses on the full stage and the lite stage plans the art offline. - The manifest: data/assets.json regenerated offline (
--offline --add-only --allow-shrink) drops her 8 subtrees (163 entries); module icons get one lower-case file per type (module/<type in lower case>.png:modules.dec-Xandmodules.WAH-Ychanged);resolveTemplatedrops an array whose lines are all missing (it kept{select: [], place: []}for the 71 自选 voice entries this machine had never downloaded); fetch-assets compares orphans (the--prunetargets) case-insensitively. Then (6499f4b)fetch-assets --add-onlyrun online added the battle voices of the 71 自选 operators — 994 lines, 25.5 MB,voiceChars120 → 191 (the manifest: 7 972 files, 485 MB) — and nothing else changed; the full zip grows by about as much. - Open (polish): 34 or more of the 38 summons of the 自选 kits (Mon3tr, 麦哲伦's drones, 令's summons, 电弧's towers,
白铁's piles, 娜斯提's devices, 望's 棋子 …) have no Spine skeleton in the online sources (fetch-assets: "missing skel"),
and the manifest lists none of the 38 with a model, so the field draws them as the avatar placeholder; extracting them
from a local client (
tools/local-extract) or keeping the placeholder is left for later. - ASSUMED: the lite zip leaves out
public/fontstoo (fetch-assets downloads the fonts with the art); package.json ships unchanged, so the maintainer scripts (npm test,golden,package) fail inside a zip; docs/img (the README screenshots), docs/WINDOWS.md, docs/ASSETS.md and the Dockerfile stay out (Docker builds from a git clone). - Golden: unchanged. Tests:
test/package.test.js(9, no network: the selection on samples and on the real tracked tree, the refusal list, a dry run and a--no-installbuild of a temporary checkout, the scans),test/assets-diy.test.js(nodiy.excludedoperator keeps art; one lower-case module icon per type; no two manifest URLs differ only in case; orphans compared case-insensitively),test/assets.test.js(the empty-array rule). Docs: docs/DEPLOY.md §7, the README download section (full and lite), docs/ASSETS.md.
25.13 Round 18: GitHub #207, #175, #169 and the community PRs #192, #209, #211 (W5Y; the owner's decisions of 2026-10-06) — server/match/builtinMeta.js, server/sim/content/garrisons/battle.js, server/match/player/acquire.js, server/match/gamedata.js bossPoolShareOf, render/units.js FLY_HOVER
The round-18 triage of the open issues and pull requests left three bugs and three community changes for 0.2.0; the owner decided the open questions on 2026-10-06. Each item is one commit (W5Y) naming the golden scenarios it moved; a ported PR credits its author there and here.
25.13.1 拟态物质 with 2 copies owned and the pool out gives nothing (GitHub #207) — server/match/builtinMeta.js (use_equip_reward_char_chess), server/match/bot.js itemTarget
- Seen (GitHub #207, reproduced in the triage): an elite 溯光星源 plus 2 normal copies hold all 5 of the Ⅵ阶 pool's copies (3 + 2); 拟态物质 on one of the normal copies gave a random same-bond operator (白面鸮 on that seed; 至简 is in the same roll). Also in 0.1.4.
- Official: the item text 「若已拥有至少2名该初始干员,则再获得1名该初始干员;否则随机获得1名同盟约初始干员」 — the 否则 is the case of fewer than 2 owned; research 06 §7: some effects fail when the copy cap is hit.
- Cause: with 2 owned the handler returned only when
grantChess(base)gave a piece; the null of an empty pool fell through to the same-bond roll. - Now: with 2 normal copies owned the item asks for the 3rd and stops there — none left in the pool, nothing is given (the item is still consumed); the same-bond operator is only for fewer than 2 owned. With copies left the 3rd copy still merges into the elite. The bots' carrier choice skips 2 copies whose pool is out.
- Golden: unchanged (no corpus match equips it on a pair whose pool is out). Tests:
test/content/items.test.js(the report — an elite and 2 normal 溯光星源, normal and golden item: nothing granted, no other operator, consumed; 2 copies with the pool drained: nothing; 2 copies with copies left: the elite),test/match/bot-smarter.test.js(no bot carrier on a pair whose pool is out). Docs: docs/META.md (built-ins, the bots' items), research 04 / 06.
25.13.2 华法琳's granted trait stops at the data's 7 / 14 layers (GitHub #175; PR #192 by @kukiC; the owner's decision of 2026-10-06) — server/sim/content/garrisons/battle.js, server/match/fields.js layerAllowanceOf
- Seen (GitHub #175): the card says 至多7层, but the operator in front of 华法琳 gained up to 12 layers per bond in a
battle (the elite: 24). The cause was the remake's own override
GRANTED_CAP_OVERRIDE(12 / 24 for garrison_95_a / _b, in the battle and in the server's client-result layer bound), taken from research 02 Addendum 1. Also in 0.1.4. - Official: PRTS 卫戍协议:盟约 下半, 3月27日更新#2调整 (revision 439189): 「[Ⅳ阶]华法琳:赋予的特质的叠层上限从 初始12/精锐24
降低至 初始7/精锐14」 — a nerf; the current 参战干员 record (下半/PRTS盟约记录) says 至多7层 / 14层, and the client
blackboard (
max_add_count_per_battle7 / 14) carries it with the other 3/27 numbers. The official notice 8584 says only 「调整每场战斗至多获得的层数」. Addendum 1 had read the PRTS line backwards (7 / 14 raised to 12 / 24). - Decision: the owner's decision of 2026-10-06 — follow the current page and the data: 7 / 14 (it replaces the earlier 12 / 24 lock).
- Now (ported from PR #192 by @kukiC): the override is gone; a granted trait keeps its data cap like a native one —
the 7th cast in front of 华法琳 reaches 7 (elite: 14) and later casts add nothing; the client-result bound counts the
handed-out trait at the same cap. Research 00 / 01 / 02 corrected (02-bonds.json's note, copied into
data/bonds.json
miraShip.spec.layerGain, regenerated offline — the only data change). - Golden: unchanged (no corpus battle casts 8 times in front of 华法琳). Tests (from PR #192):
test/content/garrisons_battle.test.js(updated on purpose: the cap is the data's 7 / 14 — the 7th cast reaches it, the 8th adds nothing),test/match/feedback1-gaps.test.js(the client-result bound with 华法琳 + 古米: 60 + 4·3 + 2 × cap passes, one more is refused),test/ui/playtest3.test.js(both cards show 至多7层 / 至多14层).
25.13.3 A newly merged elite 拉普兰德 is a new 拉普兰德: its first manual refresh this round adds +8 (GitHub #169; the owner's decision of 2026-10-06) — server/match/player/acquire.js _mergeChess, sim/content/garrisons/meta.js SERVER_GAIN_BOND_LAYER_BY_REFRESH_CNT
- Seen (GitHub #169, new comments): two white 拉普兰德 that had already fired this round merged into the elite, and the elite's next refresh added nothing. The triage confirmed the rest of the report is what the code does: each white copy fires +4 on the first manual refresh it witnesses, also in the 整备区 (§21.1).
- Official: garrison_123 「<刷新时>若为本回合首次主动刷新,使已激活的【叙拉古】层数+4,此干员在整备区时也有效」 (the elite +8;
bb
refresh_cnt1); PRTS 下半 3月27日更新#2 changed only the amounts (+3 / +6 → +4 / +8). No source says whether a merge resets the count; the code carried the copies' highest count onto the elite (ASSUMED, conservative, since 0.1.1). - Decision: the owner's decision of 2026-10-06 — a newly merged elite counts as a new 拉普兰德.
- Now:
_mergeChesscarries no per-piece round counter over (拉普兰德's refresh count is the only one): the elite starts at 0 like any new piece, so its next manual refresh this round adds +8 and a later one nothing; an in-place promotion (升华, 博士投影) keeps the piece and its count. A copy re-bought after a sale is still a new copy (ASSUMED, unchanged). - Golden: unchanged (no corpus match merges 拉普兰德 after a refresh in the same round). Tests:
test/match/feedback1-meta.test.js(updated on purpose: the elite made from copies that already fired adds +8 on its next refresh, once; new: two white copies refreshed this round, merge, refresh → +8). Docs: docs/META.md (the counter API, the edge cases), docs/PLAYING.md, the code comments.
25.13.4 The leader pool is bloodPoint per player alive when the fight starts (PR #209 by @qingjingshenghuo; the owner's decision of 2026-10-06); 胄's drone share passes 限伤 — server/match/gamedata.js bossPoolShareOf, server/match/finalAssault.js bossPoolHp, tools/build-data.mjs (config bossHpScale), sim/battle/combat.js loseHp, sim/content/bosses.js (死亡集群)
- Seen (PR #209): the author's play of the official mode — the leader pool grows with the number of players; the remake kept one fixed pool (co-op bloodPoint whatever the count, solo × 0.25 ASSUMED) since the owner's 「保持固定血量」 (§20.9 / §20.10).
- Official: activity_table bossInfoDict
bloodPointper difficulty, no per-player factor in the data; notice 5114's 「两侧的敌方领袖共享生命值(敌方领袖的总生命值不变)」 is about the mirrored copies of a pair field; the PR's rule is the author's observation (实玩反馈), not an official text. 假想敌:胄 (PRTS): a drone that dies 「令假想敌:胄受到最大生命值2%的真实 伤害」; 限伤 (research 11 §2.1) cancels any damage modifier of ceil ≥ 300000 on a leader. - Decision: the owner's decision of 2026-10-06 — adopt #209: the pool is the solo table value × the players alive when the fight starts; it replaces 「保持固定血量」.
- Now (ported by hand onto 0.2.0's files; the PR's one-line
data/config.jsonand itsdocs/BOSS_HP_ZH.mdtable were not taken — the data is regenerated, PLAYING §7 gives the examples):bossPoolShareOf(gamedata.js, used byGameData.bossPoolShareand byfinalAssault.bossPoolHpfor a plain game-data object): solo ×solo(1); co-op withperPlayertrue ×coop(1) × the players alive at the Final Assault's / Hidden Core's start (alivePlayers(): bots and AI 托管 seats count, eliminated and departed seats do not; at mostaliveFull4; a count left out = a full team). The globalconfig.bossHpScalecarries the rule (perPlayer: true, solo: 1); the modes' entries keep onlybloodPointKey(one place restores the fixed pool:perPlayer: false, solo: 0.25, its optional × alive / 4aliveScalingtoo). data/config.json regenerated offline: onlybossHpScale(global and per mode) changed. Leaders still ignoreenemyScale; parts and escorts keep their HP.- #209 documented, without fixing, that 胄's drone link (2 % of the pool,
DRONE_LINK_BASE 'pool') meets 限伤: the hidden 胄 终极 pool is 21 600 000 / 28 800 000 at 3 / 4 players, a drone 432 000 / 576 000, which the limit would cancel — drones would stop counting exactly in the largest fights. The share is no hit:Battle.loseHptakesnoHitLimitand the drone link passes it; a part's 传递 and every hit stay under the limit.
- ASSUMED: the drone share past the limit (the official client checks every damage modifier on a leader and PRTS calls the 2 % 真实伤害, but which max HP it reads is not documented — the remake reads the pool and keeps the share). The count is taken at each boss round's start, as #209 states (a seat that leaves before the Hidden Core no longer counts there).
- Golden: fields — the 20 boss / hidden scenarios (
boss-boss_1..7-pair/-solo,hidden-boss_8..10-pair/-solo): a pair field's pool × 2 (two players), a solo template's × 4 (solo × 1 instead of × 0.25); seven of them (boss-boss_1-pair,boss-boss_1-solo,boss-boss_3-pair,boss-boss_3-solo,boss-boss_5-solo,boss-boss_7-pair,hidden-boss_9-solo) now end at the 200 s cap instead of clearing; the two 联防 scenarios are unchanged. matches — 11 of 18:solo-FUNNY-2,solo-NORMAL-1,solo-HARD-1,solo-HARD-2now lose the Final Assault (team LP 0 with 93 088 – 176 395 of the pool left; solo leaders have 4× the HP);solo-FUNNY-1,solo-NORMAL-2,solo-HARD-9-boosted(its Hidden Core too) win with more leader damage (team LP −6 / 0 / −1);coop2-NORMAL-3,coop4-FUNNY-6,coop2-ABYSS-10-boosted,coop2-NORMAL-70-diywin with more leader damage (the pool × the players alive). Unchanged: the matches that end before R14 andcoop2-NORMAL-8-serverrun/coop2-NORMAL-14-standins(one player left at R14: × 1, as before); roster / bonds / standins / diy unchanged. - Tests:
test/match/boss-hp-scaling.test.js(from PR #209, adapted: every leader and difficulty × 1–4 players and solo; R14 / R15 leave out two departed players; AI 托管 and bots count, an eliminated player does not; config restores the fixed pool — the PR's test said the opposite —, the plain-object fallback agrees; only the leader's HP scales),test/content/enemies_bosses.test.js(hidden 胄 终极 at 3 / 4 players: the drone's 432 000 / 576 000 land, a hit of the same size is cancelled), updated on purpose:test/match/finalAssault.test.js(the per-player pool, the fixed pool restored through config, a mode entry overriding the global one),test/match/balance.test.js,test/match/bosshp.test.js,test/match/connection.test.js,test/docs-consistency.test.js(the §20.9 record points here; the data carriesperPlayer: true),test/sim/playtest6_limits.test.js(the drone share lands past the line),test/match/playtest6-bosspool.test.js(its 5 % knob halved to keep the two-player pool's size: that test is about the pool's arithmetic). Docs: PLAYING §7, DATA (bossHpScale), META, BALANCE, SIM, the design (engine.md 限伤, network.md boss rounds), the §20.9 / §20.10 records, research 00 / 01 / 08.
25.13.5 Flying units hover 1.3 tiles; the 帝国炮火先兆者 pair is drawn 1.263× taller and 木制瑞印 mirrored (PR #211 by @xcdoge; the owner's decision of 2026-10-06) — render/units.js FLY_HOVER / enemyModelScaleY (the mirror flip), tools/build-data.mjs MODEL_STRETCH_Y / MIRRORED_PREFABS, tools/local-extract/enemy_model_offsets.py, docs/research/12-flying-visuals-official.md
- Seen (player report of 2026-10-05, PR #211): 无人机等飞行单位位置明显偏低 — every flyer drew ~1 tile too low; the two 妖怪 drones had their art under the tile (the flat lift was 0.32 tiles).
- Official (read from the client by the PR's author, research 12): the fly offset is one model-independent constant,
Vector3(0, 0.35, 0)set byCharacterAnimator's constructor and added while flying; 0.35 is in the client's character space, whose unit is the standard battle-prefab scale 0.27 — 0.35 / 0.27 ≈ 1.3 tiles, and an official screenshot measures 1.2–1.4. The battle prefabs carry no per-model vertical correction for flyers. The same prefab sweep found two model quirks: the 帝国炮火先兆者 pair'sGraphicscale (0.19, 0.24, 0.24) (sy / sx 1.263) and 木制瑞印's negative X scale (a mirrored model). - Decision: the owner's decision of 2026-10-06 — take all of it (the lift and both quirks).
- Now (ported by hand; 0.2.0 regenerated its own data/enemies.json offline — the JSON compare shows only
enemy_1112_emppnt.modelScaleY,enemy_1112_emppnt_2.modelScaleY1.263 andenemy_1196_msfyin.mirrorX; the PR's one-line enemies.json was not taken):FLY_HOVER0.32 → 1.3, flat;enemyModelScaleYmultiplies the skeleton's Y scale and the head (bar) height, also in the impostor path; a mirrored model flips on top of the direction flip. The body, its HP bar, damage numbers, projectile hits and skill rings ride the lift; the shadow stays on the ground tile; range highlights are tiles; one camera drives the Pixi units over both the 2D and the three.js board, so both boards show it. Research 12 ported without the PR's claim that the owner had said 「都要」 on 2026-10-05, and corrected where the quirk enemies appear: 帝国炮火先兆者 is a FLY special enemy of the mode, 帝国炮火中枢先兆者 comes with the bounty 战术特训·飞行III, 木制瑞印 is in no wave of the mode. No screenshot or extracted art is committed; the extractor stays optional. - ASSUMED: the character-space → tile factor (1 / 0.27; the screenshot agrees within ±0.2 tiles).
- Golden: unchanged (drawing only; the sim reads neither field). Tests (from PR #211):
test/render/unitview.test.js(FLY_HOVER ≈ 0.35 / 0.27; the same lift for every flyer, the 妖怪 drones under the tile at the old 0.32; a flying view lifts by FLY_HOVER — added here: its body and HP bar ride the lift, its shadow stays on the ground),test/render/playtest6-enemies.test.js(exactly the two 先兆者 stretch and 木制瑞印 mirrors; the 1.263 aspect and the bar height; the mirrored model's opposite x sign). Docs: DATA §9 (modelScaleY,mirrorX), ASSETS (model size, flying units), research 00 / 12.
25.14 Community reports of 2026-10-06 (W5AA) — content/enemies/archetypes.js prisoner, render/units.js FORMS, tools/assets/spine.mjs PREFAB_SPINE_ROLES, sim/battle/economy.js _bountyPayee
The owner collected four community reports on 2026-10-06. Each was reproduced on the 0.2.0 tree with a script (and, where the report could be older, on the v0.1.2 / v0.1.4 sources), checked against the official data — the battle prefabs of the local client, ArknightsGameData's buff templates, PRTS — and the earlier decisions. Two were real and are fixed (W5AA's commits name every golden scenario moved); two were already fixed and are pinned.
25.14.1 「囚徒类敌人出门就是已解放的模型」: the 孤岛风云 prisoners leave the gate confined and change model as they are freed — content/enemies/archetypes.js prisoner, render/units.js FORMS, render/fx/kinds.js SILENT_PHASES, tools/assets/spine.mjs PREFAB_SPINE_ROLES
- Seen: 普通囚犯 / 老练囚犯 walked out of the gate drawn freed (a red collar light); no prisoner changed its model when freed (强壮囚犯, 拳师囚犯, 重犯 and 传奇重犯 stayed grey all battle), on the 2D and the 3D board alike.
- Official: each prisoner skeleton holds three clip sets whose collar light is grey, blinking orange and red. The
battle prefabs (local client
battle/enm_pfb_6.ab, read with UnityPy: the Graphic component's anim key → clip table, the modes' replace pairs, the clip the Spine starts on) draw mode Default — 【禁锢】 — on the grey set and start on it, mode R on the orange set and mode L — 【解放】 — on the red one. The buff templates (ArknightsGameDatabattle/buff_template_data.json):enemy_confinementstartsconfinement.timescharges;enemy_confinement[atk_cnt]spends one ON_BEFORE_ATTACK unless the prisoner has 麻痹 (PRTS 拳师囚犯 「在持有麻痹的情况下,攻击不计数」) and switches to mode R when one is left;enemy_liberty_listener[warning]switches to mode L before the next attack — PRTS 「进行第4次攻击前,切换至解放状态」. - Cause: the client's name-based role resolver gave 普通 / 老练囚犯 their unnumbered clips, which are the red (freed)
set — their grey set is
*3; FORMS had no prisoner entry and the sim sent no form. The sim also counted on the 'attack' hook, after the damage, so the 4th attack still hit confined. - Now:
prisoner()counts in thebeforehook (an attack 麻痹 interrupts never reaches it), sets the form 'warning' before attack times − 1 (fx 'phase', drawn silently — the blinking light is the model's) and 'liberty' before attack times (fx 'liberate', the white blast as before), so that attack already hits with the liberty bonus; 重犯's free-all and 杰斯顿's knock-out switch every freed prisoner too, and UnitInfoformgives a view built later the right set. FORMS maps 'warning' / 'liberty' for the six skeletons (普通 / 老练囚犯*2/ unnumbered, 强壮囚犯*2/*3, 拳师囚犯 / 重犯 / 传奇重犯*_orange/*_red).PREFAB_SPINE_ROLESgives 普通 / 老练囚犯 their grey*3set as the manifest's roles: data/assets.json regenerated (fetch-assets --offline --add-only, JSON compare: those twoanimsand the hash), data/enemies.json too (build-data --offline: theirattackAnim.clipAttack → Attack3, the same length and strike frame). The 3D board draws the same Pixi views, so both boards follow. - ASSUMED: none (the modes and their timing come from the prefabs and the buff templates).
- Found by the same audit (all 242 enemy prefabs against the manifest's roles), not changed, for later: 猎狗pro moves on
Run_Loop(manifestMove_Loop), 大鲍勃 attacks onAttack2, 碎骨 moves onMove_02, “斩胄之剑” / “破胄之锤” idle onIdle_A(a 0 s pose the resolver skips on purpose); 杰斯顿, 扎罗 and 再生 differ only in the death clip their FORMS already set. - Golden: 28 scenarios — the warning's 'phase' fx only: roster-001 / 003 / 007 / 024 / 033, bond-miraShip-low; the freed 4th
attack: roster-004 / 021 / 022 / 026, bond-kazimierzShip-low / raidShip-low / soloShip-low / victoriaShip-low /
visiShip-low, standin-01, diy-017 / 024 / 061 / 065 / 066 / 094 / 097 / 104 / 105 / 127, and the bot matches
solo-ABYSS-2, solo-HARD-9-boosted. Tests:
test/content/feedback5-prisoners.test.js,test/render/feedback5-prisoners.test.js,test/render/feedback5-prisoners.browser.test.js(RENDER_E2E=1, both boards). Docs: docs/ASSETS.md, docs/SIM.md, DESIGN §9 (design/client.md).
25.14.2 「敌人在忍冬技能范围内没有开技能,在攻击范围才开」: already answered by the larger-range rule (§25.5) — no change
- Checked: data/chess.json — S1 小施惩戒 DEFAULT (AUTO, no larger range), S2 坠刃拷问 SKILL_RANGE on its 技能范围 3-12
(§25.11.5), S3 隐狐之艺 (her default) ACTIVE_RANGE on its running range 2-2 (
rawRuleDEFAULT); she is in neither part of data/backups.json. On v0.1.4 S3 was on DEFAULT and cast only with an enemy in her 1-tile range — the report; on this tree it casts with an enemy two tiles ahead (not three), S2 on any tile of the 3-12. - Golden: unchanged. Pinned:
test/sim/feedback5-community-pins.test.js.
25.14.3 「被源石地板烫死的悬赏没给赏金」: a bounty enemy that dies with no operator behind it pays in 联防 too — sim/battle/economy.js _bountyPayee, sim/battle/deploy.js _remove
- Seen: a bounty enemy burned to death by the 活性源石 paid no bounty.
- Checked: on its own field it always paid its owner — all 96 walking kill-bounty enemies on 战场#04 with no
operator, on this tree and on v0.1.4: none unpaid. The loss is in 联防: a leaked bounty enemy re-enters carrying
bounty.ownerPlayerId= the leaker (unite.js planUnite), and a death without an operator killer fell back to that owner, who has no per-player entry in the 联防 battle, soaddCoinsdropped the coins. Until 0.1.3 the 联防 field was the round's map (GitHub #41), so 战场#04's 活性源石 burned leaked bounty enemies for nothing; the 联防 maps have no terrain now, but a 无来源 tick, the enemy's own HP loss or another enemy's hit still paid nobody. - Official: PRTS 卫戍协议:盟约 决策 「该敌人于对应玩家所属区域倒下时,使相应玩家获得额外资金」 — no exception for 环境伤害; the owner's decision (relayed 2026-10-06): the bounty pays whenever the body dies.
- Now:
_bountyPayee— an operator or summon of a player in the battle that dealt the blow pays its player (as before, a 联防 helper included); any other death pays the card's owner when that player fights there (own field, Final Assault / Hidden Core: unchanged), else the player whose half of the field the enemy fell on (_ownerForTile). - ASSUMED: the 联防 payee of a death nobody caused (no source names one; PRTS's 「于…区域倒下」 reads as the area's player).
- Golden: unchanged. Tests:
test/sim/feedback5-bounty-payee.test.js(the 联防 cases fail on the parent; the own-field 活性源石 death, a helper's operator on the other half and a pair boss field pinned). Docs: docs/SIM.md §1.2, docs/META.md, docs/PLAYING.md.
25.14.4 「悬赏敌人枯朽萃聚使徒召唤的枯朽之种被击杀也会获得赏金」: already fixed in 0.1.3 (§23.25) — no change
- Checked: the 使徒's BornBugs spawn its seeds through
spawnChildren, which drops the card'sbountyId/bountyCoins(§23.25); a seed never had abountyon the own field, so killing one never paid. On the v0.1.2 sources a bounty 使徒 whose seeds leaked sent every seed into 联防 carrying the card — 15 of 16 re-entries paid it again — which is the report; on this tree only the 使徒's own leak carries it. - Golden: unchanged. Pinned:
test/sim/feedback5-community-pins.test.js.
25.15 Rebindable shortcuts (W5AC; the community request 「快捷键可不可以自己设置」, the owner's decision of 2026-10-07) — ui/gameLogic/shortcuts.js, ui/gameLogic/settings.js sanitizeSettings, ui/settings.js (HotkeySection, hotkeyLabelOf), screens/game.js, ui/facingWheel.js
- Asked: players wanted to choose their own keys.
- Before: R 刷新, F 冻结, D 升级, Q 撤退 / X 出售 the selected operator (PR #114, 0.1.4), Space 准备就绪 (in a solo battle:
pause / resume) and Esc (close) were fixed in
shortcutFor; the shop bar, the ready / pause button and the underframe drew them as fixed text, the facing wheel swallowed Space andKeyR/KeyF/KeyD. No camera, speed or panel keys exist; the other keys are the dialogs', the guide's, 干员调配's and the facing wheel's own (Esc, Enter, the arrows, paging), listed with the shortcuts in docs/PLAYING.md §11. Nothing official to follow: the shortcuts are the remake's. - Now: the settings (localStorage
sp.pref.settings) holdkeys, action →KeyboardEvent.code; the defaults are the keys of 0.1.4, so nothing changes for a player who never opens the section.sanitizeSettingskeeps each saved key that may be a shortcut and gives any other its default; not a map, or two actions on one key, gives the defaults. One lookup,actionForKey— the action of the character typed (the keycap: AZERTY, Dvorak), else of the physical key (a Russian layout, an IME), the 0.1.4code === 'KeyR' || key === 'r'match generalised and identical for the defaults — servesshortcutFor(e, keys)in game.js and the facing wheel'sfacingSwallows; the modifier, text-field, repeat and overlay guards are unchanged. The key hints readhotkeyLabelOf. 设置 → 快捷键 (the one SettingsModal, in a match and on the title screen): each action with its key; a click — or Enter on the focused key — waits, the next key binds; Esc cancels and the dialog stays open, Tab leaves; a key held with Ctrl / Alt / ⌘ or one the interface keeps (Esc, Tab, Enter, the arrows, F1–F12) is refused and the wait goes on; a key another action has is swapped (that action takes the old key) and the line under the list names both; 恢复默认. Bindable: A–Z, 0–9, Space, the punctuation keys, Delete, Insert, Home, End, PageUp, PageDown; Esc stays fixed. On a touch-only device the section says the keys need a keyboard and folds the list; under 768 px it is one column. - ASSUMED: a conflict swaps rather than refuses (the request names neither, a swap never leaves an action without a key); Esc and the dialogs' own keys stay fixed; the bindable set; no modifier combinations (no shortcut used one).
- Golden: unchanged (client UI only). Tests:
test/ui/feedback5-hotkeys.test.js(the map, sanitising, conflicts, the lookup equal to 0.1.4 for the defaults on four layouts, capture, handlers and hints with a rebound key),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 Community reports of 2026-10-06, stream CB2: healers, summons, timers — kits/ops/chess_char_1_06-vendla.js, chess_char_3_04-swire2.js, chess_char_2_02-silent.js, content/tokens.js COUNTDOWN_SUMMONS / startCountdown, sim/snapshot.js unitTuple, render/fx/zones.js zoneAlpha
The owner's second collection of community reports (2026-10-06/07) was split over five streams; CB2 took the healers, the summons and the timers (items 11, 12, 13, 14, 18, 26, 31, 32, 33, 34 of the list). Each was reproduced on the 0.2.0 tree with a script first (on the v0.1.4 sources too where the report could be older), then checked against the official data — the local client's battle prefabs (charpack, token and skill prefabs, projectiles; abnormal flag ids per PRTS 异常 效果: 5 无敌, 7 禁疗), ArknightsGameData's buff templates, skill_table / character_table, PRTS (备注 included) — and the earlier decisions. Six were real and are fixed, one commit each with its golden scenarios named; four are answered with the evidence.
25.16.1 「刺玫开技能(装备源石药剂)之后不能治疗」 (item 12): only the S2 counter's trait heal goes to her protégé — kits/ops/chess_char_1_06-vendla.js
- Seen: during 荆藤庇荫 every trait heal went to the protégé, usually at full HP — a 源石溶剂 carrier drained from 1017 to 297 HP over the skill with all eight heals spent on a 9000 / 9000 ally.
- Official: 「该角色受到攻击时刺玫对目标造成攻击力20%的法术伤害并仅对该角色触发刺玫特性」 (en "…and activates her Trait on the
ally"); the client buff
vendla_trheals through the selector S2TraitHealRange (thevendla_s_2holder) only for a damage whose modifier carries the keyvendla_s_2— the counter,vendla_s_2[extra_damage]— else through TraitHealRange (_excludeOwner0, 禁疗 excluded). - Now: the counter's damage names the protégé (
traitAlly); every other damage she deals heals the lowest-HP ally of her range, herself included, skill running or not. - Golden: roster-001 / 002, bond-deputShip-low / -high, bond-suntShip-high, bond-victoriaShip-low / -high, the bot matches
solo-FUNNY-2, coop2-NORMAL-3, coop3-ABYSS-5, coop4-FUNNY-6, coop4-ABYSS-7. Tests:
test/content/feedback5-vendla-heal.test.js.
25.16.2 「琳琅诗怀雅不会治疗自己」 (item 18): S1 仗义疏财 heals her own tile too — kits/ops/chess_char_3_04-swire2.js
- Official: the client charpack (char_1033_swire2, mode S1, ability HealAlly) selects with range x-4 — the 3×3 with her
own tile —, ally side,
_excludeOwner0, max HP ratio 0.7, one target. Cause: the kit skipped her and kept Chebyshev distance 1 only. Now: the lowest HP ratio below 70 % of the 3×3, herself included (her own 禁疗 still stops it); the owner's cadence of 2026-10-04 is unchanged. - Golden: roster-027. Tests:
test/content/feedback5-swire2-self-heal.test.js.
25.16.3 「进入联防阶段琳琅诗怀雅所需的复活费用应该重置,正常对局中死亡之后再部署复活费用也应该重置」 (item 33): 破财消灾 restarts at 5 DP with every deployment — kits/ops/chess_char_3_04-swire2.js
- Official: PRTS 破财消灾 备注 「再部署时重置本天赋费用消耗」; the client buff
swire2_t_2doubles thecostof its own blackboard, rebuilt when she is deployed. Cause: the kit kept its save count for the whole battle (5 → 10 → 20 across a redeploy). Now: reset at each of her deployments (battle start, redeploy, 突袭 再部署); a 联防 field is a battle of its own, so it always started at 5 (pinned). - Golden: roster-008 (a cheaper save after a redeploy), roster-049 (snapshots only). Tests:
test/content/feedback5-swire2-revive-cost.test.js.
25.16.4 「赫默的无人机在2技能好了之后应该秒放」 (item 34): S2 医疗无人机 casts at full SP — kits/ops/chess_char_2_02-silent.js
- Seen: S2 full at 26 s and no cast while nobody was hurt; the drone came only once an ally in her range was injured.
- Official: the client skill
skchr_silent_2(AUTO) has no_trigger,_allowNoTarget1,_checkHasTargetBeforeDoCast0 and a RechargeToken action — no cast condition;_stopSpWhenTokenIsFull1 = PRTS S2 备注 「库存达到上限后赫默获得阻回, 直到库存被消耗为止」. - Now: trigger SP_FULL — the placed drone takes its tile the moment S2 is ready; 阻回 (
noSp) while her stock is full. - Golden: roster-003 / 005, bond-visiShip-low / -high. Tests:
test/content/feedback5-silent-drone.test.js.
25.16.5 「赫默的无人机、浊心斯卡蒂的海嗣等这种召唤物不会受到外来伤害(包括源石地板),也不会被干员治疗,血量随时间减少」 (item 26): the countdown summons — content/tokens.js COUNTDOWN_SUMMONS / startCountdown, sim/snapshot.js unitTuple, sim/units.js (countdown), the kits of 浊心斯卡蒂, 温蒂, 莱伊, 鸿雪, 酒神
- Seen: a 海嗣 on 活性源石 lost 70 of its 100 HP every second; a hurt drone drew every medic's heals and the 吟游者 regeneration; their bars were plain HP.
- Official / sources: PRTS 斯卡蒂的海嗣 备注 「持有禁疗、无敌」; the token prefabs give 海嗣 and 沙地兽 the abnormal flags 5 +
7, 工程蓄水炮 7; their lives are suicide buffs (
suicide_after_buff, the drone'sskcom_withdraw). The report describes the official mode: no outside damage, no heal, a bar that runs down like a timer and the summon gone when it is empty. - Now: the summons that "不会受到攻击" and leave after a fixed time — 医疗探机 (10 s), 诅咒娃娃 (15 s), 斯卡蒂的海嗣 (25 / 30
s) and the 自选 工程蓄水炮 (20 s), 沙地兽 (25 s), “打字机” (25 s), 本能的召唤 (10 s) — hold 无敌 + 禁疗 from each deployment
(
startCountdown, called where each lifetime is scheduled) and the snapshot's hp is maxHp × the share of the life left (unit.countdown). The sim HP stays full, so no selector sees a low-HP summon. Summons that block and are attacked (沙之碑, 战术装备, “小自在”, 结构性原理, 狼群 …) keep real HP. - ASSUMED: 无敌 + 禁疗 for the four whose base prefabs carry no flag (医疗探机, 诅咒娃娃, “打字机”, 本能的召唤), and the bar as a display of the time left — from the report; no HP-drain node exists in the client data.
- Golden: snapshot hashes only (the bar): roster-003 / 016 / 018 / 035 / 045 / 046, bond-visiShip-low / -high,
boss-boss_1 / 3 / 5 / 7-pair, unite-1; gameplay too: roster-005 (medics no longer heal the drone), roster-037 and
hidden-boss_9-pair (a 海嗣 / drone under damage stays up). Tests:
test/sim/feedback5-countdown-summons.test.js. Docs: docs/SIM.md (token pieces), docs/PLAYING.md.
25.16.6 「炼金师分支干员的炼金单元等范围持续性技能特效太亮(尤其是多层叠加以后)」 (item 14): stacked areas stay readable — render/fx/zones.js zone / zoneAlpha, render/fx/simfx.js, kits/ops/chess_char_5_15-thorn2.js
- Cause: 引星棘刺 S2's drifting unit was re-sent every second and drawn as a new additive zone for the rest of its life — up to twelve layers on one spot; overlapping units (锡人's charges, several alchemists) added up the same way.
- Now: the fx carries
keyand the client moves / resizes that one zone; a persistent area (> 3 real s) is drawn at 0.16 / 0.5 (disc / edge) and ÷ √n among the n persistent areas overlapping it; short bursts and telegraphs unchanged. - Golden: unchanged. Tests:
test/render/feedback5-zone-stack.test.js(node; no browser suite draws zones).
25.16.7 Answered with the evidence: items 11, 13, 31, 32 — no change
- 11 「链愈师…只能从周身8格里的干员开始,最远不会跳出攻击范围,…即使后续跳跃干员满血也会按照规则顺序跳跃」: the x-4 jump
around the last one healed and full-HP allies jumped in order are 0.2.0's WE1 (§25.7.6; on v0.1.4 a full-HP ally was
never jumped). The main target is the lowest-HP ally of the whole attack range y-2 (PRTS 分支特性信息), and the client's
chain selector (
projectile_chr_papyrs:_rangeIdx-4 around the hit,_maxTarget3) has no attack-range bound, so a jump may leave the range — not implemented. - 13 「有的持续造成伤害类的技能无伤害(如炼金师分支干员的炼金单元)」: not reproduced — every DoT skill of the pool and of the 自选 operators deals damage once its condition is met (a sweep with two layouts; on two real stages 锡人 S1 / S2 and 引星棘刺 S2 / S3 deal 13 000–134 000, the same on v0.1.4). The only zero is the hidden 锡人 record chess_char_1_16 (never in the shop) whose kit lacks S1. The stacked, over-bright zones (item 14) are the likely cause of the impression.
- 31 「伺夜的召唤物随时间增长的狼影最高能叠三只(即在新的狼影恢复前能受到三次致命伤害才死亡)」: what the sim does (kit pack
and placed piece, this tree and v0.1.4): 2 狼影 at deployment, 3 after 25 s, lethal hits 3 → 2 → 1 at full HP, the third
into the 战术点形态 — PRTS 狼群 备注. Pinned by
test/content/tokens_devices.test.js,kits_alt_t3.test.js. - 32 「吟游者的特性能恢复战术家的召唤物、不屈者分支干员的血量…(但赫默的无人机、浊心斯卡蒂的海嗣这种的血量不可以恢复)」: the
trait is 生命回复速度, which 禁疗 and 无法被友方治疗 do not stop (§25.6.8): 狼群 440 → 532 and 斥罪 1480 → 1618 HP in 3 s
under 魔王 (pinned by
test/content/feedback5-regen.test.js); 孤立 units stay out (PRTS 孤立). The countdown summons cannot be refilled since §25.16.5.
25.17 Community reports of 2026-10-06, stream CB3: operator kits and triggers — sim/ai.js resolveHit (hitDmgMul), kits/ops/chess_char_2_12-gravel.js, kits/ops/chess_char_5_05-ulpia.js, sim/battle/players.js onOwnBoard, kits/shared/tier1.js byEnemyAttack, content/items/battle.js revivedInPlace, tools/assets/audio.mjs pickUnitSfx
The owner's second collection of community reports (2026-10-06/07) was split over five streams; CB3 took the items about operator kits and skill triggers (items 2, 16.1, 16.4, 16.5, 17, 27, 28, 30, 44, 46, 54 of the list). Each was reproduced on the 0.2.0 tree with a script first (where the report could be older, on the v0.1.1–v0.1.4 sources too), then checked against the official data (character_table, skill_table, activity_table → act2autochess, audio_data, ArknightsGameData's buff templates, the local client's charpacks and skill prefabs) and PRTS (备注 included). Five are real and fixed, one commit each with its golden scenarios named; five were already answered or are not bugs (pinned by tests); one is a question for the owner (settled on 2026-10-07: §25.17.3).
25.17.1 「砾的平A是比较特殊的双判,是两次50%伤害倍率(不是攻击倍率)」 (item 16.5): two instances of 50 % 伤害倍率 per normal attack — sim/ai.js resolveHit, sim/professions.js (hitDmgMul), kits/ops/chess_char_2_12-gravel.js
- Seen: one damage instance per attack (measured: against DEF 300, ATK 352, one hit of 52), so a 频次 enemy lost 1.
- Official: PRTS 砾 特性备注 — in her attack animation every normal attack deals two instances, each 50 % of the final damage (after DEF / damage reduction, before 重设伤害), and the second triggers no 受击回复.
- Now: the profile field
hitDmgMul— the DamageInfomulof each of thehitsinstances on the main target, applied after DEF / RES and the damage multipliers,noSpon the later ones — and 砾's kit trait{ hits: 2, hitDmgMul: 0.5 }: two hits of 26 in the example (the same total), 2 per attack against a 频次 enemy. Both her skills are passive, so every attack she makes is a normal attack. - ASSUMED: the two instances land at once, at her attack's damage frame (the animation's second hit is not timed).
- Golden: 7 scenarios with 砾 on the board — roster-004 / 005 / 024, bond-indomShip-low / -high, bond-kazimierzShip-low /
-high (two damage events per attack; in roster-024 and bond-kazimierzShip-high the last blow lands on another instance,
so kills move between her and her neighbours). Tests:
test/sim/feedback5-gravel-double-hit.test.js. Docs: docs/SIM.md.
25.17.2 「乌尔比安使用3技能会在联防阶段跳到红门后」 (item 27): the S3 【移动】 lands only on his own board — kits/ops/chess_char_5_05-ulpia.js, sim/battle/players.js onOwnBoard
- Seen: on the one-helper 联防 map (act1autochess_escaped_single: the lone helper on the left half, the enemies out of the middle gate at col 10) an anchor that met no enemy flew on 6 tiles into the right half, where no enemy walks, and he stood there behind the red gate for the whole skill (reproduced: (10,7) → (10,13); on a solo boss field (2,5) → (2,11)).
- Official: PRTS 乌尔比安 S3 备注 ③ — the anchor tile if it can be deployed on, else the tile one beyond, else his own tile. "可部署" is a tile his player deploys on.
- Cause: "deployable" was any standable tile of the battle rect; UNITE_RECT spans both halves of the 联防 map and BOSS_RECT the hand / 临时整备区 rows and the partner's half.
- Now: the landing must also lie on his board —
Battle.onOwnBoard(ps, r, c), the board region GEO.FIELD mapped onto the field asmapTilemaps the pieces (the helper stream CB4 adds for the 突袭 landing; the hunk is identical). The anchor still flies its 6 tiles and blasts there; he stays when neither tile is his. - ASSUMED: that the official "可部署" excludes the other half of a shared field (the level files mark both halves buildable; no player deploys on the other's).
- Golden: 1 scenario — fields hidden-boss_9-solo (his first cast landed on the right half). Tests:
test/sim/feedback5-ulpia-own-board.test.js;test/sim/facing-invariance.test.jscounts every tile of its open field as the player's own (a board-position rule, like the deployment order it already avoids).
25.17.3 「乌尔比安3技能期间死亡会留在3技能位移后的位置复活,应回到初始部署位复活」 (item 28): back to his deployment tile — the owner's decision of 2026-10-07, a deliberate deviation from the sources — kits/ops/chess_char_5_05-ulpia.js, sim/battle/tiles.js _layBody, sim/units.js downAtHome
- Checked: knocked out during S3 he lies on the landing tile and comes back there — the rule of every operator moved
off its board tile since 0.1.1 (§21.24,
Battle._layBody): PRTS 卫戍协议/帮助 「原地留下一个“倒地干员”…自动部署至该位置」, whose one exception (「若干员被击倒的位置为其他干员或召唤物的初始位置,则…尝试返回其自身的初始位置」) does not apply to his landing tile. PRTS 乌尔比安 S3 备注 ④ (the 【返回】 at the skill's end) says nothing of a knock-out, and the client's S3 templates (ulpia_s3_*: the 【移动】 respawn clips and flags) carry no other rule. With §25.17.2 he can no longer fall behind the red gate. - Decision: asked whether to keep "where he fell" (the sources) or send him back to his deployment tile (the report), the owner chose the deployment tile (the owner's decision of 2026-10-07) — a deliberate deviation from PRTS's rule, for his S3 only: every other operator moved off its tile (a 突袭 jump, the 【移动】 of other kits) still lies and comes back where it fell.
- Now: his kit sets
Unit.downAtHomeonce the S3 【移动】 has put him on the anchor tile; the 【返回】 (the skill over with him standing) and every deployment clear it. Knocked out while it holds,Battle._layBodylays him on his home tile — his deployment tile, where the 从不混淆的方向 stood (gone with the skill) — and he redeploys there (timed, 不屈, or at once by CB1's 复活, §25.21.3); b.snapdownnames that tile, so the client draws him there. - ASSUMED: his deployment tile taken (a unit or another body on it) → where he fell, the one attempt of the PRTS exception above; a 突袭 member's jump tile before the S3 is not his deployment tile (his board home is).
- Golden: unchanged — the corpus moves him 23 times (roster-015, four solo boss fields) and knocks him out 6 times,
never while moved (instrumented). Tests:
test/sim/feedback5-ulpia-revive-home.test.js(3: knocked out during S3 he lies and redeploys at home, revived at home by M3茧甲 — both fail before —, and the control: after the 【返回】 and for a 突袭 member the PRTS rule holds). Docs: docs/SIM.md §1, DESIGN §5 (design/engine.md), docs/PLAYING.md.
25.17.4 「退行的潮涌者的攻击无法触发菲莱2技能的受击反击(排查其他类似技能的干员)」 (item 30): the 「受到攻击时」 counters answer every damage instance from an enemy — kits/shared/tier1.js byEnemyAttack, kits/ops/chess_char_3_06-philae.js and the kits below
- Seen: the report's 退行的潮涌者 is the 巢涌者 (深溟 / 富营养的巢涌者 in this mode): no normal attack, its talent hurts every operator in range once a second — and 菲莱 S2 never answered it (measured: 0 blasts).
- Official (ArknightsGameData buff_template_data): the pulse is an AdvancedApplyDamage with the enemy as its source
(
enemy_dsubrl_aoe[aura]); the counters fire on ON_TAKE_DAMAGE —philae_s_2with no filter at all, and on a source of the other sideinverse_damage(星熊 S2, from its skill prefab),inverse_damage[magic]+nian_s_2(年 S2),bubble_s_2/bubble_t_1(泡泡 S2, 尖刺盾),vendla_s_2(刺玫 S2),yu_s_1[inverse_damage](余 S1),hsgma2_s_1/hsgma2_e_003_tr_take(斩业星熊 S1, AST-X),mlynar_t_2[inverse](玛恩纳 无动于衷). 棘刺 S2 (a 普通伤害 filter) and 信仰搅拌机 S3 (any damage) were already right. - Cause: those kits required
dmg.isAttack. - Now:
byEnemyAttack= any damage instance from an enemy but a 流失 (PRTS 作战机制: 流失 triggers no 受击 events), an element 损伤, 无来源 damage or another counter / reflection (tagscounter/reflect, no ping-pong); 菲莱 S2 takes any instance but a 流失 or a counter.test/content/op_nian.test.jspinned "a non-attack hit returns nothing" for 年 S2 — updated on purpose. - ASSUMED: a hit fully absorbed by a shield still counts (ON_TAKE_DAMAGE fires on the damage instance); a dodged one does not.
- Found on the way, not changed: the pulse is
_ignoreForSpofficially (no 受击回复 SP, so it should not set off 雷蛇's talent either) and still gives SP here;content/generic.js's parsed counter still takes attacks only (no unit uses it). - Golden: 19 scenarios where an enemy's non-attack damage reached one of these operators — roster-002 / 005 / 008 / 010 /
012 / 016 / 033 / 044; bond-lateranoShip-low; fields boss-boss_2-solo, boss-boss_4-pair / -solo, hidden-boss_8-pair /
-solo; matches solo-FUNNY-1 / -2, coop4-ABYSS-7, coop2-ABYSS-10-boosted; diy-051. Tests:
test/sim/feedback5-counters-any-damage.test.js. Docs: docs/SIM.md (re-entrancy rule).
25.17.5 「突袭盟约的干员如果带被动技能,复活之后不会立马突袭出去,还要等突袭CD」 (item 44): a 复活 starts a deploy-timed skill again — content/items/battle.js revivedInPlace (since the CB1 merge reviveNow)
- Seen: 缄默德克萨斯 (S3) revived by M3茧甲 or 埃芒加德 with nothing in range jumped 10.00 s later; after 不屈's real redeploy 0.23 s later. After a timed redeploy every passive member already jumped at once (measured for 宴, 缄默德克萨斯, 斯卡蒂, 耀骑士临光, 伊内丝).
- Official: PRTS 盟约记录 备注 — 「复活」 is 退场 + a 0-time / 0-cost redeploy, a new deployment, after which a deploy-timed
skill runs again; a 突袭 member counts that running window as 技能就绪 (
raidPoll, GitHub #49 / #109). - Cause: the remake revives in place (a
fatalhook, §21.21): her window, over by then, stayed over and only the idle trigger was left. - Now:
revivedInPlacealso restarts anactivateOnDeployskill on the next tick — anew when its window had ended, back to its full duration when it still ran — so the member jumps at once; 砾 gets a fresh barrier, 缄默德克萨斯 a new sword rain. The SP reset and the other 部署时 effects of PRTS's form stay unmodelled (§21.21). - At the merge with CB1 (§25.21.3): CB1 models PRTS's form itself — the 复活 is a knock-out and an immediate free
redeploy (
reviveNow), whose skill reset starts a deploy-timed skill anew — sorevivedInPlaceand its restart were dropped; this item's tests (the jump at once, the window back to full, 砾's fresh barrier) pass on that model. - ASSUMED: none (§21.21's in-place form is gone with CB1).
- Golden: 1 scenario — roster-012 (the elite 缄默德克萨斯 revived in place three times). Tests:
test/sim/feedback5-raid-revive.test.js. Docs: docs/SIM.md, DESIGN §5.4 (design/engine.md, thefatalhook).
25.17.6 「干员银灰的普通攻击的音效错误的使用了3技能期间的攻击音效」 (item 54): an operator whose default mode is the unsuffixed ability never takes a skill mode's sound — tools/assets/audio.mjs pickUnitSfx, data/assets.json
- Seen: 银灰's normal attack swung with p_atk_silver_n and hit with p_imp_sword_n.
- Official (audio_data, the local client's charpack): his normal attack is the Default mode's Combat — impact
ON_ABILITY_HIT.char_172_svrash.combatp_imp_spear_n, no swing bank;.attack.2(silver swing, sword impact) is his S3 mode,.attack.1his S2 mode. - Cause: the picker's skill-mode test is by file name (
_d/_h/_s), and those files end in_n. - Now: an operator with a plain attack / combat bank (its default mode is the unsuffixed ability) never takes a
numbered variant; those that number their default mode (
attack.0…) keep the order. Of the 209 operators it changes 4: 银灰, 雷蛇 (S2's lightning impact), 初雪 (her S1-2 mode's impact), 圣约送葬人 (S3_End's impact). data/assets.json was regenerated offline (fetch-assets --offline --add-only --allow-shrink; JSON compare: those 4 entries, the hash and stats). 银灰's official impact file was not on disk yet, so his entry stayed empty in the stream; at the merge one onlinenode tools/fetch-assets.mjs --add-onlydownloaded p_imp_spear_n.mp3 (8.8 KB, the only new file) and the manifest lists his impact again (JSON compare with the stream's manifest:char_172_svrash.hit, the hash and stats). - Golden: unchanged. Tests:
test/feedback5-operator-sfx.test.js. Docs: docs/ASSETS.md.
25.17.7 Already answered or not a bug: 铃兰's trigger, 琳琅诗怀雅's champagne, the 突袭 玛恩纳, 归溟幽灵鲨 devoured, 荒芜拉普兰德 and 叙拉古 (items 2, 17, 16.1, 16.4, 46) — no change
- Item 2 「敌人在干员…铃兰技能范围内没有开技能,在攻击范围才开」: her default S3 狐火渺然 (「攻击范围扩大」, no class or charId
row) was DEFAULT up to v0.1.4 — an enemy in her own 2-tile range; 0.2.0's ACTIVE_RANGE (§25.5,
resolveTrigger) casts it with an enemy in its running range y-8 (3 tiles ahead), as for 忍冬 (§25.14.2). data/chess.json already says so. - Item 17 「琳琅诗怀雅的2技能的香槟只会在攻击范围内生成」: fixed by 0.2.0 WC (GitHub #116 item 2, §25.6): S2 “见面礼” throws
on the placeable, walkable ground tiles of range x-6 — her tile and two tiles up / down / left / right (PRTS 备注
「香槟炸弹放置范围:x-6」), onto an enemy's tile when one stands there. Pinned by
test/content/kits_t3.test.js. - Item 16.1 「突袭转职玛恩纳触发突袭的频率低很多…攻击范围里有怪的时候即使长时间没攻击也不会突袭」: the bond text itself — 「干员10秒内未进行攻击或技能就绪时,若范围内没有敌人」. A 解放者 never attacks with his skill off, so his 10 s are always met, and an enemy in his range (one he does not block keeps walking through it) is what holds the jump, as for every member. Should the owner have footage of the official game jumping with an enemy in range, that would be a new rule.
- Item 16.4 「归鲨被吃的时候不是变替身而是进了再部署」: not reproduced — an 阿戈尔 devour mark switches her to her 替身 on normal, 联防 and boss fields; a sweep of 400 random chains (241 marked, 201 lethal) on this tree and on v0.1.2–v0.1.4: never a knock-out. A player who does not own her fields her 补位 stand-in Sharp (近卫-无畏者, no 替身).
- Item 46 「荒芜拉普兰德开技能之后好像没有普攻了…叙拉古恐惧概率不高」: during her default S3 every drone is out chasing the enemies nearest to it (PRTS 技能流程), so she makes no attack of her own — the drones hit — and her attacks come back when it ends (measured). 叙拉古 6's true damage + fear is PRTS's rule: 0.139 % per 普通伤害 attempt, +0.139 % per miss, a counter shared by the player's members (3 % on average; measured 3.0 %).
- Golden: unchanged. Pinned:
test/sim/feedback5-cb3-pins.test.js(items 2, 16.1, 16.4, 46).
25.18 Community reports of 2026-10-06, stream CB4: enemies, bosses, waves, movement — sim/battle/players.js onOwnBoard, content/bonds/addon/battle.js raidTile, content/enemies/archetypes.js kitPolluted, content/enemies/special.js kitRush, targeting.js canTargetAlly
The owner's second collection of community reports (2026-10-06/07) was split over five streams; CB4 took the items about
enemies, bosses, waves and movement (items 6, 10, 16.3, 24, 29, 35, 36, 38, 39, 40, 47, 52, 53, 57 of the list). Each was
reproduced on the 0.2.0 tree with a script first, then checked against the official data (enemy_database,
enemy_handbook_table, activity_table → act2autochess, the level files) and PRTS (备注 included) and the earlier decisions.
The real ones are fixed, one commit each with its golden scenarios named; the rest are answered with the evidence.
Normative text touched: §5.5 (design/engine.md: 自制投石机's exception to "a stealthed ally is attacked only by the enemy
it blocks"); docs/SIM.md (onOwnBoard, the 索敌不受阻挡影响 target rule, the silenced 枯朽战士); docs/PLAYING.md (the
briefing types' share of the waves).
25.18.1 「…新约能天使在开了突袭之后蹦到了下方…临时放置溢出的干员和道具的那一栏高台」, 「单人联防时突袭也可以跑到对面的场地上」 (items 40, 16.3): 突袭 lands only on its player's own board — sim/battle/players.js onOwnBoard, content/bonds/addon/battle.js raidTile
- Seen: in a solo leader round a ranged 突袭 member (新约能天使 with the 转职球 and the 突袭手雷) jumped onto the boss field's 临时整备区 row; in a 联防 with one helper a member jumped onto the right half of the map.
- Cause:
raidTiletook any tile of the battle rect its position may stand on (grid.canStand). BOSS_RECT holds rows 0–5, so the boss field's hand row 0 and 临时整备区 row 1 (tile_achand: high ground, buildable ALL) were landing tiles for a ranged member (reproduced: an enemy on the left telin (1,3) of 战场#01 drew the member onto the hand tile (0,3)); UNITE_RECT spans both halves of the 联防 map (cols 0–20) while a lone helper's board is the left half (escaped_single's deploy tiles: cols 3–9), and on a pair field a member jumped onto its partner's half. - Official: the bond text 「保留技力立即再部署至一名地面敌人周围」 — a 再部署 goes where its player deploys; the stage data
lists each player's deploy tiles per half (data/stages.json
deployTiles: normal, bossLeft, bossRight). - Now:
Battle.onOwnBoard(ps, r, c)— the board region (rows 9–12, cols 2–10) mapped onto the field asmapTilemaps the player's pieces (the right-hand helper's +8 columns, the boss rows 2–5, the mirrored right half) — andraidTiletakes only those tiles; a target only reachable from elsewhere is skipped (the next candidate is tried, else the member stays and the next poll looks again, as before). - ASSUMED: none beyond §22.2's landing rule (the official landing tile among the legal ones is not known).
- Golden: 8 scenarios, each a member that used to land on the other half (checked with the parent instrumented):
boss-boss_2 / 3 / 4 / 5 / 6-pair, hidden-boss_8 / 10-pair (members landing on the partner's half, 1–7 per battle) and
the bot match coop2-ABYSS-10-boosted (ai_0's members on the right half of its leader fields). Tests:
test/sim/feedback5-raid-own-board.test.js(4 cases; each fails on the parent). Docs: docs/SIM.md (onOwnBoard).
25.18.2 「沉默效果没有沉默枯朽战士敌人,枯朽战士敌人被沉默之后死亡依然留下了毒」 (item 10): silenced at its death, 萨卡兹枯朽战士 releases no 污染秽蚀 — content/enemies/archetypes.js kitPolluted
- Seen: a silenced 萨卡兹枯朽战士 (组长) still left its poison zone when it died (reproduced: 150 HP in 3 s to its blocker, silenced or not).
- Official: PRTS 萨卡兹枯朽战士 天赋 「{{特殊机制|死亡爆炸}}(释放半径2.0,持续8s的【污染秽蚀】)」; PRTS 特殊机制 死亡爆炸
「如无特殊说明,此能力默认可沉默…若不处于沉默状态,将会…释放」. The client agrees: the battle prefab's PollutedDie
ability is a buff of template
projectile_on_killed, whose ON_OWNER_KILLED checksCheckAbnormalFlag SILENCED(unset) beforeEmitProjectile— the same template as 高能源石虫's blast. Its handbook line alone is NORMAL (高能源石虫's is SILENCE), so the rule "sil= the handbook's SILENCE lines" (content/enemies.js) missed it. An audit of all 243 enemy prefabs of the local client (every ability's buff templates; those whose ON_OWNER_KILLED checks SILENCED: 11 enemies) found one more NORMAL line of that kind — 刺胄之弹's blast, a part of 假想敌:胄 (not changed, for later: its blast is triggered by its arrival); the other nine are SILENCE lines our kits already silence. 萨卡兹枯朽战车's 秽蚀轰击, also NORMAL, stays unsilenceable (its skill node has_ignoreSilence1). - Now: kitPolluted's death ability is
sil; the silence test of every authored enemy names the two keys as the template exceptions. - Golden: 5 bot matches, each with silenced 枯朽战士 deaths (14–83 per match, counted instrumented): solo-NORMAL-1,
coop2-NORMAL-3, coop4-ABYSS-7, coop2-NORMAL-8-serverrun, coop2-NORMAL-14-standins. Tests:
test/content/enemies_bosses.test.js(the silence rule, the two keys silenced and after a silence ran out; 3 fail on the parent).
25.18.3 「每局游戏开始展示的敌人类型(折射、飞行等等),实际出现波次在7到9波,而且每个最多三波,其余波次用特异类型填充」 (item 6): already the official schedule — no change
- Checked:
setupMatchWaves(research 08 §2.1, decoded from the client'sRandomEnemyGenerater): each of the three briefing types owns 3 of the 15 round slots, SPECIAL (特异) the other 6, shuffled, one type per round. R14 (the leader) and R15 (the hidden core) take slots too, so the 13 normal rounds of 险境 / 绝境 / 终极 hold 7–9 type waves — 400 seeds per mode: 7 in 141 matches, 8 in 192, 9 in 67; per type 1–3 — and every other wave is SPECIAL (solo 标准: 8 normal rounds, 3–7). Exactly what the player describes. - Official: act2autochess
specialEnemyRandomTypeDict(count 3 per random type, SPECIAL −1), constDatamaxLevelCnt15,specialEnemyNum3,enemyTypeIdentifierToFillRandom1 (SPECIAL). - Now: docs/PLAYING.md states it at 确认本局信息 (the report: 「更新日志和机制描述也没写」).
- Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js(the 7–9 and the 1–3),test/match/waves.test.js(3 of the 15 slots each).
25.18.4 「敌人新硎提升攻击力的断刃好像无限消耗,实际应当攻击一次消耗一个,具体有几个复核」 (item 53): already fixed in 0.2.0 (§25.6.2, GitHub #107) — no change
- Checked: on v0.1.4 新硎's ATK went 2430 → 3510 → 4590 → 5670 and stayed (a layer per attack, none removed) — the report. On this tree: 4 attacks at 2430 (+80 %), the 4th spends the last 断刃 and ends the bonus, the next swing comes at once at 1350; killed, max(1, 4 − spent) 铁矛头 (沉沙: +70 %, 铜矛头).
- Official: PRTS 天赋 (4 【断刃】, one spent per successful attack); the client's template
enemy_dead_spawn[sfji](battle prefab enemy_1207_sfji_2): ON_OUTPUT_ATK_OR_HEAL — whilecnt≥ 1,cnt+=cnt_add(−1) and one blade marker goes; ON_ABILITY_FINISH —cnt≤ 0 ends the ATK buff and switches to mode 1 (无断刃模式); ON_OWNER_KILLED (not 坠落) — summonscnt(at least 1). - ASSUMED: the client spends a blade per damage output; here every attack spends one, so an attack an operator dodges spends one too.
- Golden: unchanged. Pinned:
test/content/enemies_bosses.test.js(the #107 test).
25.18.5 「囚犯敌人的解放状态联防时不应继承」 (item 57): already answered (§25.14.1) — no change
- Checked: a leak re-enters 联防 as a new spawn —
planUnitepasses on its key, spawn mods, LP and bounty only, andbuildUniteWavespawns it — soprisoner()starts it confined (the 禁锢 buff, no form) and only its own attacks there free it; the client drops every view when a battle starts. The freed look was 普通 / 老练囚犯's red clip set, drawn from the gate until §25.14.1. - Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js(freed in its own combat, leaked, confined in 联防, freed at its 4th attack there).
25.18.6 「萨卡兹穿刺手被眩晕或者减速恢复之后移速不会重置(降低),伤害也异常」 (item 36): a stun or 束缚 ends its acceleration; its first hit adds speed × 600 — content/enemies/special.js kitRush
- Seen: after a stun it walked on at the speed it had built up (it even kept accelerating while stunned: 1 → 1.5 in a 2 s stun); its first hit after a block was one multiplied attack (×(1 + 6 × layers / 25), 2286 at 17 layers), also after a stun that came in between.
- Official: PRTS 天赋 「每0.1秒检测一次:①若受晕眩/束缚影响,停止加速 ②若未被阻挡,开始加速…每0.5秒尝试获得1层移动速度+50%
的增益,最多尝试25次(增益于停止加速时解除…),同时普通攻击附加的Buff会额外造成一次当前移动速度×600的…物理伤害并停止加速」. The
battle prefab agrees: listeners every 0.1 s end
dlancer_t[trigger]on STUNNED (a) or UNMOVABLE (b) and start it when not blocked (c); the trigger stacks a MULTIPLIER move-speed layer every 0.5 s, blocked or not; the FirstAttack buffdlancer_t_atkdealsDamageViaAttrMOVE_SPEED × atk_scale (physical, melee, ignoreForSp) while the trigger exists, then ends it. A slow (减速) is no reset — the report's slow is the official behaviour; it only lowers the speed while it lasts, and so the extra damage. - Now: kitRush follows the templates: a 0.1 s listener (晕眩 / 束缚 statuses end the acceleration and drop its layers; not blocked starts it, from the spawn), a layer every 0.5 s up to 25 tries, the extra damage = its current move speed × 600 as a second, non-attack physical instance with no 受击回复, ending the acceleration (so a block's first hit only). Reproduced after the fix: 2 s stun → base speed, a fresh build-up; blocked at 2.375 → 450 + 1500 (2.5 × 600, one more layer before the hit).
- ASSUMED: 冻结, 沉睡 and 浮空 do not stop it (they set FROZEN / SLEEPING / LEVITATE, not the two flags the listeners read); the client's 0.1 s listener order is folded into one check.
- Golden: 6 scenarios, each with 萨卡兹穿刺手 in it: roster-016, standin-04, standin-08, diy-028, diy-124 and the bot match
coop2-HARD-4 (160 spawned). Tests:
test/content/enemies_bosses.test.js(3: the layers and the cap, the resets, the first hit; all fail on the parent).
25.18.7 「玩家的官方原版反馈:「投石车」敌人如果被蒸汽地板上的干员阻挡会不进行攻击」 (item 24): 自制投石机's 索敌不受阻挡影响 — targeting.js canTargetAlly / sortAllyTargets, ai.js attackTargets, content/enemies/special.js (enemy_10162_mnctpt)
- The enemy and the terrain: 「投石车」 = 自制投石机 (enemy_10162_mnctpt, ranged 4.0, the 悬赏·特异III bounty); the 「蒸汽 地板」 = 战场#07 (下半)'s 排气格栅 (tile_smog: an operator on it is 隐匿 to enemy ranged attacks).
- Seen here: blocked by an operator on the smog, it attacked that operator — every enemy does (the engine's rule: a blocked enemy attacks its blocker whatever its selectability, PRTS 索敌的概念 「…强行无视对方可选性发动攻击」).
- Official: PRTS 自制投石机 天赋 「…索敌不受阻挡影响,且不会因丢失目标而结束攻击」 — the blocker exception does not apply to it, so a 隐匿 blocker is no target and, with nobody else in its range, it does not attack: the players' report.
- Now: the catapult's profile is
blockFree(spawns.js gives every enemy the field):attackTargetstakes the allies in reach as if it were unblocked,canTargetAllyrefuses a 隐匿 / 迷彩 blocker to it,sortAllyTargetsputs no blocker first (仇恨值: taunt, then the latest deployed). Every other enemy keeps attacking a 隐匿 blocker. - ASSUMED: none for the rule. Not changed, for later: its stones' splash radius (PRTS 「目标半径1.5范围」, the data's
projectile_range0.5 × 3; the kit uses 0.5), the 0.3 s between its three stones, and 「不会因丢失目标而结束攻击」. - Golden: 1 battle — standin-06 (the bounty catapult, blocked by 忍冬, now shot the 斯卡蒂 / 瑕光 pieces by 仇恨值, its
blocker no longer first). Tests:
test/sim/feedback5-catapult-smog.test.js(3: no attack on a hidden blocker alone, another operator instead, every other ranged enemy still attacks its hidden blocker; the first two fail on the parent). Docs: docs/SIM.md.
25.18.8 「鸭爵策略的悬赏现在有时候会一波出现多只,比如多只鸭子」 (item 35): the official 0–2 swaps per wave — no change
- Checked: 鸭爵's “神秘顾客” (
round_start_all_player_change_enemy_2: min 0, max 2, from round 5, the late part of the wave — minweight 0.6 / maxweight 0.99) swaps 0–2 ground enemies of each player's wave, each into one of 鸭爵, 高普尼克, 流泪小子, 圆仔 at random (bands/meta.js duckReplace, once per player per battle — no second handler). 1000 real waves (m._normalOpts, solo and co-op, rounds 5–12): 0 swaps 388, 1 swap 312, 2 swaps 300, never more; the two of a 2-swap wave were the same kind in 81 of 300 (two of one kind in ≈ 1 wave in 12, two ducks in ≈ 1 in 50). A pair leader field holds each player's 0–2 on its own half, and 联防 re-enters every leaker's leaked swaps (both as before). - Official: PRTS 卫戍协议:盟约 下半/PRTS盟约记录 鸭爵 备注 「每回合将有0~2名敌人被替换为上述敌人之一」 — two ducks in one wave is the official rule.
- Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js(≤ 2 per wave, 0 / 1 / 2 and two of a kind all occur, 1 fund each).
25.18.9 「会移动的关底boss在各个地图的移动路线复核下是否正确」 (item 29): checked on every boss field — no change
- Checked: the leaders that walk are 铳 (boss_2 / 9) and 卢西恩 (boss_5); the 巨型单位 (胄, 管, 昆图斯, 阿利斯泰尔, 萨米的意志)
are 自缚 (content/bosses.js SELF_BOUND). Their routes are the level files' (level_act1autochess_h07_02 route 6 and act2
h07_05: PATROL_MOVE (3,9) → (2,3) → (5,9), 卢西恩's list four such rounds with a MOVE (5,9) between them), walked with the
official SPFA flow field and looped by
patrolLoop(back to the first leg instead of the goal). On all 8 boss fields of the season, solo and pair, 240 s each: every sample on a walkable tile, the targets in the official order, the pair's mirrored copy on (3,11) → (2,17) → (5,11) (its branch route), 卢西恩 restarting after its 19th checkpoint and never reaching the goal (its lpr 30). - Found, not changed: without the match's
waveId(tests, tools)templateOfinfers the template from the route list only and can take another leader's; 卢西恩 then misses its patrol loop and walks to the goal. The match, the server's headless fields and the browser battles always pass it (BattleSpecwaveId). - Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js.
25.18.10 「干员野鬃放在红门前两格的时候有概率会把怪顶出地图显示漏怪」 (item 38): not reproduced — no change
- Checked: 野鬃 (elite, S2 夹枪冲锋 kept running) two tiles before either red gate, facing it, on 战场#01–#08 against real
waves (912 battles, normal fields; 480 more with the solo leader fields), also on v0.1.4: her pushes (up to 30 a battle)
never left a ground enemy on a tile it cannot walk, and every leak happened at its route's end.
Battle.displacemoves a ground enemy only over walkable tiles of the battle rect, so it stops on the gate tile at the field's edge; planLeg then walks it back. What the rule does allow: an enemy she keeps pushing back onto the gate until the time limit is counted as leaked (时间到仍存活的敌人算漏怪), as in the official game. A recording or the map and round would settle what the player saw. - Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js(two real waves, three tiles before the gates).
25.18.11 「怪物的重量以及干员的推拉力度还是有点不对,比如锏能拉动10重的关底boss」 (item 39): not reproduced — no change
- Checked: a leader (tag boss) is never displaced (
Battle._displaceable); 锏's S3 pulls with 力度 1 (中力) and, at its end, 2 (较大力): 受力等级 = 力度 − 重量 ≤ −3 moves nothing (PRTS 推与拉), so no weight ≥ 5 enemy moves either. 40 S3 casts next to each of the 10 leaders (weights 6–10): never moved; 自在 as a bounty (weight 10) not even by 特大力. The one thing that looks like it: 卢西恩's 不祥幻影 has his model and weight 2, so 锏 does pull it (all the way, 受力等级 0). - Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js.
25.18.12 「昆图斯占地少最左边和最右边两排,似乎变成3x3了」 (item 47): not reproduced — no change
- Checked: 昆图斯's hit area is PRTS' 「受击判定区域为长4.95宽2.95的长方形,向上偏移1.0」 (tools/build-data.mjs HIT_AREAS):
standing on (3,10) it occupies cols 8–12 × rows 3–5 (body.js bodyKeys); an operator whose range reaches only its
leftmost column (艾丝黛尔 on (3,7)) attacks it; the Final Assault prep lights the same 15 tiles in red on both boards
(headless screenshots of the render demo's Final Assault prep; render/pick.js hitTiles = bodyKeys, pinned by
test/render/feedback3-leader-prep.test.js). Its model is drawn at the official prefab scale. - Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js.
25.18.13 「最终boss跟原版相比攻击欲望感觉低了,不怎么打人,复核」 (item 52): every leader attacks at its data interval — no change
- Checked: solo leader fields with eight walls on the board, 150 s: 胄 38 normal attacks (interval 4 s), 昆图斯 43 (3.5 s, two targets each), 阿利斯泰尔 19 (8.2 s), 萨米的意志 25 (6 s) — each at its official interval from its first target on —, their skills at their cooldowns; v0.1.4 gives the same counts (only the first strike now comes at the damage frame, §25.7.2). 铳 opens at the PRTS minimum attack speed 20 (22.5 s) and gains +80 per attack on the same target (5 times), so a fight that keeps switching its target sees few of its attacks; 管's normal attacks strike its 余音, not operators; 卢西恩 attacks only its blocker and blinks past it. A leader and a situation from the reporter would show what differs.
- Golden: unchanged. Pinned:
test/sim/feedback5-cb4-pins.test.js(the four interval leaders at ≥ max − 1 attacks).
25.19 Community reports of 2026-10-06, stream CB5: match flow and UI — ui/loadoutModel.js traitLines, player/economy.js _openLevelSlots, match/watch.js _followScout, match/views.js prepFieldMeta / bossMateView, render/app.js syncMates, ui/gameLogic/camera.js teamFrameIds
CB5 took the items about the match flow and the screens (16.2, 19, 51, 55, 56 of the list; 22 and 48 are feature requests — 22 postponed by the owner, 48 built in §25.15 —, both at the end). Each was reproduced first (a script, or the real server in headless Chrome for the screens), checked against the official data, PRTS and the official tutorial pages, then fixed in one commit with its tests; two open community PRs were reused without merging them (§25.19.6).
25.19.1 「干员调配界面很多干员的某个模组只有额外特性没有基础特性,不清楚是文本错误还是实际效果也有错」 (item 16.2): text only — the module's added line now follows the class trait — ui/loadoutModel.js traitLines / fullTraitText, ui/detailPanel.js traitText, screens/loadout.js ModuleInfo, screens/diy.js ModuleRow
- Seen: 114 of the 164 modules the 干员调配 screen offers (128 of all 184 elite module records) showed under 特性 only the module's extra line — 隐现's MAR-X read 「攻击空中单位时攻击力提升至110%」 without 「优先攻击空中单位」; 局内数值, the in-match detail card and the 自选 module row did the same.
- Official: a module's trait candidate either rewrites the class trait (
overrideDescripton) or adds a line after it (additionalDescription); PRTS flags the latter 「特性追加」 on every such module (e.g. 伊芙利特 BLA-X / BLA-Δ, 玛恩纳 LIB-X, 莫斯提马 SPC-X / SPC-Y). - Cause: the data keeps both lines (
traitOverride.desc= the class trait or its rewrite,moduleDesc= the added line); the screens showedmoduleDescinstead ofdesc(since 0.1.2: the review of GitHub #64 in §22 picked the module line over a cloned record's class trait). The battle was right: for every added-line module the unit keeps the class trait — the same trait text, targeting, attack shape and trait blackboard as 不装备 (圣约送葬人 REA-Y also rewrites it). - Now:
traitLines/fullTraitText: the class trait (or the rewrite), then the added line; the module card shows them as 特性 and 特性追加 (en "Added Trait"). - Golden: unchanged (no sim change). Tests:
test/ui/feedback5-module-trait.test.js(6; the text cases fail on the parent, the data and sim pins pass there),test/ui/loadout-stats.test.jsupdated; SP_E2Eloadout.e2e9 / 9. Docs: docs/DATA.md (trait,traitOverride).
25.19.2 「升级商店获得新的商店位时用新卡补上,而不是空着」 (item 19): the upgrade opens the new slot with a new card — player/economy.js _openLevelSlots, audit.js
- Seen: a level-up from 1 to 2 (险境: 3 → 4 operator slots) or 3 to 4 (4 → 5; 标准 5 → 6) showed no new card until the next refresh or round start (the shop kept its rolled layout; META listed it as an assumption).
- Official: the tutorial's 休整期 page (local guide art
autochess_home_4): 「升级:消耗资金升级调度中心。升级后将出现更多 的商品栏位、可调度干员以及新装备」; PRTS 帮助 「消耗资金可以为调度中心升级,从而增加刷新栏位」. - Now:
levelUp→_openLevelSlots: the new level's extra slots are appended to the operator slots at once (the item slot stays after them), each drawn at the new level; the cards shown stay in place, a bought card stays sold.audit.jschecks the count and the kept cards (matchrun --check: no violation). - ASSUMED: the new card follows the freeze toggle, as a manual refresh's cards do.
- Golden: matches — all 18 scenarios (every bot levels its shop and now sees, and draws the shop RNG for, the new card at
once); the battle families unchanged. Tests:
test/match/feedback5-shop-levelslots.test.js(3, all fail on the parent). Docs: docs/META.md §3 / §7, docs/PLAYING.md.
25.19.3 「死亡观战时每一回合结束都会被转回自己家」 (item 56): an eliminated player follows a player through every phase reset — match/watch.js watchPref / _watchTargetOf / _followScout, battle/observe.js followedScout
- Seen (real server, headless Chrome): every round start cleared an eliminated player's watch — in 回合开始 / 机变 / 休整期 it saw its own empty board, each battle started on the first field; a spectator seat asked for the first player itself.
- Official: research 09 §3.1 — after elimination the client keeps observing (self_dead_dialog KEEP_WATCH, the server's DeadAutoObDn { obIndex, state, preparation }, FindFirstAvailObTarget).
- Now:
Match.watchPref= the player of the viewer's last manualg.watch(a prep scout, a single-player field, or — new, optional —g.watch { playerId }naming the row tapped on a shared 联防 / boss pair field);_watchTargetOf= that player while still in, else the first player still in (seat order, AI seats included). The round start pushes its prep board (_followScout, kept through 机变 and 休整期), both combat modes and the boss fields start on its field, a resync or a spectator joining in prep gets the board, a followed player who quits hands over at once. The screen adopts the pushed board like a 前往查看 tap (followedScout; PR #189's stale-field fix) and keeps it through the prep phases; 返回自己 asks the server for nothing (the viewer has no board). - Golden: unchanged. Tests:
test/match/feedback5-watch-follow.test.js(9; 8 fail on the parent's server),test/match/spectator.test.jsupdated. Docs: design/network.md, docs/PLAYING.md.
25.19.4 「死亡后观战视角看不到场上的关底boss」 (item 55): a watcher of a boss round's prep sees the boss field and its leader — match/views.js prepFieldMeta, screens/game.js
- Seen (headless Chrome, the guest eliminated at the boss round): in the Final Assault fight the watched boss field showed the leader (enemy_9013_acstmk at 10,3); in the boss round's prep the guest saw its own empty normal board (camera 'prep', no leader) and a scout of a teammate was the normal board too — while the players prepare on their half of the boss field with the leader standing there (§23.18, community report #12).
- Now: in a boss round's prep the scout is built on the boss field —
kind: 'boss',BOSS_RECT, the scouted player's pieces throughbossFieldPlacement(rows − 7, the right half mirrored with RIGHT ↔ LEFT),side, the leader's spawn innextEnemies— and framed by the boss-field prep camera of that side, which shows the leader. With §25.19.3 the eliminated player gets it at the round start; the same run after the fix: field 'boss', camera bossPrep, leader shown. - Golden: unchanged. Tests:
test/match/feedback5-boss-prep-scout.test.js(2, fail on the parent); SP_E2Etest/ui/feedback5-boss-pair.e2e.test.js(item 55 case). Docs: design/network.md, design/client.md §15.
25.19.5 「还原原版最终boss战准备阶段:像战斗中那样把会成一组的两个玩家放在一起…同组两个玩家屏幕左边的头像也像原版那样用绿框框起来」 (item 51): the pair together in the boss prep, the official green frames — match/views.js bossMateView, match/messaging.js markPrivate, render/app.js syncMates, ui/teamPanel.js, ui/gameLogic/camera.js teamFrameIds
- Seen: the own half was already the official one — the right-hand player on the right half with the right_boss_*_camera_param camera, its layout mirrored col c → 20 − c with RIGHT ↔ LEFT, so its operators face the leader as before (research 09 §1.2, §15) — but the partner's half stood empty and nothing framed the pair.
- Official: every client knows every board (ChangePositionDn { boardStatus }, research 09); the team list frames the
co-op group (the owner's recall; the client's ui/battle
bg_team_border, a white 100×100 frame with its glow, and the autochess green oficon_self, #4ed8af). - Now: in a boss round's prep
m.private.bossMate { playerId, side, units }carries the partner's board on its half, placed as the battle will (bossFieldPlacement); a partner's change marks the player's m.private too (markPrivate), so it follows live; the own prep view draws those units read-only ('m:' views, never picked or dragged) and lights the whole boss field; a scout of either player shows both halves (mate). The team panel frames the pair's two avatars (teamFrameIds: the players still in by seat, two by two, asprepCamera; the boss field in the fight) from the round start through the fight, with the official sprite tinted green (a plain ring without the local art); a lone player, an eliminated player and a spectator seat get none; 联防 is not framed (not asked). - ASSUMED: the partner's bench is not shown (its board only); the frame's exact official geometry (one frame per avatar).
- Golden: unchanged. Tests:
test/match/feedback5-boss-pair-prep.test.js(4, fail on the parent), SP_E2Etest/ui/feedback5-boss-pair.e2e.test.js(both halves, the mirrored right half, the frames in prep and fight). Docs: design/client.md §10 / §15, design/network.md, docs/PLAYING.md.
25.19.6 Overlap with the open community PRs #189 and #191 (not merged; their authors' fixes were pending)
- PR #189 (watch preference, @2321Robin) — §25.19.3 builds the same chain (a manual watch is the preference; round start,
both combat modes, the boss fields and the resync follow it; the stale-field fix of the adopted scout), on the 0.2.0
method containers. Differences: the fallback is the first player still in with AI seats included (a lone human with AI
teammates had nobody to follow — the report's case), and a shared field records the
playerIdthe row tap sends (the review's point 2) instead of nothing. - PR #191 (same-field frames, issue #190) — §25.19.5 frames the pair as the owner asked: green, the official sprite, both
avatars (self included), the boss rounds only; the pairing is read from m.public as the prep camera already does, so no
bossPairingfield; #191's 联防 frames and the phase banner naming the partner are not built. If the owner still wants them, they can go on top of this.
25.19.7 The two feature requests: battle history postponed by the owner, custom hotkeys built (§25.15)
- 22 战绩 / 分队胜率 — postponed by the owner; what it would take: the result is already complete (
m.result: per-player stats, lineup, band, bonds, titles, rounds passed, victory —server/match/results.js). With no accounts the simplest is per browser: append a compact record atm.resultto localStorage (capped, e.g. the last 200; only matches of ≥ 2 rounds, as asked), a 战绩 screen in the lobby (list, win rate per strategy / core bond / mode and difficulty, 导出 / 导入 like the loadout), tests and i18n — no server change. Server-side history needs persistence and an identity the remake does not have. Decisions left for then: browser-only or not; what 「分队」 groups by (strategy, core bond, lineup); the sample cap. - 48 自定义快捷键 — built in 0.2.0: §25.15 (W5AC; the community request 「快捷键可不可以自己设置」, the owner's decision of
2026-10-07). 设置 → 快捷键 rebinds 刷新, 冻结, 升级, 撤退, 出售 and 准备就绪 / 暂停 (Esc stays fixed); the key map lives in
the settings (
sanitizeSettings) andshortcutFor, the facing wheel and every key hint read it. One difference from the estimate that stood here: a key another action has is swapped, not refused. The official PC client's keys are fixed as far as the data shows (pc_key_holderhints), so the shortcuts are the remake's own.
25.20 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_metablock; optional game textsdata/i18n/<code>.json) — the translator's way and how English ships — or a folderpacks/<id>/pack.jsonnaming its files (every future type). The manifest: type (lang;assetsanddataplanned: 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.jsscans the language folders andpacks/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 answersGET /packs/index.json(live, never cached; packs of supported types with the URLs of their files) andGET /packs/<id>/<file>(only a file a manifest names, with its role's extension, inside the pack folder). A static host usesnode 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 andnode tools/packs.mjs list. - The client lists every
langentry 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,fmtNumtakesnumberUnits(Chinese 万 / 亿; without them K / M / B). - Fallback chain per string: the pack → its base (
pt-BR→pt;zh-TWnone) → the packs_meta.fallbacknames (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 checkchecks the call sites). Plurals:{n|one|other}picks byIntl.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:_metaand 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-TWbuilds a pack's game texts from the official JP / KR / TW client (ArknightsAssets/ArknightsGamedatajp/,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). The stream shipped no language but English (a game-text file without its UI pack is not listed). - Shipped: 日本語, 한국어, 繁體中文 (the owner's decision of 2026-10-07, at the merge):
data/i18n/ja.json,ko.json,zh-TW.jsonbuilt withbuild-i18n --lang(ja 96.5 %, ko 97.4 %, zh-TW 91.1 %) and minimal UI packspublic/i18n/ja.json,ko.json,zh-TW.json— a_metamanifest (its own and English name, credits: the official client data via ArknightsAssets) and no UI strings yet:ja/kofall back to English,zh-TWto the Simplified Chinese UI (no fallback — the owner's choice; ASSUMED numbers in 萬 / 億). With five languages the menu is a list (buttons up to four). UI translations are welcome from the community (docs/I18N.md §5 "Shipped packs").
- A pack is a manifest plus its files, in one of two layouts the same registry reads: the single file
- The output in Chinese and English did not change:
test/i18n-packs.test.jsrenders every msgid ofpublic/i18n/en.jsonin both languages with sample params and compares it with the renderer of 0.2.0 before packs;node tools/build-i18n.mjs --checkstill findsdata/i18n/en.jsonup 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--langand--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.jsunchanged and green.
25.21 Community reports of 2026-10-06, stream CB1: bonds, strategies, items — sim/battle/status.js applyStatus (cold), content/items/battle.js reviveNow, content/bands/battle.js (埃芒加德), content/bands/meta.js (佩佩), content/tokens.js airTile, screens/result.js resultBonds, tools/build-data.mjs (pool_equip_kathe)
Fifteen of the owner's community reports of 2026-10-06 (items 5, 7, 8, 9 / 37, 15, 20, 21, 23, 25, 41, 42, 43, 45, 49, 50 of the list). Each was reproduced on this tree with a script, checked against the official data (bonds.json, items.json, the client's buff templates), PRTS (卫戍协议:盟约 下半/PRTS盟约记录 and its 备注, 术语释义, 特殊机制) and the earlier decisions. Seven were real and are fixed in six commits (7 and 8 share one; golden named in each); five are the official behaviour (four pinned by tests); three could not be reproduced and need the reporters' cases; two questions went to the owner (the order of §25.21.1, a fallback in §25.21.10) — the owner's decision of 2026-10-07 kept both as they are.
25.21.1 「维多利亚的锁血锤和烛煌的锁血只生效了一个」: both work, one after the other — no change
- Measured: 烛煌 (elite) carrying 坚固维式重锤, a lethal hit every 2 s: 倒地 at the first (绝处重燃, a kit
fatalsaver −50), the hammer's lock at the hit that breaks the 6000 barrier while she is 倒地 (PRIO_REVIVE−100), death 8 s later; without the hammer she falls at the second. The 蒸汽之心 path (another operator's hammer) behaves the same. - Why it looks like one: PRTS 备注 「不处于【重燃】状态下,受到足以致命的伤害时,可触发此天赋效果,次数不限」 — the talent takes every lethal hit outside 【重燃】, so the lock only ever shows when she is killed while 倒地. The order — kits' savers before the consumable 不死 — is the documented ASSUMED (§21.21, §22.7's 余烬): the official talent fires on ON_BEFORE_TRY_SET_HP_ZERO (buff template blaze2_t_2) and the autochess hammer's template is not in the client's buff data, so no source gives an order. Asked whether the lock should take her first lethal hit instead, the owner kept the order (the owner's decision of 2026-10-07): 绝处重燃 first, then the lock.
- Golden: unchanged. Pinned:
test/content/feedback5-blaze-hammer.test.js.
25.21.2 「谢拉格盟约冰冻时间没有随层数正确成长」 and 「…被在无法被任何干员攻击到的地方永控」: a pair of colds becomes the freeze — sim/battle/status.js applyStatus
- Seen: the 6-member wind (every 25 s, 寒冷 20 + 0.1 × layers s) froze an enemy for the rest of the battle from 51 layers on, wherever it stood (at the gate too), and never below: measured, 60 layers → frozen from 50 s to the end; 40 → never.
- Official: PRTS 术语释义 寒冷 「友方寒冷始终需要两两一对产生友方冻结,持续时间取双方之中最高」; 异常效果 COLD 「在特定条件下转变为冻结」 — the pair turns into one freeze (a lone 友方 cold on a frozen enemy needs a partner, unlike the 敌方 rule 「…施加的敌方寒冷会变为敌方冻结」).
- Cause: the second cold froze for max(remaining, incoming) (§23.27) and the older cold stayed on, extended to the same length, so the next cold before it ran out — the next gust — froze again.
- Now: on an enemy the pair becomes the freeze and no cold is left; on an operator (敌方寒冷) the old rule stays. The wind alone freezes 20 + 0.1 × L s of every 50 s from 51 layers (60 → 26 s, 200 → 40 s, all of it from 300).
- ASSUMED: a paired cold emits no
statusApplied'cold' (the freeze does). - Golden: every scenario where a second cold met a cold enemy (the commit lists 35). Tests:
test/sim/feedback5-kjerag-cold.test.js;feedback3-cold-freezeand 灵知 S2 (kits_t4) updated. Docs: docs/SIM.md (cold), DESIGN §5 (design/engine.md).
25.21.3 「卡西米尔和艾芒加德策略似乎有BUG:像砾和瑕光这种死亡和部署的叠层效果…无法触发」: a 复活 is a knock-out and a free redeploy — content/items/battle.js reviveNow, content/bands/battle.js, content/bonds/core.js installEgir
- Seen: with 埃芒加德's 命结之秘, 砾 (<部署时> 卡西米尔 +1, <被击倒时> 不屈 +2) gained nothing from his first three knock-outs and stacked only on the 4th, real death; 瑕光's <部署时> +4 never fired on a revive.
- Official: PRTS 埃芒加德 (and M3茧甲, 阿戈尔) 备注 「“复活”的实现方式为:受益者因移动之外的原因退场时下次部署的再部署时间和 费用归零」 — the operator is knocked out and redeployed at once.
- Cause: both 复活 were
fatalsavers that kept the unit standing (a known simplification, §21.20's "not done"): nodeath, nodeploy. - Now:
reviveNow, adeathhook (M3茧甲PRIO_RESPAWN13, 埃芒加德PRIO_BAND_REVIVE12, ahead of 阿戈尔 5 at 11 and 不屈 at 10): the knock-out stands (被击倒时 effects, 克莱门莎, 卡莱莎, 不屈's +5 SP …) and the operator redeploys where it lies, free (full HP, SP reset, 部署时 effects, the 卡西米尔 deployment ATK, a new 坚固 lock —revivedInPlaceis gone). The ctx carriesrevivedBy, so 阿戈尔 5 does not count that knock-out as the member's first (the owner's decision of 2026-10-05, unchanged). - ASSUMED: a revive whose tile is taken spends nothing (as 阿戈尔 5); with both, M3茧甲 answers first (as before).
- Golden: the battles with M3茧甲 or 埃芒加德 whose operators fell (11, the commit lists them). Tests:
test/content/feedback5-revive-redeploy.test.js; bands / bonds_core / feedback1f-hammer / op_lessng / op_zuole / docs-consistency updated. Docs: docs/SIM.md (fatal,death), DESIGN §5 (design/engine.md), docs/PLAYING.md, research 04.
25.21.4 「局内划掉被ban的盟约的实际效果有问题:只在标准模拟中生效」: the drawn bonds are the same in every difficulty — no change
- Measured: the drawn set D — 0 core + 1 add-on in 标准, 3 + 4 in 险境 / 绝境 / 终极 — removes only the operators whose every bond is in it (23–25 banned, none in the pool); each drawn bond keeps 2–10 members through their other bond, 标准's one included. Only 标准 also has the mode's static list (the official modeDataDict inactiveBondIdList, 10 bonds that never activate, §21.7).
- Official: 帮助 「…以及不完整的盟约与不会进入调配池的干员」, the briefing badge 「部分盟约所含干员阵容不完整」, the strategies' 「在部分干员缺席时体验可能不完整」 (research 01 A2). The briefing legend already says it.
25.21.5 「佩佩策略的特殊刷新也是要花钱的,不是免费」: the special refresh is paid — content/bands/meta.js
- Seen: reaching shop level 2 / 4 / 6 granted a free refresh; the special one cost 0.
- Official: 博学多通 「获得1次特殊刷新」 names no 免费 (德克萨斯's trait 「获得1次免费刷新」 does); the blackboard's
price0 had been read as its price. - Now: the level-up marks the next manual refresh special — the usual refresh price, the chess slots filled with
<萨尔贡> first. ASSUMED
cnt/price0 change nothing. Golden: unchanged. Test:test/content/bands.test.js.
25.21.6 「独行这种盟约是不能叠层的」: they stack, the game never shows them — screens/result.js resultBonds
- Official: PRTS 盟约记录's header 「下述盟约中部分盟约不会显示叠加层数,但是叠加层数的特质/策略/装备等效果仍然对其生效」 — the
four bonds.json
noStackbonds (调和, 协防干员, 独行, 绝技) take layers like every other (GitHub #139's answer, 0.1.4 PR #66); their effects do not read them. The report asks for what the game does not do. - Now: the one place still printing the hidden count — the result card (「独行 24」, ranked by it) — shows no number and
does not rank by it, as the bond strip since PR #66. Golden: unchanged. Test:
test/ui/feedback5-result-bonds.test.js. Docs: docs/PLAYING.md (层数), research 02 §2.2.
25.21.7 「Touch策略给的医疗干员会跟炎盟约的炎祐冲突,无法同时出场」: the 炎佑 keeps off the map-character slot — content/tokens.js airTile
- Seen (every season map): on 战场#08 涨潮控制 (always) and 战场#07 排气格栅 (the second 炎佑 of 9 炎) the 外勤医疗 medic / Touch never stood.
- Cause: both spawn at battle start; the 炎佑's tile (void tiles nearest the half's centre) took (10, 2), the medic's
stage slot (stages.json
mapChars), first. The 联防 maps have no predefined medic in the official levels: none there. - Now:
airTileholds the map characters' positions. Golden: unchanged. Test:test/content/feedback5-yanyou-touch.test.js.
25.21.8 Not reproduced — 「炎祐能错误的被空中单位阻挡」 (item 25), 「选pith策略的时候阿戈尔在联防时会出现加成被清空」 (item 41), 「源石溶剂在干员血量满的时候没生效」 (item 42) — no change
- 25: the 炎佑 never blocks (block 0) and is never blocked (only enemies are block candidates), as PRTS 特殊机制 我方单位 「敌人类我方单位不会被角色类单位阻挡」; it hovers on the top-aggro enemy, and an unblocked ranged enemy — a flyer included — stands for each attack (GitHub #58), so a flyer shooting it looks held.
- 41: Pith's 盟约·辅助干员 (调和) with four 阿戈尔 (5 with 调和's +1): the same 阿戈尔 HP bonus in the normal battle and in 联防, one or two helpers, either half; the 联防 input is the normal one plus the round's layers, HP ratio, SP and 倒地.
- 42: from full HP the drain ticks 60 / s and ATK +40 % holds. Noted for the owner: the official
periodic_damagetemplate has_ignoreForSp: true(no 受击 SP), while §21.12 lets it charge 受击回复 SP. - The reporters' cases (operators, items, screenshots) are needed.
25.21.9 「凯瑟琳装备池没有超出商店等级的装备」: the 凯瑟琳 offer is every shop item — tools/build-data.mjs
- Seen: the 1 → 2 upgrade offered tiers I–II only (40 seeds: 55 × I, 65 × II).
- Official: the pool is server-side; the players' first-hand account 「原版凯瑟琳1升2都能有6本装备」.
- Now:
pool_equip_katheis every shop-eligible item, uniform ASSUMED (40 seeds: I 9 … VI 24); data/choices.json rebuilt offline (only that pool'smaxTiergone). Golden: coop4-ABYSS-7. Test:test/match/feedback5-cathy-pool.test.js.
25.21.10 The official behaviour, pinned — 「寻呼模块和电话对干员缪尔赛思用不会给缪尔赛思」 (item 45), 「炎祐能吃到掉血道具的效果」 (item 49), 「两个空弦转职阿戈尔…最后面的空弦不能吃前面的空弦」 (item 50) — no change
- 45: 「电话」 is 简易通讯机 (its phone icon; 备注 「获得的干员等阶不高于当前调度中心等级」), like 寻呼模块 「(不高于当前调度中心 等级)」. 缪尔赛思's only bond is 调和, whose only operator in the pool is her, tier VI: below shop level 6 nothing qualifies and the item is used up (as 拟态物质 at the copy cap, §25.13.1); at 6 she comes. Offered a fallback to any tier when nothing qualifies (what the reporter expects), the owner kept the official cap (the owner's decision of 2026-10-07).
- 49: PRTS 源石溶剂 备注 「携带后,全场范围内的所有敌人类我方单位也会获得此装备的“每秒受到60真实伤害”效果」 — the 炎佑 is one (600 HP in 10 s, no ATK bonus).
- 50: two operators made 阿戈尔 by 变形同构体 + 阿戈尔重刃 (two 空弦, 空弦 + 哈洛德) devour like any others, through the real intents too (+3 layers, ATK, block). Two NORMAL copies of one item merge (the official rule), so two 空弦 need a normal and an 进阶 set; and the pair counts once toward the 3 members.
- Pinned:
test/content/feedback5-cb1-pins.test.js.
25.22.2 GitHub #236 「被淘汰后每回合开始横幅仍显示「资金已到账」(观战席同理)」 (@2321Robin, with PR #237): the round-start banner reads 观战中 to an eliminated player and a spectator seat — ui/gameLogic/phases.js phaseBanner, screens/game.js
- Seen (a real Match with fake battles: three humans and a spectator seat, p_0 out of LP at round 1's settlement): at the round-2 start p_0 (funds 0, pending 0) and the spectator seat (no seat, no funds) got 「第 2 回合 · 资金已到账」, the same as p_1 (funds 5). The sub had been fixed text since 0.1.0.
- Official: no rule for the banner's text. The money: round income goes only to the players still in.
startRoundrunsps.startRound(income + pending coins) foralivePlayers()only, andeliminate()zeroesfunds/pendingFunds(server/match/match/phases.js, player/round.js). An eliminated player keeps watching (research 09: KEEP_WATCH). - Now:
phaseBanner(phase, pub, { alive, spectator }). The match screen passes itsaliveandspectator.aliveis false for an eliminated player and for a spectator seat. A spectator seat has no row in m.public, sopubalone cannot tell. For those viewers ROUND_START's sub is 「观战中」 (en "Spectating", the combat HUD's spectator caption). A player still in keeps 「资金已到账」. The title and the other phases do not change. PR #237 was read for the idea only: its fourthaliveargument sits on top of the #189 / #191 stack and Match.js changes, so it was not merged. - Golden: unchanged (client text only). Tests:
test/ui/gameLogic.test.js+1 (a player still in, an eliminated player, a spectator seat, the screen's call). It fails on the parent: 「资金已到账」 where 「观战中」 is expected.
25.22.3 GitHub #173 「bug:网页版游戏文件未加载」 (@sarilendorf): a 干员调配 tab without its game data says so, and every import is refused — screens/loadout.js missingGameData / importRefusal / DataMissing
- Seen: on the reporter's own server (Node 24) the operators, bonds, maps and enemies did not load. Servers other
people host worked, and a loadout exported there failed to import locally. The screenshots, as described in the
thread: 干员调配 empty, the import toast 「导入失败:这份数据在当前版本没有可用的调配,未做任何改动」, the
npm startlog with every check passed, an ad blocker showing one block. Reproduced with every /data/*.json request answering 404. All five files of the screen endmissing, the screen counts them as loaded, the roster is empty (「没有符合条件的干员」) and the loadout import gives the reporter's toast. Two imports did worse: 干员持有 said 「已导入:全部持有」 and stored [] over the saved list, and 自选编队 said 「已导入:全部名额为空」 and stored {} over the saved picks. With the files served, the same three imports work. 0.1.3 and 0.1.4 behave the same. - Cause:
useData(public/js/data.js:489–501) counts a file that never arrived (statusmissing) as settled, so the UI can carry on without optional files. In screens/loadout.jsready(:399) was then true. The tab drew its empty roster, and the import guardif (!ready)(:479) let the import run. It exists to stop an import before chess.json loads, because such an import would sanitise every entry away. The loadout import kept the loadout but blamed the data (:501).applyOwnershipImport/applyDiyImport(ui/loadoutSync.js:93, :113) stored the empty result. The server sync was already safe: the loadout sync sends nothing without chess.json, and the other two send the stored lists. - Official: no rule involved; the page reads its game data from the server it was opened from (/data/*.json).
- Now:
missingGameData(tab)names the files a tab cannot work without: chess.json, plus backups.json for 自选编队. When one ismissing, the tab showsDataMissingin place of the roster: 「游戏数据没有载入」, the file paths (e.g. /data/chess.json), that the saved settings are unaffected, and what to try (reload; then the ad blocker and the network).importRefusal(kind, ready)is the one guard of every import. It refuses while the files load (as before) and when the data is missing (「导入失败:游戏数据没有载入,未做任何改动。请刷新页面;仍不行时,请检查广告拦截插件和网络」), before anything is parsed or applied. Three new UI strings, with English. - ASSUMED: the cause on the reporter's machine is still unknown: the ad blocker, a proxy or security software, or a
different address. The new message and the console line
[data] /data/<file> unavailable (<reason>)are what to ask for. - Golden: unchanged (client only). Tests:
test/ui/feedback5-loadout-data-missing.test.js(4, all fail on the parent: the tab's files, the refusals, the screen's guard order, the message in Chinese and English); loadout, loadout-stats, module-trait, moduleIcons, diy-ui and standin-ui tests pass unchanged.
25.22.4 「提问:联防结算播报没了」 (GitHub #235; PR #112 by @Convey123, approved, never merged): the official 「作战结束」 box and the three BATTLEOVER sounds at settlement — match/settle.js, match/views.js, ui/gameLogic/phases.js, ui/components.js ResultDialog, screens/game.js
- Seen: 0.1.4 and 0.2.0 have no result box and never play the battle-over sounds. A co-op 联防 round run to SETTLE
through the match harness: the SETTLE m.public carries nothing about the 联防;
public/jsnames none of the three sounds, thoughdata/assets.jsonaudio.sfx.uilists all three and they are on disk (so the full zip, which packs every file the manifest lists, already carries them). PR #112 targeted 0.1.4's layout; the owner approved it on 2026-10-05 once the remake's own 「联防成功 / 联防失败:还有 N 只突破防线」 line went (the author removed it, then made 「全员无伤!」 true-only). - Official: research 09 §3.1 "Round result dialog": 「作战结束」 + 「全员无伤!」, or 「生命值减少」 and the LP lost; the
client's audio data names
ON_ACT1AUTOCHESS_BATTLEOVER_REDUCE / _NOREDUCE / _NORMAL, not when each plays. No EN client text for the three lines indata/i18n/en.json: plain translations (Battle over — the existing msgid —, All unharmed!, LP reduced by {n}). - Now (ported by hand onto the 0.2.0 modules, every line reviewed):
settle()keepsuniteResultView—through(the leakers' enemies that still got through), helpers, leakers andlosses(every alive player's own charge, the verylossdeducted) — which the SETTLE m.public carries asuniteResult(cleared at the round start; design/network.md §8.2). At SETTLE (the moment is ASSUMED — the sources do not time the dialog, and a leaker's number exists only after the 联防) the screen popsResultDialogfor 2.8 s (inside SETTLE's 3 s; click-through, under the phase banner): 「作战结束」 and the viewer's own line — after a 联防 fromlosses: charged → 「生命值减少 −N」 (red); nothing got through → 「全员无伤!」 (mint, true for everyone); the 联防 leaked but the viewer paid nothing (a helper, a spared leaker) → the title alone (orange); without a 联防, the own battle'smin(cap, leaks)as kept while it ran (roundLossRef, the live LP's own inputs). Sound: Reduce when charged, NoReduce when a 联防 ran and the viewer paid 0, Normal otherwise [ASSUMED mapping, PR #112's; the owner called the three right]. No ticker line for the outcome. - Who sees it: solo — every normal round (no 联防 there) [ASSUMED: the same dialog]; bots — nothing to show, listed
in
losses; a spectator seat or a player eliminated earlier — no box and no sound in any round, where PR #112's last commit gave them the title alone after a 联防 although its own rule gave them nothing in an ordinary round (and no sound either) ASSUMED; 最终攻势 / 隐秘核心 — no SETTLE phase (_finishFinal→ the result screen or the Hidden Core round) and the merged team LP has no per-player loss, so no box ASSUMED; a reconnect landing on SETTLE — the 联防 box (the server's figure) without sound, nothing in an ordinary round. - Left out of the PR: ResultDialog's unused
iconprop and gold / ice tones. Golden: unchanged (283 scenarios). Tests:test/ui/gameLogic.test.js(5 new: sounds, loss, words in zh and en, 联防 cases, no-联防 box; the file does not load on the parent),test/match/playtest6-matchflow.test.js#235 (2; the 联防 one fails on the parent: losses = the LP settled, no result ticker, gone in the next phase), SP_E2Etest/ui/resultbox.e2e.test.js(3, mock variantsunite[,through][,helper|,dead]). Docs: PLAYING.md §1 / §5, design/network.md, design/client.md, design/match.md.