0.2.5-dev: docs — §30 sections renumbered in order after the merges and every reference pointed at its topic; the 0.2.5 CHANGELOG section regrouped under the usual headings (no change to code behaviour)

This commit is contained in:
sganggs committed 2026-10-12 16:02:41 +08:00
1 parent 3c1952afc0
commit e2bc005c88
16 files changed
+71 -67

No files matched your search

+21 -17
View File
@@ -1,40 +1,44 @@
# 更新记录
## 0.2.5-dev — 未发布
- 干员调配同步在等待游戏数据时,恢复默认或之后的修改会使仍在准备的旧请求作废,避免旧技能写回服务器(PR #540,感谢 @Xinglan233)。
- 导入带潜能/练度的调配文件时,若缺少自选编队所需的游戏数据,整份导入会被拒绝,不再清掉已保存的练度(PR #538,感谢 @Xinglan233)。
- 玩家包里的 package.json 只保留指向包内文件的脚本;`npm test` 不再在没有测试的情况下显示通过。打包进去的说明里,指向未随包发布的文件的链接改为该版本标签的 GitHub 地址(#531、#530)。
### 规则(按官方)
- 补齐司霆惊蛰二技能、斩业星熊三技能对空及予愿安洁莉娜三技能周身范围的自动开技判定。
- 首领配对改为每局随机,准备期至开战固定,隐藏首领沿用同局分组;客户端棋盘和队友框同步实际配对。
- 修复联防阿戈尔继承残血后再次结算开场吞噬、误触发复活的问题,保留准确生命比例和技力。
- Touch 外勤医疗按本局团队权益保留,持有者淘汰或退出后不再使下一场医疗消失(维护者已确认保留,原作寿命规则仍待实测确证)。
- 补齐回合开始、机变、休整期和战斗中的盟约叠层提示音;同类最多播放一路,新触发替换旧声音,重连和结算回填不补播。
- 修复固定特质赠品被共享库存阻断:仍计入库存,达到上限也会继续发放;补齐洛洛、焰尾的实测子池。
- 已展示的干员商店牌和奖励牌不再因随后库存耗尽而领取失败;道具购买与奖励保留库存检查。
- 修复克莱门莎三技能被友方侵蚀爆条触发、号角不攻击脚下不可阻挡敌人、自制投石机溅射半径,以及忍冬首次追凶附伤。
- 谢拉格不融冰、催泪瓦斯改为造成伤害时判定,包含阿斯卡纶的持续伤害。
- 支持只修改自选潜能/练度时导出调配,补齐观战自选干员盟约名单;刷新请求在途时防止重复发送。
- 生命值在结算前保留当前数值并标待扣;盟约提示补本局禁用干员名单,增加开发用模拟一致性检查页。
- 修正韩语界面和维多利亚英文按装备逐件加成的表述。
- 修复干员一次攻击后模型继续循环、多挥一次的问题,保留迟到消息的现有前摇同步方式。
- 自在重生后的无敌期不再被普攻或需要可选目标的自动技能锁定;修复 AI 托管遮罩挡住“在此页面继续”按钮。
- 设置增加「官方伤害数字」(默认关闭)。打开后只按 PRTS「伤害红字(暴击)」显示红色整数;关闭时仍显示每一次命中(#412)。
- 标题画面页脚增加「项目仓库」,在新标签页打开本项目仓库(#543)。
- 3D 棋盘在提取了官方场景时按战场显示沙地等 11 个场景,没有场景时仍用金属地块(PR #533,感谢 @andrew05060414)。完整包带上提取出的场景;精简包和源码可以在本机下载并提取,提取依赖缺失时继续用金属地块。
- 自在重生后的无敌期不再被普攻或需要可选目标的自动技能锁定。
- 外勤医疗的预备地图角色在开战时保持比普通初始干员更早的索敌顺序(预备干员-医疗与 Touch 都是;[ASSUMED],维护者 2026-10-12 决定按作者描述实现);准备阶段可以点开该角色的详情和攻击范围(PR #523,感谢 @YinqiMargatroid)。
- 萨卡兹枯朽战士和组长在已经沉默时被击倒,不留下污染秽蚀。维护者 2026-10-12 的实机回忆是沉默能阻止这团雾,这与 PRTS / 游戏内文字「不可沉默」相反;同一死亡能力只有这两名敌人,其他枯朽敌人的沉默规则不变(#470)。0.2.0 起行为已是如此,这次记下的理由改为上述回忆。
- 调度中心 4 级的五阶晋升奖励可以出现五阶自选,5 级的六阶晋升奖励可以出现六阶自选;普通商店仍在 5 / 6 级才刷出;不保证出现;禁用和库存照旧(#515,维护者 2026-10-12 决定)。
- 驭械术师未释放的浮游改为本体攻击再加一份附加伤害(初始相当于攻击力 20%,同一目标每次 +15,上限 110%);技能放出的浮游仍造成技能伤害(PR #537,感谢 @Xinglan233)。
- 只改普攻的技能保留干员自己的那一击。耶拉二技能(基础与隐藏)放出浮游时仍打出 100% 的普通攻击,寒冷对自身和浮游各判一次;荒芜拉普兰德一技能开启后仍是本体一击加两份未释放浮游。只由浮游出手的技能不另加这一击。
- 干员再部署时浮游倍率回到初始值,并清掉按目标记住的倍率;自由移动仍保留。已经飞出的浮游按命中时的倍率结算(PR #536,感谢 @Xinglan233)。
- 洛洛二技能放出的浮游在目标离开攻击范围后继续锁定,只在击杀或技能结束时返回;技能期间不再叠加未释放浮游的附加伤害(PR #535,感谢 @Xinglan233)。
- 受击格按官方四舍六入五成双取整,被挡在场地边缘的敌人留在边缘那一格(PR #520,感谢 @Cloudnyco)。
### 界面
- 干员调配同步在等待游戏数据时,恢复默认或之后的修改会使仍在准备的旧请求作废,避免旧技能写回服务器(PR #540,感谢 @Xinglan233)。
- 导入带潜能/练度的调配文件时,若缺少自选编队所需的游戏数据,整份导入会被拒绝,不再清掉已保存的练度(PR #538,感谢 @Xinglan233)。
- 补齐回合开始、机变、休整期和战斗中的盟约叠层提示音;同类最多播放一路,新触发替换旧声音,重连和结算回填不补播。
- 支持只修改自选潜能/练度时导出调配,补齐观战自选干员盟约名单;刷新请求在途时防止重复发送。
- 生命值在结算前保留当前数值并标待扣;盟约提示补本局禁用干员名单。
- 修正韩语界面和维多利亚英文按装备逐件加成的表述。
- 修复干员一次攻击后模型继续循环、多挥一次的问题,保留迟到消息的现有前摇同步方式。
- 修复 AI 托管遮罩挡住“在此页面继续”按钮。
- 设置增加「官方伤害数字」(默认关闭)。打开后只按 PRTS「伤害红字(暴击)」显示红色整数;关闭时仍显示每一次命中(#412)。
- 标题画面页脚增加「项目仓库」,在新标签页打开本项目仓库(#543)。
- 3D 棋盘在提取了官方场景时按战场显示沙地等 11 个场景,没有场景时仍用金属地块(PR #533,感谢 @andrew05060414)。完整包带上提取出的场景;精简包和源码可以在本机下载并提取,提取依赖缺失时继续用金属地块。
### 人机
- AI 选开局策略和构筑重心时,会软性让开仍在场队友已经选择的阵营;队友淘汰后取消。不锁库存,也不阻止立刻合成(PR #518 / #514,感谢 @IceCodeNew)。
### 工具与开发
- 玩家包里的 package.json 只保留指向包内文件的脚本;`npm test` 不再在没有测试的情况下显示通过。打包进去的说明里,指向未随包发布的文件的链接改为该版本标签的 GitHub 地址(#531、#530)。
- 增加开发用模拟一致性检查页。
## 0.2.4 — 2026-10-11
### 规则(按官方)
+1 -1
View File
@@ -165,7 +165,7 @@ The research JSONs in `docs/research/` (03, 05, 07) define **which** ids are nee
| Enemy Spine (PC build, premultiplied alpha) | isHarryh/Ark-Models `models_enemies/{key}/`, file names from `models_data.json` | `spine/enemy/{enemyId}/{stem}.*` |
| Enemy Spine that no dump carries (灼热源石虫 / 炽焰源石虫) | the local client only (`tools/local-extract/extract.py ENEMY_SPINES`, optional); never downloaded and never required: an overlay of the web alias (`enemies[id].spineLocal`) | `local/spine/enemy/{enemyId}/{stem}.*` (listed in `data/local-assets.json`) |
| Original token Spine overlays (40 summons: most 自选 summons, 凯瑟琳's 爬行号·防护单元, 凛御银灰's 风雪之眼, 香槟炸弹) | local-client extraction (`tools/local-extract/extract.py TOKEN_SPINES`, optional); the original overlay is preferred, with any listed web model retained as fallback | `local/spine/token/{tokenId}/{stem}.*` (listed in `data/local-assets.json`) |
| Official battlefield scenes (one per battlefield: meshes, lightmaps, albedo textures; DESIGN §15, DESIGN §30.17) | the scene bundles `scenes/activities/<season>/level_<stage>/…` (`tools/local-extract/extract.py --only scene`, optional). The client carries them only while the season runs; off season `tools/local-extract/fetch_scenes.py` downloads the bundles of the in-season version `26-04-13-12-31-42_e9b560` from the official CDN into `.cache/official-scenes/` (33 bundles, 22,801,308 bytes compressed on the Android list, md5-checked), and the materials / textures still come from the local client's theme bundles. The 0.2.5 full release zip includes the extracted files under `public/assets/local/scene/` when the maintainer extracted them before packaging; a lite zip and a source install may fetch and extract them (`node tools/setup.mjs --scenes`). The repository never stores the bundles or the extracted files. Without a scene the 3D board draws its procedural metal tiles | `local/scene/{stageId}/scene.json`, `scene.bin`, `lm{i}.*`; `local/scene/tex/{texture}.*` (listed in `data/local-assets.json`) |
| Official battlefield scenes (one per battlefield: meshes, lightmaps, albedo textures; DESIGN §15, DESIGN §30.21) | the scene bundles `scenes/activities/<season>/level_<stage>/…` (`tools/local-extract/extract.py --only scene`, optional). The client carries them only while the season runs; off season `tools/local-extract/fetch_scenes.py` downloads the bundles of the in-season version `26-04-13-12-31-42_e9b560` from the official CDN into `.cache/official-scenes/` (33 bundles, 22,801,308 bytes compressed on the Android list, md5-checked), and the materials / textures still come from the local client's theme bundles. The 0.2.5 full release zip includes the extracted files under `public/assets/local/scene/` when the maintainer extracted them before packaging; a lite zip and a source install may fetch and extract them (`node tools/setup.mjs --scenes`). The repository never stores the bundles or the extracted files. Without a scene the 3D board draws its procedural metal tiles | `local/scene/{stageId}/scene.json`, `scene.bin`, `lm{i}.*`; `local/scene/tex/{texture}.*` (listed in `data/local-assets.json`) |
| BGM | AA2 `voice` branch `audio/sound_beta_2/music/**` (大厅/休整期 `act1autochess`, 开战 `act13side/m_bat_kazimierz2_{1,2}` — 骑士之日 / 无畏者; the 开战 track follows the round: `_2` 无畏者 rounds 1–7, `_1` 骑士之日 from round 8) | `audio/bgm/{file}.mp3` |
| SFX (UI, battle, per unit) | AA2 `voice` `audio/sound_beta_2/**`, mapped from `audio_data.json` banks | `audio/sfx/{same sub-path}.mp3` |
| 干员战斗语音 | AA2 `voice` `audio/sound_beta_2/voice_cn/{charId}/cn_nn.mp3` (Chinese, `audio.voice`) and `voice/{charId}/cn_nn.mp3` (Japanese, `audio.voiceJp`: the same file names) — the lines `charword_table.json` lists (`placeType` = when the game plays one, `voiceAsset` = the path); `--voice-lang=jp|en|kr` fills `audio.voice` from `voice/`, `voice_en/`, `voice_kr/` instead | `audio/voice/cn/{charId}/{cn_nn}.mp3`, `audio/voice/jp/{charId}/{cn_nn}.mp3` (`audio/voice/{lang}/…` for another `--voice-lang`) |
+2 -2
View File
@@ -112,7 +112,7 @@ Top level: `{ season, seasonName, modes, economy, lpCapPerRound, bossOvertimeAft
| `poolCopies[tier]` + `poolCopiesOverrides` | 12/14/18/16/8/5 plus measured low-tier identity exceptions (DESIGN §29.8) | single-player copies; `coopPoolMultiplier: 2` doubles shared operators, not private DIY stock |
| `itemPoolCopies[tier]` + `itemPoolCopiesOverrides` | 4/6/7/8/7/3 plus eight measured exceptions (DESIGN §29.8) | shared shop-equipment ownership: normal 1, upgraded 2; non-shop effect-only equipment unlimited |
| `goldenCopies`, `mergeCount`, `mergeCountOverrides`, `itemMergeCount` | `3`, `3`, `{"chess_char_2_11_a":2}` (风丸), `2` | |
| `rewardOffer` | `{"count":3,"tierOffset":1,"maxTier":6,"price":0,…}` | merge reward: 3 **different** free chess of tier `min(shopLevel+1,6)` (a short tier tops up from the tier below; the player's stocked 自选 of that tier joins the roll, DESIGN §30.20; `PlayerState.pushRewardOffer`, user playtest #6 item 19) |
| `rewardOffer` | `{"count":3,"tierOffset":1,"maxTier":6,"price":0,…}` | merge reward: 3 **different** free chess of tier `min(shopLevel+1,6)` (a short tier tops up from the tier below; the player's stocked 自选 of that tier joins the roll, DESIGN §30.23; `PlayerState.pushRewardOffer`, user playtest #6 item 19) |
| `handFillOrder` | `"rightToLeft"` | |
| `shopOdds` | `{"model":"copyWeighted",…}` | [ASSUMED] roll model |
| `borrowCount`, `fallbackBondId`, `defaultBandId`, `defaultStartLp` | `20`, `"emptyShip"`, `"band_bldsk"`, `28` | |
@@ -643,7 +643,7 @@ prototype. Built by `tools/build-data.mjs buildBackups`; `shared/standIn.js` com
the four slots on the 自选编队 tab (`room.diy { picks }`, docs/PLAYING.md §3; shared/protocol.js checkDiyPicks keeps the
legal picks), the match takes the picks the seat had at its start (`PlayerState.diy`), and each slotted piece is sold in
that player's shop only — its own stock (the tier's pool copies, 8 / 5 [ASSUMED]). The ordinary shop draws it from the
调度中心 level `shopLevel`; the promotion reward draws 自选 of the reward tier, one shop level earlier (DESIGN §30.20).
调度中心 level `shopLevel`; the promotion reward draws 自选 of the reward tier, one shop level earlier (DESIGN §30.23).
It has no stock when every bond of it is banned this match, and it is the operator for every rule of that player (its data view:
server/match/player/diy.js, docs/META.md §3). The rules in the data (activity_table act2autochess `charShopChessDatas`; PRTS 卫戍协议, 卫戍协议:盟约
下半/PRTS盟约记录):
+1 -1
View File
@@ -5,7 +5,7 @@ This is the **single source of truth** for every implementer. Research lives in
Language: player-facing text is **Simplified Chinese** by default, with an English switch since 0.2.0 (§25.2, docs/I18N.md: UI strings through `t('中文')`, game texts from the official Chinese data or the official EN client's). Code, comments and identifiers are English.
Current development state: **0.2.5-dev**, §30, the state described by this document. Its fixed gifts, already displayed operator offers, combat corrections
and client/tool changes supersede the corresponding 0.2.4 rules below. Official battlefield scenes (DESIGN §15, DESIGN §30.17) are optional 0.2.5 local art: the full bundle includes them when extracted, and a missing scene keeps the metal board. It is not yet released.
and client/tool changes supersede the corresponding 0.2.4 rules below. Official battlefield scenes (DESIGN §15, DESIGN §30.21) are optional 0.2.5 local art: the full bundle includes them when extracted, and a missing scene keeps the metal board. It is not yet released.
Versions: the first public release was **0.1.0** (2026-10-02, the state of §0–§20.15); the releases after it add the player feedback and GitHub reports — 0.1.1 §21, 0.1.2 §22, 0.1.3 §23, 0.1.4 §24 — and **0.2.0** (2026-10-07; `CHANGELOG.md`) the maintainability refactor, two languages, 补位, 自选编队 and their fidelity work — §25 — **0.2.1** (2026-10-07) the 联防 battlefield restored, full potential and the GitHub fixes after it — §26 — and **0.2.2** (2026-10-09) per-operator 潜能 / 练度, Japanese voices, the statistics page, 失衡, whole-frame attack timing and the GitHub fixes after 0.2.1 — §27. **0.2.3** (2026-10-10; `package.json`, `shared/constants.js APP_VERSION`) 克莱门莎 and new modules, community fixes, text size, per-operator voices, installation, the opening reroll and local match recovery — §28. **0.2.4** (2026-10-11) the official shared card pool and item stock, Raid revival and #475, and the community fixes after 0.2.3 — §29. The labels v1 / v2 / v2.1–v2.5.2 in §0, §14–§20 and in the BALANCE / SIM comparisons name the design generations and the private playtest builds that came before it; they are kept as history.
+1 -1
View File
@@ -566,7 +566,7 @@ Any `choice:` handler whose EffectRef reuses its own key must guard like this (o
`min(shopLevel + 1, 6)`, so a tier-5 自选 piece can appear when the 调度中心 reaches 4 and a tier-6 piece when it
reaches 5 — one shop level before the ordinary shop, and not guaranteed. 卫戍协议/帮助 干员晋升 names one refresh one
tier above the 调度中心 and no separate pool; the owner decided on 2026-10-12 that the refresh includes 自选 of that
tier (0.2.0 had [ASSUMED] the shop-level gate for the reward too, DESIGN §25; §30.20 reverses it). An effect, reward
tier (0.2.0 had [ASSUMED] the shop-level gate for the reward too, DESIGN §25; §30.23 reverses it). An effect, reward
pool or 机变 card that grants the player a random operator draws its stock too
(effectsMeta `rollChess` / `rollPool`, the 驰援 fallback in choices.js: `ps.diyStockEntries()` — the roll's own tier
rules, no 调度中心 gate, bonds through the player's view; 「自选干员放入后模拟中的补给池随机范围也将被相应扩大」, 0.2.0), and
+4 -4
View File
@@ -87,7 +87,7 @@ field — units deploy one after another with a fixed delay from the battle star
预备干员-医疗 or Touch after counting deployed elites. [ASSUMED] Its effective targeting order precedes ordinary
initial deployments (`preBattleAggroSeq`); its actual `deploySeq` still identifies the later runtime spawn. Prepared
slots on a shared field follow player order [ASSUMED]. A later `spawnMapChar` without this option keeps its ordinary
summon order (§30.17).
summon order (§30.22).
Register hooks before the first step (e.g. `opts.setup(battle)` or right after `new Battle`).
@@ -382,7 +382,7 @@ enemy: 隐匿 kept out, 起飞 not), 【污染秽蚀】 on every ally inside (fl
`alliesInRadius`) — through `dealDamage`, so shields absorb a damage
tick, damage-taken modifiers scale it and it counts for 受击回复 SP and TAKE_DAMAGE skills like any hit (§4; element fills
excepted). 【污染秽蚀】 (萨卡兹枯朽战车's 秽蚀轰击,
萨卡兹枯朽战士 / 组长's death — none when either dies while silenced. The owner's official-play recall of 2026-10-12 is that a silenced death creates no fog, which contradicts the PRTS / in-game text 「不可沉默」; only `enemy_1267_nhpbr` and `enemy_1267_nhpbr_2` share this PollutedDie ability, DESIGN §30.20) is **true** damage, 50 / 25 per second on low / high ground (PRTS "每秒受到50/25点真实普通伤害 …
萨卡兹枯朽战士 / 组长's death — none when either dies while silenced. The owner's official-play recall of 2026-10-12 is that a silenced death creates no fog, which contradicts the PRTS / in-game text 「不可沉默」; only `enemy_1267_nhpbr` and `enemy_1267_nhpbr_2` share this PollutedDie ability, DESIGN §30.23) is **true** damage, 50 / 25 per second on low / high ground (PRTS "每秒受到50/25点真实普通伤害 …
同名效果不叠加", user playtest #6): a unit covered by several zones takes one tick per second (`unit.mem.pollutedAt`), so
a crowd of dying 萨卡兹枯朽战士 totals 50 / s, not 50 × n. It is "可对空,无视无法选择": it also burns an airborne 起飞 ally
(`ignoreSelect`), at the low-ground rate on a low tile. The other zones are no exception to 对地规避: a ground enemy's
@@ -554,7 +554,7 @@ returns their current `weight` (including modifiers). The same tick's count and
list and budget (DESIGN §28.27); this is local to the kit, not a change to general displacement.
**Hit areas (`body.js`, user playtest #5 item 10).** A regular enemy is a point: in a grid range when the tile of its
position (`roundHalfEven(y)`, `roundHalfEven(x)` — PRTS 作战机制 "四舍六入五成双"; `Math.round` would take 2.5 to 3) is a range tile, in a radius when its position is (DESIGN §3). An enemy held on the field edge is inset by `FIELD_EDGE_INSET` (1/1048576) [ASSUMED] so that rounding keeps it on the edge tile; movement, knockback and a unit's standing tile for range keys still use `Math.round` (§30.20). A huge enemy (巨型单位:
position (`roundHalfEven(y)`, `roundHalfEven(x)` — PRTS 作战机制 "四舍六入五成双"; `Math.round` would take 2.5 to 3) is a range tile, in a radius when its position is (DESIGN §3). An enemy held on the field edge is inset by `FIELD_EDGE_INSET` (1/1048576) [ASSUMED] so that rounding keeps it on the edge tile; movement, knockback and a unit's standing tile for range keys still use `Math.round` (§30.27). A huge enemy (巨型单位:
`enemy.hitArea` from data/enemies.json `hitArea` — 假想敌:胄 / 管 / 盐风主教昆图斯 / 阿利斯泰尔 / “萨米的意志”, PRTS
"受击判定区域为长4.95、宽2.95的长方形,向上偏移1.0") is hit anywhere on a rectangle `w` × `h` tiles centred on its position
moved `dx` columns right / `dy` rows up: it occupies every tile the rectangle overlaps (`bodyKeys` — 5 × 3 tiles; PRTS
@@ -1360,7 +1360,7 @@ header of professions.js).
| loopshooter | 回环射手 (user playtest #3): every attack throws a boomerang (`ai.js throwBoomerang`, projectile `'boomerang'`) out to the target at 15 tiles/s — it hits on arrival — and back to the thrower's current position at 3.75 tiles/s without damage (PRTS 跃跃 "投射物飞行速度15,返回时飞行速度3.75"); attacks only while holding it (every boomerang thrown caught — "必须回收全部回旋投掷物才可以进行下一次攻击", `unit.trait.boomerangsOut`) and with the attack cooldown ready, so the real interval is the longer of the two; a target dead mid-flight is not hit (it still flies to the last position and back); knocked out / withdrawn ⇒ lost, a redeployed thrower holds a fresh one; 跃跃 S2's extra boomerangs share the one flight (cnt hits); each catch fires `boomerangCaught`, and an attack profile's `boomerangOnward(ctx)` flies it on after the first hit before it turns back — ctx `hit` (a hit of the same attack), `comeBack(x, y)` once (a content error sends it back from the hit point): 娜仁图亚 S1 bounces, S2 dashes on and hits on its way back (kits/ops/op-narant.js) |
| reaperrange | hits every enemy in range; ×1.5 (bb atk_scale) on the trait front grid (or its own line ahead) — both along its direction |
| chain | chain N (trait text/bb max_target) with −15 % per jump (bb chain.atk_scale), 1.7-tile jumps (constants.js CHAIN_RADIUS, PRTS 溅射半径一览: 链术师 1.7; 1.8 until 0.1.1), sluggish on each hit |
| funnel | normal attack: one 100 % ATK body hit plus separate drone additional damage, 20 % → +15 %/hit on the same target → 110 % (bb init/delta/max; modules can change init/cap). `funnelMul` holds the drone ramp; `dmgMul` applies to both. Extra drones (`hits`) do not duplicate the body; an unreleased skill attack can set `funnelBodyHits` (至简 S2: two body hits and two additions). Body and additions share an `attackId`, but only the body is `isAttack`; additions carry `addition, funnel`. [ASSUMED] body instances first at the existing impact, one ramp per volley. A skill that only buffs or retargets the normal attack keeps the body; `isSkill` does not remove it. `funnelBodyHits: 0` is drone-only (荒芜拉普兰德 S2). 耶拉 S2 detaches `funnelMul`: one 100 % `isAttack` body in range, the unreleased addition off, and `1 + attack@cnt` arts skill drones (`kjera:drone`, `isSkill`, not `isAttack`) that keep the lock until the enemy dies or the skill ends. [ASSUMED] Those drones use the trait ramp; her blackboard has no drone scale. The base form continues the per-target ramp (one step per volley on a shared target) and writes it back; the hidden form restarts each drone at init and does not write the scales back. [ASSUMED] No flight delay; an untargetable lock is dropped and retargeted; stun and disarm do not pause the drones. 澄闪's skills and 荒芜拉普兰德 S3 stay on their own `dealDamage` paths. A normal deployment resets target, scale and any per-target ramp map to init, including revival against the same living target. A free move (`moveRedeploy`, the same carry as a 秘术师's stored energy and 乌尔比安 S3) keeps the ramp. An in-flight drone recomputes the ramp on impact. 洛洛 S2 detaches this multiplier from new body shots and inherits the trait ramp in an independent skill tick: `rockr:drone`, arts, `isSkill:true`, `isAttack:false`. Older projectiles cannot change its local ramp. A living selectable lock need not remain in body range; the drone returns on a kill or when the skill ends, and ending hands the ramp back and restores the normal multiplier (§30.19) |
| funnel | normal attack: one 100 % ATK body hit plus separate drone additional damage, 20 % → +15 %/hit on the same target → 110 % (bb init/delta/max; modules can change init/cap). `funnelMul` holds the drone ramp; `dmgMul` applies to both. Extra drones (`hits`) do not duplicate the body; an unreleased skill attack can set `funnelBodyHits` (至简 S2: two body hits and two additions). Body and additions share an `attackId`, but only the body is `isAttack`; additions carry `addition, funnel`. [ASSUMED] body instances first at the existing impact, one ramp per volley. A skill that only buffs or retargets the normal attack keeps the body; `isSkill` does not remove it. `funnelBodyHits: 0` is drone-only (荒芜拉普兰德 S2). 耶拉 S2 detaches `funnelMul`: one 100 % `isAttack` body in range, the unreleased addition off, and `1 + attack@cnt` arts skill drones (`kjera:drone`, `isSkill`, not `isAttack`) that keep the lock until the enemy dies or the skill ends. [ASSUMED] Those drones use the trait ramp; her blackboard has no drone scale. The base form continues the per-target ramp (one step per volley on a shared target) and writes it back; the hidden form restarts each drone at init and does not write the scales back. [ASSUMED] No flight delay; an untargetable lock is dropped and retargeted; stun and disarm do not pause the drones. 澄闪's skills and 荒芜拉普兰德 S3 stay on their own `dealDamage` paths. A normal deployment resets target, scale and any per-target ramp map to init, including revival against the same living target. A free move (`moveRedeploy`, the same carry as a 秘术师's stored energy and 乌尔比安 S3) keeps the ramp. An in-flight drone recomputes the ramp on impact. 洛洛 S2 detaches this multiplier from new body shots and inherits the trait ramp in an independent skill tick: `rockr:drone`, arts, `isSkill:true`, `isAttack:false`. Older projectiles cannot change its local ramp. A living selectable lock need not remain in body range; the drone returns on a kill or when the skill ends, and ending hands the ramp back and restores the normal multiplier (§30.26) |
| mystic | 秘术师 (PRTS 分支特性信息 秘术师, GitHub #181): at its attack check (the attack ready, able to act, not disarmed) with no valid target — no target, or its kit's `canAttack` false (深靛 never picks a bound enemy) — it stores one energy (`storeEnergy`, up to bb times: 3, 深靛's MSC-X 4), an attack action: the attack interval restarts; a full store idles with the attack ready. The energies leave with its next attack that happens (`releaseEnergy` in `performAttack`, after `beforeAttack`: an attack cancelled before its shot keeps them) and land with the main hit, one arts attack hit each (`hitsFn` reads the hit's `info.energy`); a redeployment holds none [ASSUMED]. 维伊 / 黑键 plug their own `storeEnergy` (转置能量, elite energies) into the same check |
| phalanx | no attack & DEF +200 %, RES +20 (bb) while the skill is off; while on, `rangeAoe`: each attack strikes every selectable enemy on its range at once (blocked enemies included; a stealthed one only when revealed or blocked), the same damage near and far, instant (`'beam'`) — "群体法术伤害" (secondary: Terra Wiki, Phalanx Caster: "attacks hit all enemies within their range"; supporting: PRTS 林 S3 备注 "单次普攻最多触发1次效果" — one normal attack can kill several — the same 锁定攻击范围 shape as the 轰击术师, and PRTS 溅射半径一览 documents no splash radius for it (it omits the 撼地者 too, so this is not proof); no primary source states a target cap; community report E3: it used to be one bolt + a 1.1 splash). 卡涅利安's charged S1 keeps the skill-off trait, 不攻击 included (kit `canAttack`, PRTS 备注) |
| physician | heal the lowest HP% injured ally in range (a skill `targeting.maxTargets` widens any heal profile) |
+3 -3
View File
@@ -60,7 +60,7 @@ The owner's `prepMapChars` (外勤医疗's 预备干员-医疗, or another displ
preparation views: tapping one opens its existing operator-style detail card and highlights its attack range from
its board-space position and facing, including on a mirrored boss half. They cannot be dragged, sold or retreated
from this preview. The inspection affordance does not make the preview a combat unit; the battle sim still creates
the selected variant at battle start (§30.17).
the selected variant at battle start (§30.22).
Audio: autochess BGM per phase, UI SFX (buy/sell/refresh/level/merge/ready/timer), per-unit attack/hit SFX (throttled; an impact plays for a hostile attack's phys / arts / true damage only, never an operator's skill-mode file for a normal attack, ≤ 2 copies of one battle sound — §18.4; a skill cue that reaches the client before its unit — the sim emits a deploy-tick cast ahead of the unit's `['spawn']` — is held and sounds once when the unit is tracked, `AudioManager.pendingSkill`, GitHub PR #292 by @LimitlessHPPK; entering a field late hands the sound the buffered `spawn` tuples only, `screens/game/early.js audioEarly`, so no old death, deploy or cast replays), boss music in R14/15.
@@ -70,7 +70,7 @@ Audio: autochess BGM per phase, UI SFX (buy/sell/refresh/level/merge/ready/timer
`tools/local-extract/extract.py` (Python: UnityPy + lz4 + Pillow; decodes Arknights' custom **LZ4AK** bundle compression via `aklz4.py`) extracts the art the web download does not include (some of it, most official HUD sprites among it, is on the public mirror too — §22.5) from a locally installed client (CrossOver Windows build or PlayCover iOS build) into `public/assets/local/**` and writes `data/local-assets.json` (`{ groups: { '<subdir>': { name: { path, w, h, kind } } } }`). Everything here is **optional**: clients must render correctly when the file or any entry is missing (fall back to the web assets / procedural art). The emotes and the guide pages below are on the public mirror too (§22.5): fetch-assets downloads them (data/assets.json `ui['emoticon/<dir>/<picId>']`, `ui['guide/<key>']`) and the client shows the local copy first, then that one (`data.js artUrls`); docs/DEPLOY.md §6 lists what still needs the client.
- `map/autochess/TX_autochessi_*` — the real autochess board atlas (`_D` diffuse 2048² with floor tiles, gold-framed high-ground plates, REINFORCEMENTS bench pads, EQUIPMENTS pads, crates, gates; `_N/_M/_E` normal/mask/emission; `common_D` device icons; `BG` backdrop). `map/autochesssand/*` — the textures and materials of the sand theme (the theme of nine of the eleven battlefield scenes, §15).
- `scene/<stageId>/` and `scene/tex/` — the official scene of a battlefield (§15 "Official battlefield scenes", DESIGN §30.17): `scene.json` (materials, key light, chunk records), `scene.bin` (the meshes in board space), the lightmap pages `lm<i>`, and the materials' albedo textures shared by the scenes. Read from the scene bundles `scenes/activities/<season>/level_<stage>/…`, which the client carries only while the season runs: `extract.py --only scene` takes them from the client or from `--scenes <dir>` / `.cache/official-scenes/*` (`tools/local-extract/fetch_scenes.py` downloads them from the official CDN's in-season version). The 0.2.5 full release zip includes the extracted files when the maintainer extracted them before packaging; a lite zip and a source install may fetch and extract them (`node tools/setup.mjs --scenes`). The repository never stores the bundles or the extracted files.
- `scene/<stageId>/` and `scene/tex/` — the official scene of a battlefield (§15 "Official battlefield scenes", DESIGN §30.21): `scene.json` (materials, key light, chunk records), `scene.bin` (the meshes in board space), the lightmap pages `lm<i>`, and the materials' albedo textures shared by the scenes. Read from the scene bundles `scenes/activities/<season>/level_<stage>/…`, which the client carries only while the season runs: `extract.py --only scene` takes them from the client or from `--scenes <dir>` / `.cache/official-scenes/*` (`tools/local-extract/fetch_scenes.py` downloads them from the official CDN's in-season version). The 0.2.5 full release zip includes the extracted files when the maintainer extracted them before packaging; a lite zip and a source install may fetch and extract them (`node tools/setup.mjs --scenes`). The repository never stores the bundles or the extracted files.
- `ui/{common,battle,outer}/*` — every sprite of the three official autochess UI bundles (tier chips I–VI, bond disc rings, frames, banners, HUD pieces, badges, backgrounds, mode art).
- `emoticon/<dir>/<picId>.png` — the 36 official battle emotes, 6 themes (`shared/constants.js → EMOTE_THEMES / EMOTES`, `emoteArtPath`; data/emotes.json); also downloaded from the mirror (§22.5).
- `guide/autochess_{home,shop,handbook}_N.png` — the 19 official tutorial pages; stored squashed to 1024² — **display at 16:9** (the mirror copies too, §22.5).
@@ -182,7 +182,7 @@ the actor returns to base/skill idle. Late operator events still start at the st
Connection recovery sits above the AI-away overlay and below global modals (§30.8), so a replaced session can
be reclaimed by pointer while away. This does not change the stacking behavior of modals nested inside a screen.
§30.17: 设置 →「官方伤害数字」 defaults off. Off, damage numbers stay the typed every-hit popups. On, and only
§30.20: 设置 →「官方伤害数字」 defaults off. Off, damage numbers stay the typed every-hit popups. On, and only
while 「显示伤害数字」 is also on, the field draws a red integer for a `dmg` tuple marked `'r'` and a yellow MISS
for a dodge fx whose payload is `num: 'm'` (PRTS 作战机制 「伤害红字(暴击)」). Ordinary hits and heals draw no
digits in that mode. The mark is computed in the sim; the random offset above the model is client-side. The
+6 -6
View File
@@ -13,7 +13,7 @@ Expanded automatic skill areas (§30.11) include 司霆惊蛰 S2's current low-t
initial area, 斩业星熊 S3's selectable air targets, and 予愿安洁莉娜 S3's initial 3-9 ∪ x-4.
Permanent range extension, control/operation cooldown and targetability still apply; normal attacks are unchanged.
Prepared 外勤医疗 map characters (§30.17) keep an earlier aggro order than ordinary initial operators. Preparation
Prepared 外勤医疗 map characters (§30.22) keep an earlier aggro order than ordinary initial operators. Preparation
can open their detail card and board-space range. Their `deploySeq` is still the later runtime spawn. The retained
team grant (§30.14) is unchanged.
@@ -135,7 +135,7 @@ Engine helpers (content must use these, never touch internals): `battle.dealDama
slot behind the ordinary starting operators in effective deployment priority: both variants receive an earlier
`aggroSeq`, while their actual `deploySeq` still records the later runtime creation and guards deployment-scoped
effects. On a shared field, prepared slots follow player order [ASSUMED]. An ad-hoc map-character spawn during
combat retains ordinary summon priority. See §30.17 and SIM.md §1.
combat retains ordinary summon priority. See §30.22 and SIM.md §1.
- **Initial deployment** at t=0, free: operators by column — the left column first, top to bottom within a column (right-side boss player: from its own left, the highest field column) — then the summons (PRTS 卫戍协议/帮助 "按从上到下>从左到右的顺序部署。优先部署干员,随后为召唤物", read as a scan: down each column, the columns left to right — the order PRTS gives the 阿戈尔 devour, "更靠左和靠上"; row-major until 0.1.3, §23.23; `aggroSeq` ranks every start-of-battle summon after all operators) — a skill's placed summon (赫默 医疗探机, 巫恋 诅咒娃娃) included, once and free ("所有手动部署的召唤物,无视所属干员的持有状态…作战开始时立即部署一次"; afterwards it re-appears on its tile each time the owner's skill gives one, §20.1); on a shared field (联防, boss) the players' i-th operators deploy together [ASSUMED]. Deploy effects fire (`deploy` with `initial: true`). Then operators carried into 联防 knocked out (`carryState.down`) are forced out (`FORCED_EXIT`, HP 0, §19.3). Then `battleStart`, after which the forced-out operators' timers are re-read (redeploy-time effects that start with the battle, e.g. 机变 征召, cover them too).
- **DP**: per player, start 10, +1/s, cap 99; used only for auto-redeploy (dead op: after `respawnTime`, if the tile it lies on is free and DP ≥ cost ⇒ redeploy there with full HP, SP = initSp). A knocked-out operator (and, since 0.1.2, one forced out by its own effects, §22.15) stays **down** on the tile it fell on — its own home when it fell on another board piece's home (that piece on the field or not) and its home is free, and 乌尔比安 knocked out while his S3 has moved him always on his deployment tile when it is free (the owner's deviation of 2026-10-07, `Unit.downAtHome`, §25.17.3) — until it redeploys there, and no ally deploys or moves onto that tile meanwhile (PRTS 卫戍协议/帮助 §作战阶段 单位部署; `Battle.downOn` / `restTile` / `_layBody`, §21.24; b.snap `down`, §18.3: counting / waiting for DP / its tile taken, a safeguard) — also one that entered 联防 knocked out (`FORCED_EXIT`, its full redeploy timer — confirmed by the user — with the battle-start redeploy effects, §19.3); summons, devices and enemies leave at once.
- **Blocking** (contact radius, PRTS 游戏数据基础 §阻挡半径 / 作战机制 "中点判定…案例:阻挡"; `constants.js BLOCK_RADIUS`, `Battle._checkBlock`, §19.2): an operator with free capacity blocks an unblocked, blockable enemy whose position lies within its block radius of its centre — ground 0.7071 (squared 0.49999037), 0.8944 × the blocker's 阻挡半径倍率 for blockFly units vs flyers (起飞; mod `blockRadiusScale` = 倍率 − 1 — PRTS 游戏数据基础 "飞行阻挡半径 = 0.8944 × 阻挡半径倍率", 凯尔希·思衡托 +0.23), devices 0.4472 (阻隔工事 / 障碍物); air units (FLY, 近地悬浮, 浮空) only by blockFly units. A ground enemy is never blocked by a unit standing on a tile ground units cannot pass (围墙 / 围栏: PRTS 地形机制 "部署在其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人" — an enemy pushed or pulled against the fence walks on; air blocking there stays [ASSUMED], §21.23) nor by an airborne (起飞) unit, which blocks flyers only (§21.22). An enemy holding 不可阻挡 (PRTS 异常效果 BLOCK_FREE 「无法阻挡/被阻挡,自动解除阻挡」) — `unblockable` (恐惧, 诱导, enemy abilities), 浮空, and 沉睡 (SLEEPING = 无法行动+无敌+不可阻挡) — is never blocked and is released at once: a sleeping enemy frees its blocker's slot, stays where it is and, once awake, is blocked again only by a blocker with room (§24.9). The nearest such operator wins (ties: scan order [ASSUMED]). It is re-checked every tick, moving or not, so another operator in contact with room takes the enemy over when its blocker dies, is withdrawn or is stunned, and an operator whose capacity frees up grabs an overlapping enemy; one that finds no room walks on. A stunned or frozen enemy is checked too — 晕眩 / 冻结 hold no 不可阻挡 (PRTS 异常效果: the STUN / FROZEN state machines stop its moves and attacks) —, so an operator redeployed beside a held enemy blocks it where it stands and lifts its 隐匿; one held short of contact is blocked once it walks in after the status (GitHub #232; until 0.2.0 the check waited for the status to end). A head-on enemy stops at contact (≈ 0.71 tile), outside the blocker's tile. Enemy uses `blockCnt` capacity (default 1). Blocked enemies stop moving and attack their blocker if melee (or anyone in range if ranged, blocker first). **Every blocker** — melee units (重装要塞 / 领主 / 哨戒铁卫 included), summons and a ranged operator on a melee tile alike — whose attack hits enemies may always target the enemies it blocks, in range or not, whatever its facing, and targets them first — a 速射手's air priority (优先攻击空中单位) excepted, which comes before the enemy it blocks (the owner's decision of 2026-10-08, GitHub #220) — ("可以选择且优先选择阻挡单位", PRTS 选择器; the user's rule after playtest #6, "阻挡了就一定要能打到": officially the collision pushes a blocked enemy to its blocker's front; `Battle.blockedTargets`, `targeting.js sortEnemyTargets`; §20.3 — it replaces the playtest #5 QA's melee-only restriction of §19.2). A healer (dmgType `heal`, or a skill attack turned into a heal) selects injured allies only and keeps healing while it blocks (PRTS 卫戍协议/帮助 "对于医疗干员(咒愈师分支除外),攻击目标为需要治疗的单位"; §21.17); 咒愈师 follow the blocker rule. The huge leaders are 自缚 + unblockable (§7).
@@ -186,7 +186,7 @@ Profession traits (default behaviours implemented once in the engine, keyed by `
---
Unreleased funnel drones deal additional arts damage alongside the ordinary attack (PRTS 分支特性信息 驭械术师, §30.17).
Unreleased funnel drones deal additional arts damage alongside the ordinary attack (PRTS 分支特性信息 驭械术师, §30.24).
The engine keeps a 100 % ATK body instance and a separate drone instance, each through mitigation and shields.
`funnelMul` holds only the drone ramp; the attack's `dmgMul` (至简's talent) is shared once. Extra attached drones
raise `hits`, not the body count; 至简's charged S2 sets `funnelBodyHits` to two. Both share one `attackId`, attack
@@ -195,15 +195,15 @@ instances precede additions at the existing projectile impact; consecutive hits
that only buffs or retargets the normal attack keeps the body; `isSkill` is not the switch. `funnelBodyHits === 0`
is drone-only (荒芜拉普兰德 S2): the ramp stays inside those hits. 耶拉 S2 detaches `funnelMul` the way 洛洛 S2 does:
one 100 % body inside her range, the unreleased addition off, and the released drones as separate skill hits that
keep the lock until the enemy dies or the skill ends (§30.17). 澄闪's skills stay on their own `dealDamage` paths.
keep the lock until the enemy dies or the skill ends (§30.24). 澄闪's skills stay on their own `dealDamage` paths.
Funnel ramps return to the initial scale on a normal deployment, including automatic revival against the same living
target (§30.18). The reset clears the current target, the scale and any per-target ramp map, and leaves other trait
target (§30.25). The reset clears the current target, the scale and any per-target ramp map, and leaves other trait
state alone. A free move (`moveRedeploy`, the same carry as a 秘术师's stored energy and 乌尔比安 S3) keeps the ramp.
An in-flight shot recomputes the ramp when it lands, so a projectile launched before the reset can still step the new
ramp.
洛洛 S2 releases its trait drone into an independent skill tick (§30.19). Acquisition uses the body's normal target
洛洛 S2 releases its trait drone into an independent skill tick (§30.26). Acquisition uses the body's normal target
selection; a living selectable lock stays valid outside the body's range and returns only when that enemy dies or the
skill ends. The body retains its own ranged ordinary attacks. The released ramp inherits the trait state but is
isolated from older projectiles, and while it is out the unreleased addition is off. Ending the skill returns that
+2 -2
View File
@@ -60,7 +60,7 @@ Summons (§20.1): an operator on the board sends its manually deployable summons
Equipment (research 04 §2 + addendum, 09 §1.2): 2 slots per chess; a third item on a full carrier replaces the equipped item `replaceUid` names (the replace dialog's pick, official `UseEquipUp.unloadInstId`; absent ⇒ the oldest; a uid not equipped on the target ⇒ `BAD_TARGET`, nothing changes) and the replaced item is destroyed. A consume-on-equip item (盟约之币, 博士投影 …) on a full carrier replaces the same way before it resolves, so the carrier is left with a free slot (the normal 博士投影 takes it until the next round start); a target its effect refuses (博士投影 on an elite) keeps both items — PRTS 卫戍协议/帮助 "达到上限强行佩戴会改为替换装备" names no exception (GitHub #263; the client opens the replace dialog for it, `equipReplaces`). Equipped items are otherwise **locked**: `destroy` (销毁) accepts hand / temp items only (`BAD_TARGET 'equipped items are locked'`); equipment goes back to the hand only when its carrier merges, is sold, or is destroyed by 突变细胞's transformation (the cell itself returns too; PRTS 帮助 "在失去该干员(干员出售、销毁、合并等)…时自动卸除", §21.1) — a sale is refused with `HAND_FULL` when there is no room for it; returned equipment is stowed before the operator a transformation gains and before a merge elite's summon cards, and every path that hands the player an item — returned equipment included — ends with the auto-merge, so no player holds two identical mergeable normal items (§21.7).
Economy/shop/pool/merge/hand rules: exactly as research 00-INDEX §3–§4 (income `min(3+r,12)`; prices by tier; refresh 1; freeze toggles all; sell +1; items not sellable; upgrade prices per mode with −1/round; single-player pool copies 12/14/18/16/8/5 plus measured exceptions; co-op shared operators use twice those counts, while equipment has separate shared stock (DESIGN §29.8); elite = 3 copies; odds = copy-weighted draw over unbanned visible chess with tier ≤ level; merge 3 (风丸 2) → elite onto the consumed deployed copy's tile, else to the hand (§20.11) + reward offer of 3 **different** free chess of tier `min(level+1, 6)` (copy-weighted, including the player's stocked 自选 of that tier — one shop level before the ordinary shop, §30.20; a tier short of different chess tops up from the tier below [ASSUMED], §20.6); full hand blocks every buy / reward pick, a merge-completing one too (PRTS 卫戍协议/帮助 §手牌区, GitHub #82); overflow to temp; a free hand slot pulls the temp pieces back in at once, right → left (`PlayerState._fillHandFromTemp`); temp blocks ready).
Economy/shop/pool/merge/hand rules: exactly as research 00-INDEX §3–§4 (income `min(3+r,12)`; prices by tier; refresh 1; freeze toggles all; sell +1; items not sellable; upgrade prices per mode with −1/round; single-player pool copies 12/14/18/16/8/5 plus measured exceptions; co-op shared operators use twice those counts, while equipment has separate shared stock (DESIGN §29.8); elite = 3 copies; odds = copy-weighted draw over unbanned visible chess with tier ≤ level; merge 3 (风丸 2) → elite onto the consumed deployed copy's tile, else to the hand (§20.11) + reward offer of 3 **different** free chess of tier `min(level+1, 6)` (copy-weighted, including the player's stocked 自选 of that tier — one shop level before the ordinary shop, §30.23; a tier short of different chess tops up from the tier below [ASSUMED], §20.6); full hand blocks every buy / reward pick, a merge-completing one too (PRTS 卫戍协议/帮助 §手牌区, GitHub #82); overflow to temp; a free hand slot pulls the temp pieces back in at once, right → left (`PlayerState._fillHandFromTemp`); temp blocks ready).
**Temp overflow (临时整备区, row 8; user playtest #3 item 3).** Passive gains that find the hand full (merge elites, grants — the operator a 突变细胞 transformation gains included, §21.1 —, battle-result rewards, equipment returned by a merged / sold / transformed carrier) overflow into the 5 temp slots, and Ready is refused while any is occupied (official "直到溢出情况排除才可开始进行作战"). A temp piece is resolved — a chess sold back to the pool with its summons removed, items destroyed, a summon stack removed (it comes back at the next round start, PRTS "干员所属召唤物会于下一回合返还", §20.1) — only at the deadline of the **first prep in which its player could act on it** (`PlayerState.tempDue(piece)` vs `prepsEnded`; every write into a temp slot goes through `_putTemp`, which records it): a piece that arrived during a prep before Ready is due at that prep's end; one that arrived after Ready or during the `<休整期结束时>` effects, or outside PREP (COMBAT, 联防, SETTLE — battle-result grants, a SETTLE merge's elite, returned equipment —, the next ROUND_START, 机变) is kept, visible and usable (move to a free hand slot, place, equip, use, destroy, sell) through the **next** prep. Un-readying (`setReady(false)`) makes whatever arrived while ready due at the current prep. ROUND_START no longer wipes temp (it used to destroy what SETTLE had put there before the player ever saw it). A merge's elite whose merge consumed a deployed copy takes that copy's tile and facing (§20.11); otherwise it goes to the hand, overflowing into temp (also outside PREP). `server/match/audit.js` (`tools/matchrun.mjs --check`) tracks the arrivals itself and flags any temp piece that outlives its due prep. The UI frames the row on the board with the rule (§17.5).
@@ -130,7 +130,7 @@ adjusted count and reset scope stay limited to its own operators; the DIY export
active bonds overlap another living teammate's opening strategy. Human and AI teammates are treated equally; it
neither reserves stock nor prevents a stronger purchase. Existing strategy presets and rehearsal counts are unchanged.
A living teammate's selected strategy also soft-reserves its bonds for bot strategy selection and focus planning
before any member is deployed (§30.21). The reservation ends when that teammate is eliminated. It does not hard-exclude
before any member is deployed (§30.28). The reservation ends when that teammate is eliminated. It does not hard-exclude
a strategy, reserve stock, or stop an immediate merge. A reserved strategy keeps a quarter of its unreserved draw
weight (`SOFT_BAND_RESERVE` = 0.25), so it can still be chosen. Mode-inactive bonds stay weight 0 (DESIGN §21.26).
+24 -24
View File
@@ -315,7 +315,7 @@ stage rewrites those six Markdown files: a relative link whose target ships stay
use. Source copies in the git checkout stay relative. Golden unchanged. Tests: `test/package-player.test.js`,
`test/package.test.js`, `test/docs-paths.test.js`.
### 30.17 Official damage numbers and the title-page repository link
### 30.20 Official damage numbers and the title-page repository link
Issues #412 and #543. #412's font swap, element-colour pass and bold crit type are not part of this change.
The new setting 「官方伤害数字」 (`officialDamageNumbers`) defaults off. While it is off, every rounded hit and
@@ -367,7 +367,7 @@ Tests: `test/sim/official-damage-numbers.test.js`, `test/ui/official-damage-numb
`test/render/official-numbers.test.js`. Golden digests do not move: no new event kind is emitted, and the extra
tuple field is not part of the digest. Player notes: PLAYING; client notes: design/client.md.
### 30.17 Official battlefield scenes (#532)
### 30.21 Official battlefield scenes (#532)
Report: the web board draws the metal theme for every battlefield. The reporter asked for the sand theme.
PR #533 by @andrew05060414.
@@ -415,7 +415,7 @@ layout shared by scenes.py and load.js, sub-graphic groups, RGBM decode, the loa
with a stub renderer: scene on / areas / fallback). `test/scene-assets.test.js` (setup's scene step, the full plan
ships extracted scene files, the lite plan ships none, git ignores the bundles).
### 30.17 Prepared 外勤医疗 target order and preparation inspection
### 30.22 Prepared 外勤医疗 target order and preparation inspection
PR #523 by @YinqiMargatroid, continuing #451. PR #451 made 预备干员-医疗 visible in preparation and left its initial
aggro order unchanged. The owner decided on 2026-10-12 to take both halves of this report as the author describes them.
@@ -465,7 +465,7 @@ continues the same layer gap (191 → 206). The human settle row first differs a
already differed from 0.2.4 (§30.9, §30.16), so the release-relative total is now 46. The other 286 digests match
the preceding candidate.
### 30.20 Silenced 枯朽 death fog, and 自选 in the promotion reward
### 30.23 Silenced 枯朽 death fog, and 自选 in the promotion reward
Two owner decisions of 2026-10-12. Neither is a new pool or a change to any other silence rule.
@@ -522,7 +522,7 @@ allowed. The digest records
shop draws, fielded pieces, board hashes and the rng state, not an untaken reward card, so the stored scenario does
not move. The release-relative total against 0.2.4 stays 46.
### 30.17 Funnel normal attacks keep a body hit
### 30.24 Funnel normal attacks keep a body hit
PR #537 by @Xinglan233. [PRTS 分支特性信息 驭械术师](https://prts.wiki/w/分支特性信息/data) says a drone that has not
been released by a skill deals additional damage on top of the operator's attack: 20 % ATK at first, +15 on the same
@@ -563,10 +563,10 @@ the unreleased attack: one body hit plus the two additions, at the raised ATK. A
Kits that stored the ramp on `dmgMul` (至简, both 耶拉 forms, 澄闪 S2) now store it on `funnelMul`.
Tests: `test/sim/funnel-body.test.js`, and the funnel cases in `kits_t3`, `kits_t4`, `kits_t6`, `kits_alt_t6`,
`kits_alt_t2` and `op_gdglow`. The golden moves from this correction, measured against the candidate after §30.22,
are §30.23.
`kits_alt_t2` and `op_gdglow`. The golden moves from this correction, measured against the candidate after §30.29,
are §30.30.
### 30.18 Redeploy resets the drone ramp
### 30.25 Redeploy resets the drone ramp
PR #536 by @Xinglan233. The same branch page says that changing target, or redeploying the operator, restores the
drone damage to its initial value at once.
@@ -578,7 +578,7 @@ impact, so a shot launched before the reset can step the new ramp. That limit is
Tests: `test/sim/funnel-redeploy.test.js`, `test/match/funnel-redeploy.test.js`.
### 30.19 洛洛 S2 keeps its lock outside her range
### 30.26 洛洛 S2 keeps its lock outside her range
PR #535 by @Xinglan233. The official skill table `skchr_rockr_2`, as recorded in `docs/research/03-operators.md`,
says the released drone stays locked until the enemy is killed or the skill ends, then returns. Leaving her attack
@@ -597,7 +597,7 @@ existing paths. 立于磐石 is unchanged.
Tests: `test/content/rockrock-s2-lock.test.js`, and the 洛洛 case in `kits_t1t2`.
### 30.20 Hit tiles use half-even rounding
### 30.27 Hit tiles use half-even rounding
PR #520 by @Cloudnyco. PRTS 作战机制 (oldid 433935, 「碰撞体积与位置识别」) says the struck unit's coordinates are
rounded half to even (四舍六入五成双) onto the tile they occupy. `Math.round` sends an exact .5 toward +∞, so an enemy
@@ -615,7 +615,7 @@ official source.
Tests: `test/sim/hit-tile-round.test.js`, `test/sim/detmath.test.js`, the edge landing in
`feedback5-raid-own-board`, the 连星 probe in `op_wang`, and the 麦哲伦 probe in `feedback5-wv-summon-triggers`.
### 30.21 Bots soft-reserve a living teammate's opening bonds
### 30.28 Bots soft-reserve a living teammate's opening bonds
PR #518 by @IceCodeNew, for issue #514. This is not an official rule. It extends the accepted #407 card penalty.
@@ -635,9 +635,9 @@ Tests: the two `#514` cases in `test/match/bot-smarter.test.js`. One proves the
the teammate lives and returns after elimination. The other proves a reserved strategy is still drawn, and drawn more
often once that teammate is eliminated. The existing card test still shows a merge outscoring the −18 penalty.
### 30.22 Golden changes after the funnel, hit-tile and bot-reservation ports
### 30.29 Golden changes after the funnel, hit-tile and bot-reservation ports
All 287 scenarios were recomputed once after §30.17–§30.21 and compared with this candidate before those ports
All 287 scenarios were recomputed once after §30.24–§30.28 and compared with this candidate before those ports
(`HEAD` `7fd0478d`, `git show HEAD:test/golden/*.json`). No scenario was added or removed. 43 digests differ from
that candidate. They are additional to §30.9 and §30.16.
@@ -648,18 +648,18 @@ candidate and are not repeated below: `roster-011`, `roster-012`, `roster-013`,
`coop2-NORMAL-3`, `solo-HARD-9-boosted`, `coop2-ABYSS-10-boosted`, `standin-06`, `standin-07`. The other 24 of
those 45 moved again, and 19 scenarios that still matched 0.2.4 on this candidate now differ.
Opening strategy ids do not change in any of the 20 match digests. A solo match has no teammate, so §30.21 cannot
Opening strategy ids do not change in any of the 20 match digests. A solo match has no teammate, so §30.28 cannot
move one. Co-op seeds keep the same `bandId` and the same bot-draw counts except `coop4-ABYSS-7`. The recorded
match moves are battle totals from §30.17–§30.20, and the later gold and LP those totals change. No isolated
match moves are battle totals from §30.24–§30.27, and the later gold and LP those totals change. No isolated
counterfactual was re-run; the groups below follow who is actually on the board.
| Cause | Changed scenarios |
|---|---|
| Funnel body hit plus redeploy reset, and 洛洛 S2's independent lock (§30.17–§30.19). These boards include 洛洛 | `roster-004`, `roster-005`, `roster-023`, `roster-024`, `bond-victoriaShip-low`, `bond-victoriaShip-high` |
| Funnel body hit plus redeploy reset (§30.17–§30.18). 至简 and/or 耶拉, not 洛洛 | `roster-007`, `roster-009`, `roster-026`, `roster-028`, `bond-deputShip-low`, `bond-emptyShip-low`, `bond-kjeragShip-high`, `bond-maniShip-low`, `bond-miraShip-low`, `bond-sargonShip-high`, `bond-soloShip-low`, `bond-visiShip-low` |
| Funnel body hit plus redeploy reset, and 洛洛 S2's independent lock (§30.24–§30.26). These boards include 洛洛 | `roster-004`, `roster-005`, `roster-023`, `roster-024`, `bond-victoriaShip-low`, `bond-victoriaShip-high` |
| Funnel body hit plus redeploy reset (§30.24–§30.25). 至简 and/or 耶拉, not 洛洛 | `roster-007`, `roster-009`, `roster-026`, `roster-028`, `bond-deputShip-low`, `bond-emptyShip-low`, `bond-kjeragShip-high`, `bond-maniShip-low`, `bond-miraShip-low`, `bond-sargonShip-high`, `bond-soloShip-low`, `bond-visiShip-low` |
| Same body hit and redeploy reset on 荒芜拉普兰德 | `roster-017`, `roster-019`, `roster-036`, `roster-046`, `roster-047`, `boss-boss_3-pair`, `boss-boss_5-pair`, `boss-boss_7-pair`, `hidden-boss_9-pair` |
| 澄闪 DIY: the normal attack is a body hit plus one drone addition (§30.17) | `diy-098`, `diy-099` |
| Hit-tile half-even rounding and the edge inset (§30.20). No funnel operator is deployed; the damage total stays 1388100 and the hook counts and the snapshot sample at index 27 move | `standin-04` |
| 澄闪 DIY: the normal attack is a body hit plus one drone addition (§30.24) | `diy-098`, `diy-099` |
| Hit-tile half-even rounding and the edge inset (§30.27). No funnel operator is deployed; the damage total stays 1388100 and the hook counts and the snapshot sample at index 27 move | `standin-04` |
| Full matches. Opening bands are unchanged. Final lineups include a funnel operator, except `coop2-HARD-4` (both seats eliminated, lineup empty) and `coop3-ABYSS-5` (the surviving lineup has none), whose first divergence is round 7 and round 5; those two are the hit-tile change, or a funnel operator who is not left in the stored lineup | `solo-FUNNY-1`, `solo-FUNNY-2`, `solo-NORMAL-1`, `solo-HARD-1`, `solo-ABYSS-1`, `coop2-HARD-4`, `coop2-NORMAL-1-coverage-standins`, `coop2-NORMAL-5-coverage-diy`, `coop2-NORMAL-8-serverrun`, `coop2-NORMAL-70-diy`, `coop3-ABYSS-5`, `coop4-FUNNY-6`, `coop4-ABYSS-7` |
Result flips inside that match list: `solo-NORMAL-1` defeat → victory (team LP 0 → 2); `solo-FUNNY-1` team LP 15 → 23
@@ -668,13 +668,13 @@ team LP 26 → 27; `coop4-ABYSS-7` eliminated at round 12 → defeat at round 13
The other matches keep the same end reason. `standin-04` is the only battle in this set with no funnel operator on
the board.
### 30.23 Golden changes after the skill-only funnel body correction
### 30.30 Golden changes after the skill-only funnel body correction
All 287 scenarios were recomputed after the §30.17 correction (a skill that only buffs or retargets keeps the body;
耶拉 S2 uses the 洛洛 split) and compared with this candidate after §30.22 (`HEAD` `e0f37718`,
All 287 scenarios were recomputed after the §30.24 correction (a skill that only buffs or retargets keeps the body;
耶拉 S2 uses the 洛洛 split) and compared with this candidate after §30.29 (`HEAD` `e0f37718`,
`git show HEAD:test/golden/*.json`). No scenario was added or removed. `fields`, `standins` and `diy` are unchanged
(澄闪 stays on `dealDamage`). 19 digests differ. They are additional to §30.9, §30.16 and §30.22. Seventeen of them
already moved in §30.22 and move again. `roster-038` and `coop2-NORMAL-14-standins` did not move in §30.22.
(澄闪 stays on `dealDamage`). 19 digests differ. They are additional to §30.9, §30.16 and §30.29. Seventeen of them
already moved in §30.29 and move again. `roster-038` and `coop2-NORMAL-14-standins` did not move in §30.29.
Opening strategy ids do not change in any of the 20 match digests. No isolated counterfactual was re-run. The roster
and bond rows name the skill index the corpus assigns: 耶拉 index 1 is 心随意动, 荒芜拉普兰德 index 0 is 慵怠者悲鸣.
+1 -1
View File
@@ -27,7 +27,7 @@
// * Merge: 3 normal copies (风丸 2) on board/hand/temp → 1 elite; equipment returns to the hand; a
// reward offer of 3 different free chess of tier min(level+1, 6) is queued (never one operator twice — user
// playtest #6 item 19; a short tier tops up from the tier below; the player's stocked 自选 of that tier joins,
// §30.20; pick 1, expires at prep end; an offer earned
// §30.23; pick 1, expires at prep end; an offer earned
// after the prep — SETTLE / Final Assault effects — is kept for the next prep). Where the elite goes (PRTS
// 卫戍协议/帮助 "发送1名【精锐】状态的该干员至手牌区(若消耗已部署至作战区的干员,则发送至作战区对应位置)", user
// playtest #6 follow-up): when a consumed copy stood on the board, onto that copy's tile with its facing (of several,
+1 -1
View File
@@ -218,7 +218,7 @@ export class PlayerAcquire {
* The player's slotted 自选 pieces of the reward tier join the draw (player/diy.js diyStockEntries: copies left, then
* the roll's tier — not the ordinary shop's shopLevel gate). 卫戍协议/帮助 干员晋升 names one temporary refresh one tier
* above the 调度中心 and no separate pool; the owner decided on 2026-10-12 that the refresh includes 自选 of the newly
* reached tier. 0.2.0 had [ASSUMED] the shop-level gate on this refresh too (DESIGN §25); §30.20 reverses that.
* reached tier. 0.2.0 had [ASSUMED] the shop-level gate on this refresh too (DESIGN §25); §30.23 reverses that.
* An offer built from explicit `ids` does not roll.
*/
pushRewardOffer(source = 'merge', { tier = null, ids = null, label = null } = {}) {
+1 -1
View File
@@ -29,7 +29,7 @@
// min(shopLevel + 1, 6): a tier-5 自选 piece can appear when the 调度中心 reaches 4, a tier-6 piece when it reaches
// 5, one shop level before the ordinary shop. 卫戍协议/帮助 干员晋升 names that refresh and no second pool; the owner
// decided on 2026-10-12 that it includes 自选 of the newly reached tier. 0.2.0 had [ASSUMED] the shop-level gate
// for this refresh too (DESIGN §25); §30.20 reverses it. A piece is not guaranteed. Banned slots and `left <= 0`
// for this refresh too (DESIGN §25); §30.23 reverses it. A piece is not guaranteed. Banned slots and `left <= 0`
// stay out. Explicit-id offers do not use this draw.
// * random grants (diyStockEntries, 0.2.0 WE2 #9): an effect, reward or 机变 card that grants this player a random
// operator from the pool draws its stock too — 「自选干员放入后模拟中的补给池随机范围也将被相应扩大」 (bilibili), "调度中心
+1 -1
View File
@@ -16,7 +16,7 @@
// ("copy-weighted"; duplicates within a roll allowed). The item slot picks a tier with the same tier shares, then a
// uniform shop-eligible item of that tier (falling back to lower tiers). A roll may add entries outside the pool
// (`extra`, after its own): one player's 自选 stock — the ordinary shop passes diyRollEntries (the shopLevel gate);
// the promotion reward and random grants pass diyStockEntries (the roll's own tier, DESIGN §30.20). Weighted by its
// the promotion reward and random grants pass diyStockEntries (the roll's own tier, DESIGN §30.23). Weighted by its
// copies like any chess, drawn by that player only.
/**
+1 -1
View File
@@ -20,7 +20,7 @@
// is flagged SILENCE (沉默 disables it: exactly the data's `format: "SILENCE"` lines). 萨卡兹枯朽战士 / 组长's
// 【污染秽蚀】 death fog is the one NORMAL line also silenced (archetypes.js kitPolluted, `enemy_1267_nhpbr` and
// `_2` only): the owner's official-play recall of 2026-10-12 is that a death while silenced creates no fog, and
// that recall contradicts the PRTS / in-game text 「不可沉默」 (DESIGN §30.20). stun / freeze / sleep block
// that recall contradicts the PRTS / in-game text 「不可沉默」 (DESIGN §30.23). stun / freeze / sleep block
// skills. Enemy SP skills ("数次攻击后…"): SP +1 per attack, the (spCost+1)-th attack is the skill attack (official
// 粉碎攻坚手 text: spCost 2 = "攻击2次后,下一次攻击").
// Shared mechanics: reborn() — "首次被击倒后重生 / 第二形态" (the first KO is hidden from kill credit and bounty; a
+1 -1
View File
@@ -72,7 +72,7 @@ test('stats-only enemies attach no ability and fight with their data stats', ()
// 萨卡兹枯朽战士 / 组长's PollutedDie is silenced even though the handbook line is NORMAL and the PRTS / in-game text
// says 「不可沉默」. The owner's official-play recall of 2026-10-12 (GitHub #470) is that a death while silenced
// creates no fog. Only these two keys share that ability (DESIGN §30.20; 0.2.0's client-template reading is §25.18.2).
// creates no fog. Only these two keys share that ability (DESIGN §30.23; 0.2.0's client-template reading is §25.18.2).
const SILENCE_BY_TEMPLATE = new Set(['enemy_1267_nhpbr', 'enemy_1267_nhpbr_2']);
test('沉默: exactly the abilities whose handbook line is SILENCE-flagged can be silenced (every authored enemy), plus 萨卡兹枯朽战士 / 组长\'s death fog', () => {