Commit Graph
367 Commits
Author SHA1 Message Date
Xinglan233 19c7b26850 feedback7 R22-LATE: a 画卷 copy that completes a three-copy merge copies the target's equipment again; golden: unchanged
GitHub #389 / PR #390 by @Xinglan233 (this commit is substantially the PR: the snapshot and its test file, ported).
onArt read target.items after grantChess; a gain that completes a merge runs _mergeChess first, which consumes the
target and empties its items, so the copy loop ran on an empty list (two base 维式重锤 never became the +25% one).
The item ids are now recorded before the gain.

Added on top of the PR: after a promotion the copied items are never equipped onto the elite (an already-advanced
item used to go straight back onto it via equipDirect). The promotion unequips the copies (PRTS 帮助 自动卸除 on
合并) and the 画卷 note says the obtained equipment arrives unequipped, so they wait in the hand; a copied normal item
merges with the returned original as before. The non-promotion path is unchanged.

Tests: test/match/scroll-copy-merge.test.js (8; 4 fail on the parent, the advanced-item case also fails with the
PR's snapshot alone). Golden unchanged (no scenario casts 画卷 into a promotion).
2026-10-08 21:04:58 +08:00
sganggs dc609ea13f feedback7: merge fb7-ui-backlog — #229 device tooltips, #238 settings button in lobby / room, #138 准备 folds the shop, #120 in-match spectator roster (cap stays 2), PR #308 capsule counts (+ the shared-field progress fix), PR #333 empty new shop slot on 调度中心 upgrade
- Conflicts: the stats entry (merged fb7-stats) and the settings button both sit in the lobby / room top bars — both kept;
  public/js/ui/settings.js (#321 diagnostics, voiceLang, SettingsButton); docs/PLAYING.md table rows resolved line by
  line against the merge base (#368, #354, #333 edits kept); docs/SIM.md / design/network.md snapshot field lists
  (resolved + ammo / wolves / neg / stand / standCut); design/client.md Screens line (#368's AI switch kept).
- Grok review: MERGE AFTER FIXES — the shared-field capsule finding fixed on the branch (1a880699).
- Golden: roster 23, bonds 2, fields 11, matches 18, diy 11 — #308 totals / snapshots and #333's shop RNG (union OK);
  broad node --test 5473 (5472 pass, 0 fail, 1 skipped); lint 0 errors; typecheck; i18n strict clean.
2026-10-08 20:56:20 +08:00
sganggs cf98f4c3f8 feedback7: merge fb7-render — #382 赤刃明霄陈 S3 sword-qi drawn (sim chen3Wave fx), #381 enemy attack recovery held in interpolation, #380 push / pull slide (corpse stays where pushed; same-step kills finish the slide), #384 eye masks, 香槟炸弹 HP bar hidden, #246 an unwound attack plays its whole clip
- Conflicts with the merged fb7-hud (both added display-only snapshot lists): server/sim/battle/events.js, types/core.js,
  public/js/render/interp.js, docs/SIM.md, docs/design/network.md — union of ammo / wolves / neg and stand / standCut.
- Grok review: MERGE AFTER FIXES — the HIGH finding (same-step push kill) fixed on the branch (7a33bc7e).
- Golden: diy-073 / diy-074 (fx counts only; union OK); broad node --test 5442 (5441 pass, 0 fail, 1 skipped); lint 0
  errors; typecheck.
2026-10-08 20:51:11 +08:00
xcdoge b4bc89ad4e feedback7 UIBACK: the top-bar capsule counts like the official — resolved = killed + leaked among the enemies the round scheduled (opening 0/3, a leak 1/3, a kill 2/3, the splitter 3/3); a split child, a summon and a boss summon are in neither number but still cost LP and break 完美作战 (PR #308 by @xcdoge, the capsule half of PR #157 — authored by them: the sim / protocol / HUD hunks applied as reviewed): inTotal / killedInTotal / leakedInTotal / resolved, b.snap / BattleResult / b.progress (optional field) / m.public progress carry resolved, killed may exceed total (validation bounds it by the content-spawn allowance); dropped the PR's stray design-doc line — it had replaced the S→C b.end bullet of docs/design/network.md, which is back; the 联防 live-counter change mark follows the enemy list now that a spawn no longer moves total (uniteLeftMark + test); golden: only total / players.*.total / snaps move, outcomes bit-identical — roster 23 (roster-002 003 007 008 009 010 011 012 013 015 017 018 020 023 024 025 026 027 037 045 047 048 049), bonds 2 (bond-maniShip-low, bond-soloShip-high), fields 11 (boss-boss_1 3 5 pair+solo, boss-boss_6-solo, hidden-boss_8 10 pair+solo), diy 11 (diy-036 040 056 062 068 073 083 091 095 114 115), matches 12 (solo-FUNNY-1 NORMAL-1 HARD-1 ABYSS-1 ABYSS-2, coop2-NORMAL-3 coop2-HARD-4 coop3-ABYSS-5 coop4-ABYSS-7 coop2-NORMAL-8-serverrun solo-HARD-9-boosted coop2-NORMAL-70-diy: the total column of 36 round rows), standins unchanged 2026-10-08 19:30:36 +08:00
IceCodeNewandConvey123 8ae891f1f3 feedback7 R22-HUD: the HP bar shows the ammo skill's rounds as yellow cells (隐现 S2: 14), 伺夜's 狼影 left as diamonds and 斩业星熊's 我执 pool as a red bar — one snapshot change for PR #303 and #378 by @IceCodeNew and PR #383 by @Convey123; golden: unchanged
The three PRs patched the same snapshot and HUD lines (Grok's review: do not merge three diffs), so this is one design
built from their code and tests; IceCodeNew is the commit author (#303, #378), Convey123 co-author (#383).

- b.snap gains three optional, display-only lists beside the unchanged 9-field tuples (snapshot.js ammoView / wolfView /
  negView, called from battle/events.js snapshot(); a living, deployed, visible ally, only when it has one):
  ammo [[id, rounds left, magazine]] (whole rounds; the magazine is the activation's real total that unitTuple's SP
  fraction runs on, extras and refills included), wolves [[id, 狼影 left, talent maximum]] (mem.shadows of the new
  mem.wolfCapacity, set by tokens.js wolfPack and the managed vigil kit), neg [[id, fill]] (unit.negFill(), a function
  op-hsgma2.js sets: the pool is read when the snapshot is taken, no per-tick sync). UnitInfo.ammoSkill (an ally whose
  skill is an ammo magazine) is known from the first appearance: fx events run before the frame's sample, so the aura
  cannot wait for the first ammo row.
- render/interp.js keeps the lists per snapshot (malformed rows / unknown ids dropped) and sample() hands them out from the
  older snapshot like flags (they step with the skill flag); render/units.js draws them: the ammo magazine replaces the
  SP bar (a cell per round, thin cuts, exact fill, no cuts under 2 px a cell), a row of diamonds under the bars for the
  wolves (the element gauge row moves below), the red bar over the drained HP bar for the pool. An ammo skill draws no
  standing aura (rings.js _aura; the activation burst stays).
- PR #378's wolf-head avatars are NOT taken: the count is data (the talent text 至多3只, mem.shadows), the HUD art of the
  official counter is in no game data we have, so the pips are plain diamonds [ASSUMED look]. The PRs' own tests are
  folded in and extended (test/sim/hud-readouts.test.js, test/render/hud-readouts.test.js, op_hsgma2.test.js).
- Docs: network.md, SIM.md §9, client.md, PLAYING.md, types/core.js.
- Golden: unchanged (283 scenarios; the canon hashes units / down / elem only, no sim state moved).
- Tests: 4 + 14 new + 1 in op_hsgma2 (12), all fail on the parent; 344 related tests pass; lint 0 errors, typecheck,
  check:imports, docs tests.

Co-authored-by: Convey123 <Convey123@users.noreply.github.com>
2026-10-08 19:22:08 +08:00
ZiyueW1116 8a64edc9e9 feedback7 R22-RENDER: an enemy standing out its attack recovery is drawn standing — the snapshot carries stand / standCut and the interpolator holds the position until the recovery ends (PR #381 by @ZiyueW1116, supersedes #307 / #314); golden: unchanged
Since 0.2.0 the sim stands an unblocked enemy for the rest of its attack clip (ai.js attackStand → atkStandUntil),
but render/interp.js lerped x/y over the whole snapshot gap, so the view slid through a recovery the sim held
(repro: a real 隐形弩手, snapshots 4.9 / 5.0, stand until 4.934 — sampled at 4.917 it slid at vx −0.2).

The snapshot now carries, only when non-empty, `stand: [[id, until]]` (atkStandUntil of enemies alive, deployed,
visible, neither feared nor stunned) and `standCut: [[id, at]]` (the latest time each listed enemy's recovery was cut
or ignored: a displacement, fear, a stun, hiding, leaving — Battle._cutAttackStand, display metadata the battle never
reads). sample() holds the older position until `until` and interpolates the rest (HP / SP keep the whole interval),
stays linear when the newer snapshot records a cut inside the interval, and extrapolates nothing for a newest snapshot
that shows a stand, a death, a stun or a block. Teleports and redeploys still snap first; old snapshots without the
fields interpolate as before.

Substantially @ZiyueW1116's code (PR #381), authored as theirs. Changed on review: the docs (SIM §9, design/network.md)
and code comments in English like the rest of them; the snapshot builds its listed-id set only when an enemy has a cut
to report.

Golden: unchanged — the digest canon hashes neither field and the sim's timing does not move (all 283 scenarios match).

Tests: test/render/attack-recovery-interp.test.js (new, 25: metadata validation, hold-then-slide, cuts, legacy
snapshots, extrapolation guards, real 隐形弩手 / Weedy push-kill / stun / freeze / sleep / levitate / block / fear
battles) 25/25; render/interp 16/16; sim battle, perf, robustness, downelem 69/69.
2026-10-08 18:54:54 +08:00
Convey123 ffa538c39d feedback7 R22-RENDER: 赤刃明霄陈 S3's sword wave is drawn along its path — the sim sends its position as a chen3Wave fx every 0.12 s, the client draws a 'qi' blade (PR #382 by @Convey123, owner item 12); golden: diy-073 / diy-074 events.fx and fx.chen3Wave only
The 赤霄·天喟 wave is a kit-managed probe (it turns corners and lives as long as the skill), not a snapshot
projectile, and the sim emitted one `dash` at the cast and a `slash` per hit — nothing along the way, so the client
drew no wave. op-chen3.js now emits fx('chen3Wave', { x, y, fromX, fromY, dr, dc, id }) every WAVE_FX_EVERY (0.12 s;
4 ticks), the trail restarting at a corner; render/fx registers chen3Wave → 'qi' (pt: drawn at the event, never on
her) and draws a streak plus a crescent head turned the way it travels. The look is a procedural stand-in, not the
official particle prefab.

Substantially @Convey123's code (PR #382), authored as theirs. Changed on review: the head is projected after
streak() — streak() reuses the effect system's projection scratch, so the PR drew the crescent on the trail's start,
one event behind the wave — and the trail, head and heading share one height; an unused test variable dropped.

Golden: diy-073 (5_diy*=chen3 S3 in two slots) events.fx 508 → 1558, fx.chen3Wave → 1050; diy-074 (6_diy*=chen3 S3)
events.fx 272 → 872, fx.chen3Wave → 600. HP, kills, damage, hooks and snapshot hashes unchanged: battle.fx only
records an event.

Tests: test/content/op_chen3.test.js (+1: the events, their cadence, id, direction, trail start, silence after the
skill) 12/12; test/render/fxchen3wave.test.js (new, 6: the archetype, drawn at the wave not at her, the head on the
wave and turned with it, a sweep joining into one trail, junk input, nothing left after) 6/6; boardart 15/15.
2026-10-08 18:48:53 +08:00
Cloudnyco ae22335cfe feedback7: the battle sim uses engine-independent math — Chrome, Firefox, Safari and the server agree bit for bit (PR #373 by @Cloudnyco)
- server/sim/detmath.js: hypot (sqrt of the squares, rescaled outside 2^±500), powi (integer powers in double-double,
  one rounding), sin / cos (fdlibm 5.3) and atan2 (fdlibm / FreeBSD msun) built only from correctly rounded IEEE
  operations; the sim's Math.hypot / sin / cos / atan2 / pow calls go through it (65 files); eslint.config.js forbids
  the approximated Math functions under server/sim and test/sim/detmath.test.js scans for them.
- sin / cos / atan2 are the algorithms V8 runs in Node, so the server's results stay; only hypot differs from V8's.
  Golden: 2 moved — diy-027 (a hypot distance, damage +80) and coop3-ABYSS-5 (a later card pick from round 9, same end).
- Applied unchanged after review (Grok static review: MERGE; the diff read in full: no network, no new dependency).
- Tests: broad node --test 5155 / 5155 with the new file tracked (detmath 7 / 7, package 10 / 10); lint 0 errors,
  typecheck, check:imports.
2026-10-08 18:35:55 +08:00
sganggs b05845f507 feedback6: merge R21P — every operator at full potential (潜能 6; GitHub #252, PR #255 by @SpiritedAwayCN, the owner's decision of 2026-10-07)
- tools/build-data.mjs applies every potentialRanks attribute step (COST, RESPAWN_TIME, ATK, MAX_HP, DEF,
  MAGIC_RESISTANCE, ATTACK_SPEED) to the chess, elites, 补位 and 自选 units and picks talent / trait / module-talent
  candidates up to requiredPotentialRank 5; summons take the owner's potential for their talents, not its stat steps.
  data/chess.json, backups.json, tokens.json and the en / ja / ko / zh-TW data translations rebuilt; op-wang.js reads
  her stock cap (8 at full potential). 刺玫 435 ATK / cost 15, 砾 16 s, 至简 70 s.
- No conflicts outside the golden files (regenerated). Golden vs HEAD: roster 49, bonds 46, fields 22, matches 18,
  diy 133 (standins and diy-012 / diy-135…138 unchanged: no potential ranks or never hit). Union check against the
  branch and the merge base: every scenario only the branch moved equals the branch, except roster-048 and
  solo-ABYSS-2: at full potential a 频次 器物 is reached there (roster-048: one more enemy dies instead of leaking, 86 → 87
  units), so R21H's hit count (data × hpMul ÷ supplyHpMul) applies where it did not before — with only that rule put back
  (archetypes.js times as at the merge base) both equal the branch exactly.
- Tests: broad node --test 5147 / 5147; lint 0 errors.
2026-10-07 18:48:38 +08:00
sganggs 806a047717 feedback6 R21P: every operator fights at full potential (潜能 6) — the owner's decision of 2026-10-07 (GitHub #252, PR #255; no host slider): tools/build-data.mjs OPERATOR_POTENTIAL adds every character_table potentialRanks attribute step (部署费用 / 再部署时间 / ATK / HP / DEF / RES / ASPD, all ADDITION, before rounding) to every chess (normal and elite), 补位 and 自选 unit form and picks talent / trait / module-talent candidates up to requiredPotentialRank 5 (「天赋效果增强」); a summon picks its talent candidates at its owner's potential (their requiredPotentialRank mirrors the owner's — PRTS 凯尔希: Mon3tr 3.5 s / 1400) and takes none of the owner's attribute steps; the 原型干员 stand-ins have no potential ranks (unchanged). 刺玫 413 / 17 → 435 / 15 as in the tournament video, 砾 18 → 16 s, 至简 80 → 70 s. data/chess.json (256 records), backups.json (the 71 owned picks, 8 summons), tokens.json (5 summons) and the data translations en / ja / ko / zh-TW rebuilt — only potential-driven fields (JSON-compared); the 干员调配 局内数值 and detail cards read the records. op-wang.js reads her stock cap 「最多拥有8(+1)枚」 through the potential step (the pattern fell back to 7: she sat at the cap from the start). Docs: DATA §2 / §18 / tokens, PLAYING (detail card), research 03, kits README, shared/diy.js / standIn.js, the 71 自选 kit headers and the kit comments that quoted potential-0 numbers. Tests: test/full-potential.test.js (new, fails on the parent); data.test.js re-derivation adds the potential steps (+ respawnTime); every test that hard-coded a potential-0 number carries the full-potential one (from the data and the test's own formula; no check loosened); golden: moves almost everywhere — roster 49/49, bonds 46/46, fields 22/22, matches 18/18, diy 133/138 (each battle parts on a stat: roster-001 / roster-020 at tick 1 on 角峰's HP (生命上限+250), bond-arcaneShip-high at 4.73 s and diy-001 at 3.70 s on an enemy's HP from a higher ATK; diy-110 / 111 also by 望's cap; the matches through those battles); unchanged: standins 10/10 and diy-135…138 (no potential ranks), diy-012 (twelve 夜莺 never hit, never redeployed) 2026-10-07 18:35:39 +08:00
sganggs a9fe794c3f feedback6: merge R21H — 器物 (频次) enemies take the 攻坚 HP share and not 补给线's (the data's exclusion list names exactly the 14 器物), leader summons take the round's enemy scaling (PR #272 by @CXUtk, re-implemented from the data); tools/golden.mjs keeps R21H's roundMods import and drops uniteStageId (removed by R21B); golden regenerated on the merge — vs the parent exactly R21H's 74 scenarios, vs the branch only the other streams' moves 2026-10-07 18:21:01 +08:00
sganggs 3f918c9f03 feedback6: merge fb6-small-fixes (see its commits) 2026-10-07 18:16:10 +08:00
sganggs e33ee3db8f feedback6 R21H: the round's enemy effects reach the 频次 器物 and the leaders' mid-fight summons (PR #272, 感谢 @CXUtk); golden: 74 moved
器物 (the 14 hit-count keys): hits = data × the spawn's hpMul ÷ supplyHpMul, rounded as before (setHits) — 攻坚装备 / II / III
leave out only 炎佑, 补给线 / 补给线II also exactly these 14 keys (activity_table aceffect_enemy_2 / 2_2 enemy_exclude,
data/effects.json); until now setHits(def.maxHp) overwrote the round's HP (青铜镜 30 hits at every difficulty). build-data
writes enemyScale[r].supplyHp = 1.2^(kHp − kAtk) · extra (the HP-only 补给线II steps and 补给线's 1.08; co-op 终极 R5–R15
only — the rebuild changed config.json alone), gamedata returns it as supplyHpMul and the wave / 悬赏 mods carry it
(waves.js roundMods; a 频次 enemy's death spawn inherits it). Not taken from the PR: its 1.08 / 1.2 back-calculation (it
counted the 补给线II steps as 攻坚装备) and its fractional-HP ceiling. Leader summons (死亡集群's 妖怪, 刺胄之弹,
“裂管之音”/“断弦之音”, 不祥幻影): the boss / hidden field carries the round's scale as flags.enemyScale (bossRounds.js,
golden fields, tools/balance.mjs) and bosses.js summonMods gives them HP / ATK / speed (死亡集群's summon.hp_ratio on
top; 刺胄之弹 / 余音 hit counts follow their HP); the leader's pool stays exempt; 王权号令's invulnerable equipment
unchanged; 炎佑 is an ally token, never scaled (no change). Unchanged and open: the 逐火 / 再生 husk counts (talent
prop_max_hp).

Golden — 器物 counts: roster 37 (002 003 004 005 007–020 022 023 025 026 029–034 036–041 043 045 049: each holds a 器物
extra spawn / 频次 wave / death spawn), bond-soloShip-high, diy 9 (036 040 056 062 068 073 091 114 115), boss-boss_6-solo
(俗心's 小说卷轴 escorts); matches 16 (all but solo-ABYSS-2 and coop2-NORMAL-70-diy: 频次 rounds / 悬赏 and the Final
Assault summons). Summons: boss-boss_1-pair/solo, hidden-boss_8-pair/solo (妖怪, 刺胄之弹), boss-boss_3-pair/solo,
hidden-boss_10-pair/solo (余音), boss-boss_5-pair/solo (不祥幻影). standins unchanged.
2026-10-07 18:05:42 +08:00
sganggs ce2bd75b49 feedback6 R21E: a refresh runs the 刷新时 特质 of the chess that stood on the board / in the hand when it happened (EffectDispatcher.dispatch takes them before its first handler; each still runs where it stands now, one that left is skipped): the 拉普兰德 贾维 grants on every 6th refresh — or the elite that gift completes — fired in the very refresh that granted her and spent her 「本回合首次主动刷新」; now her first is the next manual refresh; round counters are still not copied on a merge (a merged elite is a new 拉普兰德, §25.13.3); the part of PR #196 0.2.0 lacked, re-implemented; golden: unchanged 2026-10-07 18:02:48 +08:00
sganggs c225559d4d feedback6 R21E: an operator's 凋亡 burst drains the official 技力 — stored charges and the ready charge included (Skill.setSpTotal(spTotal − 1) each second; PRTS 技能 可充能 「当持有者的技力流失时,充能次数也会实时降低」, PRTS 元素 「每秒损失1点技力」): the drain took only the SP towards the next charge, so a full skill kept every charge and a one-charge skill stayed ready through the 15 s; a running timed skill is left alone as before; PR #262 (#261 its closed duplicate), re-implemented; golden: 5 moved, each by a burst on an operator with SP stored (假想敌:管's 凋亡 strikes, the 萨卡兹王庭军's 凋亡 on hit) — fields hidden-boss_10-solo (泥岩 loses its stored charge: casts 1 → 0, the move PR #262 reported; the team's heals and the snapshots after it), boss-boss_3-solo / hidden-boss_10-pair and diy-058 (later snapshots and event counts only, the same results), diy-059 (黍 forms against the 萨卡兹王庭军 waves: fewer casts — 11 → 5, 6 → 2, 9 → 5, 6 → 1 — the battle goes otherwise, kills 39 → 47, leaks 57 → 49) 2026-10-07 17:58:45 +08:00
sganggs c623550f29 feedback6 R21E: the 外勤医疗 Touch casts 恳切福音 on an injured ally inside its 5-2 (ACTIVE_RANGE in touchKit — the larger-range rule the Touch 补位 already runs by its data; the map character's record keeps DEFAULT), and the Touch / 预备干员-医疗 card is an operator card (干员 · 医疗 · 远程位, 特性, skill row with SP / duration, talents from the tokens.json record — it took the summon path: 召唤物, base stats only); 恳切福音 gets a line under its text that the boost is strictly below half (PRTS 修正 of 不高于, what touchGospel does; the operator card of the 补位 Touch too: SKILL_TEXT_NOTES); GitHub #260, PR #278; golden: roster-041 (its strategy Touch heals 8438 → 17072, 19 → 27 heal actions, casts unchanged at 2, the same numbers as PR #278; p1 deaths 7 → 4) and matches coop2-NORMAL-14-standins (h_0 plays 外勤医疗: defeat in round 13 → victory, teamLp 16) — both battles with that strategy's Touch, no other scenario moved 2026-10-07 17:54:17 +08:00
sganggs 26c72a6d95 feedback6: merge R21B — 联防 plays on the round's battlefield again, its terrain, crates, water, devices and runes as in 0.1.4 (the owner's report 「联防阶段地形全消失了」 and knowledge of the official mode, GitHub #244's tournament video; 0.2.0's escaped level was the placeholder road every wave-template level carries); the 联防 battle input is byte-identical to 0.1.4's in 20 cases; 乌尔比安's comment keeps both streams' sentences; golden as R21B's commit (unite-1 / unite-2 back to their stages, coop2-NORMAL-3, coop2-HARD-4, coop3-ABYSS-5, coop4-ABYSS-7, coop2-NORMAL-8-serverrun, coop2-NORMAL-14-standins), the merged tree differs from the branch only in R21A's boss pair fields 2026-10-07 17:54:16 +08:00
sganggs 75202776cc feedback6 R21B: 联防 plays on the round's battlefield again — its terrain, crates, water, devices and runes, as in 0.1.4 (the owner's decision of 2026-10-07, 「官服保留地形,改回去」; GitHub #244). 0.2.0's escaped-level map (8a436249, §25.6.4) is withdrawn: that map is the placeholder grid all 39 wave template levels carry, tile for tile; only the 11 stage levels have terrain. match/unitePhase.js _uniteOpts fields this.stageId in both combat modes, unite.js uniteStageId is removed, the client draws the 联防 on the board's stage again (screens/game.js: 0.1.4's ownStage / baseStage, no map switch, nothing to restore on leaving), the dev mock likewise. Kept from 0.2.0: own-board 突袭 / 乌尔比安 S3 landings (onOwnBoard, raidTile untouched), the bounty payee, the 联防 BGM, the SETTLE result box. data/stages.json keeps the two kind 'unite' records (no field uses them; engine tests use them as a plain two-halves road); tools/build-data.mjs comments only, an offline rebuild reproduces data/ byte for byte. The 联防 battle input is byte-identical to v0.1.4's in 20 cases (5 stages × 1 / 2 helpers × both combat modes); GitHub #41 item 3 (野鬃 pushing walkers back across the gate onto the other half) is back with v0.1.4's numbers, none off the map. Tests: test/match/feedback5-unite-map.test.js rewritten (6, all fail on the parent), test/e2e/coop.e2e.mjs checks the 联防 field's drawn stage; docs: DATA §12, META §4, PLAYING §5, design/geometry-time, I18N, the §25.6.4 pointer; golden: fields unite-1 (escaped_single → act1autochess_m02) and unite-2 (escaped_multi → act1autochess_m07), the stages of 0.1.4, and the co-op matches whose 联防 rounds come out differently on the round's map — coop2-NORMAL-3, coop2-HARD-4, coop3-ABYSS-5, coop4-ABYSS-7, coop2-NORMAL-8-serverrun, coop2-NORMAL-14-standins (now a victory) 2026-10-07 17:40:03 +08:00
sganggs cfd3c67281 feedback6 R21A: a 突袭 member may land on a teammate's half when both halves of the field are taken — the two-helper 联防 field and the Final Assault / Hidden Core pair field (the owner's decision of 2026-10-07): Battle.onFieldBoard (onOwnBoard of any player of the battle) read by raidTile only; a lone 联防 helper's empty half, a solo boss field's other half and the hand / 临时整备区 rows stay closed, every other landing rule kept, 乌尔比安's S3 【移动】 keeps onOwnBoard; golden: 8 moved, each parting from the parent at a member's first landing on its teammate's half (checked tick by tick with the parent instrumented) — fields boss-boss_2 / 3 / 4 / 5 / 6-pair and hidden-boss_8 / 10-pair (the right player's 缄默德克萨斯 / 伊内丝 / 仇白 / 耀骑士临光 on the left player's half, 1–7 landings per battle, the first 0.3–39.8 s in), matches coop4-ABYSS-7 (round 6's two-helper 联防: ai_2's 斯卡蒂 on ai_1's half at 52 s; only ai_1 / ai_2 dmgDealt move, 8263 between them); unite-2 unchanged (its two landings stay on their own half)
Tests: test/sim/feedback5-raid-own-board.test.js — the pair field (the right player's member onto the left telin's board tile (2,3), the left player's onto the mirrored right (2,17), the hand rows closed) and the two-helper 联防 (each helper onto the other's half; 乌尔比安 beside a teammate stays on his own) fail on the parent; the solo boss field's hand rows and the lone helper unchanged.
Docs: docs/history/0.2.1.md (new, §26; §26.1 cites the owner's decision and PRTS 卫戍协议/帮助 §联防阶段), the DESIGN index row and versions line, a pointer from §25.18.1, docs/SIM.md (onFieldBoard; onOwnBoard now 乌尔比安's only).
2026-10-07 17:09:39 +08:00
sganggs 11fd65a5a5 feedback5: merge R19E — every enemy finishes its attack clip after a strike before it moves on (PRTS 状态机: ATTACK → MOVE after the attack ends; the 鸭爵 swap's 流泪小子 no longer walks off on its strike tick, community report and GitHub #214), and the 鸭爵 strategy's swapped-in 流泪小子 hides again 1 s after a block ends instead of 0 s (the owner's decision of 2026-10-07, a deliberate deviation for that copy only); golden as R19E's commits (216 scenarios + solo-HARD-2), the merged tree differs from the branch only in R19G's three 蕾缪安 scenarios 2026-10-07 13:07:21 +08:00
sganggs dd66adfbd1 feedback5 R19E: the 鸭爵 strategy's swapped-in 流泪小子 hides again 1 s after a block ends instead of the official 0 s — a deliberate deviation, the owner's decision of 2026-10-07 (「要不等待个1秒这样再重新隐匿」); a separate commit the integrator can drop; golden: 1 scenario moves (matches solo-HARD-2)
content/enemies/archetypes.js stealth: an enemy spawned with the band's swap tag 'duck' (content/bands/meta.js
duckReplace) gets its 隐匿 back no sooner than DUCK_STEALTH_RESTORE (1 s, content/enemies/helpers.js) after a block ends
— in practice 流泪小子 (enemy_2034_sythef_2), the only one of the four swaps with 隐匿, officially 0 s (PRTS 流泪小子
「隐匿(解除阻挡0秒后恢复)」). The same enemy anywhere else keeps 0 s: the bounty card's 流泪小子 (enemy_2034_sythef), an
untagged spawn; a 3 s 隐匿 stays 3 s; a copy leaked into 联防 keeps its tag and the 1 s. After each strike (its stunned
blocker lets go) it is now revealed through its 0.8 s post-strike stand and 0.2 s of walking.

Measured, 8 seeds each — leaked / HP left / revealed s per battle; W = 3 elite melee in a lane + an elite sniper vs the
R6 wave's ground enemies with one swapped 流泪小子, B = 8 elites on 战场#01 vs the whole R6 wave with one swap: before
the clip fix W 5/8, 42 %, 2.3 / B 8/8, 47 %, 3.2; after it W 5/8, 31 %, 2.6 / B 8/8, 58 %, 2.5; with the 1 s W 4/8,
31 %, 4.0 / B 8/8, 56 %, 5.5. Options for the owner (measured on the fixed engine, not built): 2 s W 4/8, 31 %, 5.4 /
B 8/8, 46 %, 8.5; 3 s (the general 隐匿 rule) W 4/8, 31 %, 6.4 / B 8/8, 39 %, 11.5; a 1.5 s stun on the copy (below its
2 s interval, so its blocker takes it over again) W 4/8, 2 %, 4.0 / B 4/8, 6 %, 5.5; a 1 s stun: knocked out in all 16;
the 1 s delay + a 2 s stun W 4/8, 21 %, 5.1 / B 5/8, 26 %, 8.1. Worse: half speed while 隐匿; a stunned operator that
keeps blocking it (pins that operator for good).

Golden: matches solo-HARD-2 — its bot holds 鸭爵; the swapped 流泪小子 of round 13 is free and revealed for 49 ticks in
its 1 s windows (the round-12 one is never released by a block), so the match parts at round 13 (a victory instead of
a defeat); the other 282 scenarios unchanged.

Tests: test/content/feedback5-duck-restealth.test.js (3; the swap's 1 s and the band path fail on the parent, the 0 s
guard passes on both); enemies_bosses, feedback2-surtr-stealth, feedback1-ducklord, feedback5-attack-clip-rest pass.
Docs: CHANGELOG 0.2.0 有意与官方不同的调整 (and the 核实后不是问题 line points to it), docs/history/0.2.0.md §25.22.6,
docs/PLAYING.md, docs/SIM.md, design/engine.md.
2026-10-07 12:58:06 +08:00
sganggs ef25c03525 feedback5 R19E: an enemy finishes its attack clip after its block ends — the 鸭爵 swap's 流泪小子 no longer walks on the tick its strike stuns its blocker (community report of 2026-10-07 「哭狗瞬间隐匿没有后摇」, GitHub #214 by @FrogThai); golden: 216 scenarios move
ai.js enemyAttack set the post-strike stand only for an unblocked ranged enemy (`!e.blockedBy && radius > 0`), so a
melee enemy released by its own strike walked on that very tick. 流泪小子 (enemy_2034_sythef_2, the strategy's version;
「泪眼汪汪」 / 「哭狗」 in the reports) stuns its blocker with every hit, the stunned blocker lets it go and its 隐匿 is
back 0 s later: on 0255afd it walked off the tick of each strike (four non-attacking walls in a lane: 8 stuns, 19.8 s
隐匿 / 9.0 s revealed, leaked at 28.9 s). PRTS 状态机: an enemy's ATTACK state 「每帧检查异常状态…攻击结束后回退到MOVE状态」
and COMBAT 「逻辑同ATTACK」 — only a character's COMBAT 「检测到不存在阻挡对象时强行切回IDLE状态」 — so an enemy finishes its
attack when its blocker goes. Now every enemy stands for the rest of its clip after a strike (attackStand; a blocked one
never walks, so it shows only when the block ends meanwhile: its blocker stunned or knocked out by that strike, or
gone); a stun / freeze / sleep / 浮空, leaving the field and, new, a displacement (失衡, Battle.displace) end the stand.
流泪小子 now stands 0.8 s (its 1.567 s clip, strike at 0.767), 隐匿, and a blocker whose stun ended often takes it over
again: the same lane 13 stuns, 29.1 s 隐匿 / 12.8 s revealed, leaked at 42.0 s.

Checked and official, unchanged: a stunned operator blocks nothing (gamedata_const ba.stun 「无法移动、阻挡、攻击及使用技能」,
PRTS 异常效果 STUNNED 「无法攻击、释放技能、阻挡敌人类单位」 — the keeps-blocking hypothesis is wrong); 隐匿 back 0 s after a
block (PRTS 流泪小子); moveSpeed 0.8 × the level's moveMultiplier 0.5, interval 2.0 s, stun 3.5 s, MELEE (enemy_database;
PRTS 盟约记录 鸭爵 备注: 4500 HP, 3.5 s stun, 隐匿 kept); the cooldown runs on the walk, so a new blocker sees the swing at
once and the strike after the 0.767 s wind-up; a bot teammate's 鸭爵 swaps into a human's battles, the Final Assault and
the Hidden Core too (「你和队友遭遇的部分敌人」), on the replaced enemy's route.

Golden — traced in lockstep against a copy of the parent: in each of the 199 battle scenarios the first differing tick is
an enemy standing out its clip after a strike where the parent walked on; every moved match has such stands in an
earlier or the same round. roster 41 of 49 (all but -003, -005, -009, -018, -019, -025, -035, -049); bonds 21
(deputShip-low, emptyShip-low / -high, indomShip-low / -high, investShip-low, kazimierzShip-low / -high,
kjeragShip-high, lateranoShip-high, miraShip-high, raidShip-low, sargonShip-high, siracusaShip-low, soloShip-low /
-high, suntShip-low / -high, swiftShip-high, visiShip-low, yanShip-low); fields 13 (all but boss-boss_1-solo,
boss-boss_2-pair / -solo, boss-boss_6-solo, boss-boss_7-pair / -solo, hidden-boss_8-solo, hidden-boss_10-solo,
unite-1); matches 17 (all but solo-HARD-9-boosted); standins 10 of 10; diy 114 of 138 (all but -011, -012, -018, -020,
-025, -027, -029, -031, -033, -047, -053, -077, -080 … -082, -086 … -088, -091 … -093, -098, -108, -123). The
displacement rule alone moves one roster scenario.

Tests: test/sim/feedback5-attack-clip-rest.test.js (5; the four behaviour tests fail on the parent, the data pin passes
on both); test/sim (745), test/content + feedback1-ducklord (2030), test/match (593) pass. Docs: CHANGELOG 0.2.0 规则
(按官方) and 核实后不是问题, docs/history/0.2.0.md §25.22.6, docs/SIM.md, design/engine.md, DATA.md.
2026-10-07 12:56:12 +08:00
sganggs d014b9ff0b feedback5: merge R19D — 5-阿戈尔 revives: the members the battle-start devour knocks out revive by board position once every devour pass is over (community report; replaces §24.3's knock-out order for that batch; scan 「左下到右上」 = columns from the left, bottom first [ASSUMED]); bond HP before the devour and one 5000 物理 (DEF) per mark confirmed official; golden unchanged 2026-10-07 12:46:03 +08:00
sganggs 2b0dfceabd feedback5 R19D: 5-阿戈尔 revives — the members the battle-start devour knocks out revive once every devour pass is over, by board position (columns from the left, bottom first: the [ASSUMED] reading of the community report's 「左下到右上」), not in knock-out order; later knock-outs take the slots left in time order, uneaten members none (community report relayed 2026-10-07); golden: unchanged
The report's steps 1-2 were verified and hold: the bond HP is on every member before the devour (an elite 深巡,
2904 HP / DEF 655, stands its 4345 from 15 layers on), and each mark is one 5000 物理流失 less DEF (PRTS), so a member
in the middle of a chain is marked by every 阿戈尔 behind it — that is what knocked out the reporter's 蓝蒂 / 小鲨.
Golden unchanged: the corpus's only 5-阿戈尔 battle (bond-egirShip-high, 999 layers) has no devour knock-out.
DESIGN §25.22.5.
2026-10-07 12:32:33 +08:00
sganggs b87848a443 feedback5 R19G: 蕾缪安's S3 no longer ends by itself when nothing is in her range — it keeps its bullets and locks and locks the next enemy that comes; the bombardment follows only when the bullets are spent (community report); golden: 3 scenarios move
Seen (community report 「蕾缪安3技能范围里没人好像会自动结束」, relayed by the owner): with S3 locking, the locked enemy
killed or walking out of her range and nobody else in it, the skill ended at the next lock tick — the shells fell at
once and the bullets left were thrown away (repro on 0255afd: 3 of 5 bullets lost; a walker leaving her range, 1 lost).
Cause: chess_char_6_01-lemuen.js:169 `if (!e) { if (m.lemLocks.length) skill.end('ammo'); return; }`, there since the
initial import with no decision behind it.
Official: 「攻击装有5发弹药,打完后结束(可随时停止技能)」 — an ammo skill ends when its bullets are spent or the player
stops it; PRTS 卫戍协议/帮助 技能操作 「通常不会自动关闭技能」 (only 玛露希尔's 召唤使魔 is closed automatically); the client
(charpack char_4193_lemuen, buff_template_data lemuen_s_3): the S3 lock is an attack that needs a target and the skill
buff switches to the bombardment mode on ON_BUFF_FINISH only.
Now: with nothing to lock the skill waits (bullets and locks kept, the marks following their enemies or staying where
they left), its lock ready, so the next enemy in range (or 通缉) is locked on the next tick; it ends when the bullets are
spent and the shells fall on every mark in lock order as before. The S3 'lock' fx carry `hold`: render/fx/locks.js keeps
those reticles while the shooter's skill bit (UF.SKILL) is on and starts their LOCK_T at the skill's end (they faded 5 s
into a wait otherwise); S2's aim lock keeps its timeout.

Golden — traced on both trees (SkillRuntime start / end, the round's fields, the carried SP); in each the first
divergence is an S3 the parent ended with bullets left and nothing in her range:
- roster-018: the elite 蕾缪安's S3 of 7.63 s ended at 9.63 s with 2 of 6 bullets left; now the 6th goes at 12.00 s
  (first differing snapshot window 0–10 s).
- boss-boss_3-pair: her S3 of 27.8 s ended at 30.3 s with 4 of 9 left; now all 9 by 34.43 s (window 30–40 s); the boss
  now falls at 199.53 s instead of the 200 s cap.
- coop2-NORMAL-14-standins: ai_0's 蕾缪安 in round 11 ended S3 at 17.2 s (6 of 8 left) and 77.97 s (7 of 9); now she
  spends them, enters the 联防 with 25.96 SP instead of 10.27, casts S3 there and kills one more of h_0's leaked enemies:
  h_0 loses 1 LP less (rounds 11–12 LP 18 → 19, 8 → 9; lpLost 30 → 29; ai_0 kills +1).
bonds, standins, diy unchanged.

Tests: test/sim/feedback5-lemuen-s3-wait.test.js (3; the killed target and the walker who leaves fail on the parent),
test/render/fxproj.test.js +1 (a held lock waits while the skill bit is on; fails on the parent renderer).
Docs: CHANGELOG 0.2.0 规则(按官方), docs/history/0.2.0.md §25.22.8 (also notes, unchanged: S2 spends a bullet on every
normal attack where PRTS says only the 通缉 snipe does — left to the owner).
2026-10-07 12:19:55 +08:00
sganggs 9123e76509 feedback5 R19A: a stunned or frozen enemy is blocked by contact where it stands — an operator redeployed beside a frozen 隐匿 enemy blocks it and so reveals it (GitHub #232, @ccyl; the repro and the cause by @kukiC); golden: 52 scenarios move
ai.js updateEnemy returned on `stunned && !e.hidden` before the contact check (Battle._checkBlock), and 冻结 / 沉睡 / 浮空
set `stun` too, so a held enemy was never checked: an operator redeployed or deployed beside it, a slot freeing up or a
push / pull into contact with a stun all waited for the status to end (0.1.4 had it too). PRTS 异常效果: STUNNED / FROZEN
stop the enemy's moves and attacks and hold no 不可阻挡 (BLOCK_FREE), which SLEEPING / LEVITATE do; 术语释义 冻结 names no
block; 作战机制 §碰撞体积与位置识别: an operator deployed onto an enemy blocks it, a standing one included. The held branch now
runs the same check before it returns (no move, no attack, as before): _checkBlock still refuses 沉睡 / 浮空 / 恐惧 /
不可阻挡, an enemy held short of contact is blocked only once it walks in (the same point as without the status), and the
3 s 隐匿 window after a block's end is unchanged. A block the held enemy already holds is still not re-checked (a reborn()
重生 keeps its blocker, as in 0.1.4: noted as open in §25.22.1).

Golden — in each scenario the first divergence is a stunned or frozen enemy blocked during its status by an operator or
summon it touched with a free slot (traced one by one with an instrumented copy): roster-003, -014, -015, -016, -017,
-018, -019, -031, -036, -038, -040, -041, -045, -046, -047; bond-indomShip-high, bond-kazimierzShip-high,
bond-raidShip-low, bond-siracusaShip-low, bond-suntShip-low; boss-boss_3-solo, boss-boss_4-pair, boss-boss_7-solo,
hidden-boss_8-pair, hidden-boss_9-pair, hidden-boss_10-pair, unite-2; matches solo-FUNNY-1, solo-NORMAL-2, solo-HARD-2,
solo-ABYSS-1, coop2-NORMAL-3, coop2-HARD-4, coop3-ABYSS-5, coop2-NORMAL-8-serverrun, coop2-NORMAL-70-diy; diy-003, -004,
-026, -034, -035, -056, -057, -065, -066, -070, -071, -094, -095, -101, -102, -103. standins unchanged.

Tests: test/sim/feedback5-frozen-reblock.test.js (9; the four #232 cases and the 晕眩 / 冻结 capacity cases fail on the
parent). Docs: CHANGELOG 0.2.0 规则(按官方), docs/history/0.2.0.md §25.22.1, docs/SIM.md (§1.2 Blocking, stun, freeze),
docs/design/engine.md, docs/PLAYING.md.
2026-10-07 11:22:27 +08:00
sganggs 9738bb829a feedback5: 乌尔比安 knocked out while his S3 has moved him lies and redeploys on his deployment tile, not on the anchor tile — the owner's decision of 2026-10-07 on community report 28 「乌尔比安3技能期间死亡会留在3技能位移后的位置复活,应回到初始部署位复活」, a deliberate deviation from PRTS's "where it fell" for this 【移动】 only; golden: unchanged (the corpus moves him 23 times and knocks him out 6 times, never while moved)
- server/sim/units.js `downAtHome` (false), cleared by every deployment (battle/deploy.js _deploy).
- kits/ops/chess_char_5_05-ulpia.js sets it once the S3 【移动】 has put him on the anchor tile; onEnd clears it when the
  skill ends with him standing (the 【返回】); knocked out, it stays for the body.
- sim/battle/tiles.js _layBody: a unit holding it lies on its home tile (his board placement, where the 从不混淆的方向
  stood) when that tile is in the rect and free — else where it fell [ASSUMED], the PRTS exception's one attempt; the
  timed redeploy, 不屈's and CB1's 复活 (M3茧甲 / 埃芒加德: at once, free) all come back there (restTile), b.snap
  `down` names it. Every other moved operator (a 突袭 jump, other kits' 【移动】) keeps "where it fell".
- Test: test/sim/feedback5-ulpia-revive-home.test.js (3) — knocked out during S3 he lies at home, the anchor tile free,
  and redeploys there; revived at home by M3茧甲; control: after the 【返回】 and for a 突袭 member the PRTS rule holds. The
  first two fail on the parent (he lay and stood up on (10,7)); the third fails there only on the missing field.
- Docs: DESIGN §25.17.3 (the decision, marked as the owner's deviation; the §25 intro's decisions of 2026-10-07),
  docs/SIM.md §1, DESIGN §5 (design/engine.md DP / knocked-out line), docs/PLAYING.md 作战 row.

Gate: non-browser suites 5024 / 5024, npm run golden ok, test/golden.test.js 9 / 9, lint 0 errors, check:imports ok,
typecheck ok.
2026-10-07 04:04:41 +08:00
sganggs 9ca52ba798 feedback5: merge CB1 — community reports (bonds / strategies / items): a pair of colds on an enemy becomes the freeze and leaves no cold (the 谢拉格 wind no longer freezes for good), a 复活 (埃芒加德's 命结之秘, M3茧甲) is a knock-out and an immediate free redeploy where the operator lies (砾's and 瑕光's 被击倒时 / 部署时 layers fire), 佩佩's special refresh is paid, the result card hides the layers of 调和 / 协防干员 / 独行 / 绝技, the 炎佑 keeps off 外勤医疗's slot, 凯瑟琳's 定向投放 offers every shop item; 烛煌's 绝处重燃 before the hammer's lock and the 寻呼模块 / 简易通讯机 tier cap kept as they are (the owner's decisions of 2026-10-07); §25.15 → §25.21 (§25.15 is the shortcuts'); golden: vs feedback5 CB1's own rules — roster-005/009/010/012/014/015/016/018/026/029/031/033/036/040/042/046/047/049, bond-egirShip-high, bond-indomShip-low, bond-kjeragShip-high, bond-maniShip-high, bond-raidShip-low, bond-steadShip-high, bond-suntShip-low, boss-boss_2/3/4/6-pair, hidden-boss_8/9/10-pair, standin-07, matches solo-FUNNY-1, solo-NORMAL-1, solo-HARD-1, solo-ABYSS-1, coop3-ABYSS-5, coop4-FUNNY-6, coop4-ABYSS-7; vs CB1 what feedback5 changed since its base (CB2, CB3, CB4, CB5) plus roster-014
Conflicts resolved by hand:
- server/sim/content/items/battle.js: CB3 had extended `revivedInPlace` (an in-place 复活 restarts a deploy-timed
  skill, item 44); CB1 replaced the in-place revive by PRTS's form — `reviveNow`, a `death` hook that redeploys the
  operator at once, free, where it lies — and removed `revivedInPlace`. CB1's side is kept: its redeploy resets the
  skill, so an `activateOnDeploy` skill starts anew by itself; CB3's tests (test/sim/feedback5-raid-revive.test.js:
  the jump at once after M3茧甲 / 埃芒加德, the window back to full, 砾's fresh barrier) pass on it unchanged. Their
  header, bonds_core's comment, DESIGN §25.17.5 say so.
- docs/SIM.md, docs/design/engine.md: CB1's `fatal` rows (the 复活 are `death` hooks now); the `death` rows also say a
  deploy-timed skill starts anew (§25.17.5).
- data/choices.json: no conflict; `node tools/build-data.mjs --offline` on the merged tree rewrites all 15 data files
  byte-identically, and the JSON compare with feedback5 shows only pools.pool_equip_kathe.maxTier removed (CB1).
- docs/history/0.2.0.md: CB1's section renumbered §25.21 (its §25.15.1–10 and two self-citations; no citation of it
  elsewhere), placed last; the owner's decisions of 2026-10-07 on items 5 and 45 recorded there, in the intro and in the
  two pin tests' headers (feedback5-blaze-hammer, feedback5-cb1-pins).

Golden: solo-FUNNY-1 (outside CB1's list) has 6 埃芒加德 revives and 85 freezes on feedback5's path (instrumented).
roster-014 differs from CB1's own digest by 玛恩纳's 无动于衷: CB3's rule (every enemy damage instance) answers the
萨卡兹枯朽战车's pollution that hits a 卡西米尔 operator in CB1's timeline — with that counter limited to attacks the merged
roster-014 equals CB1's digest exactly (checked).

Gate: non-browser suites 5021 / 5021, npm run golden ok, test/golden.test.js 9 / 9, lint 0 errors, check:imports ok,
typecheck ok.
2026-10-07 03:54:35 +08:00
sganggs d841d6ac22 feedback5: merge CB3 — community reports (operator kits): 砾's normal attack hits twice at 50 % 伤害倍率 (a 频次 enemy loses 2), 乌尔比安's S3 moves only onto his own board (never behind the one-helper 联防 map's red gate nor onto a boss field's other half), the 「受到攻击时」 counters answer every enemy damage instance (菲莱 S2 on 深溟巢涌者's pulse, 星熊, 泡泡, 刺玫, 余, 玛恩纳, 年, 斩业星熊), an in-place 复活 restarts a deploy-timed skill so a 突袭 member jumps at once, 银灰's normal attack plays its own impact (and 雷蛇 / 初雪 / 圣约送葬人 drop a skill mode's sound); five reports pinned; §25.17 between CB2's §25.16 and CB4's §25.18; data/assets.json lists 银灰's impact (p_imp_spear_n.mp3 fetched); golden: vs feedback5 CB3's own rules — roster-002/004/005/008/010/012/016/024/033/044, bond-indomShip-low/high, bond-kazimierzShip-low/high, bond-lateranoShip-low, boss-boss_2-solo, boss-boss_4-pair/-solo, hidden-boss_8-pair/-solo, hidden-boss_9-solo, diy-051, matches solo-FUNNY-2, coop2-NORMAL-3, coop4-ABYSS-7, coop2-ABYSS-10-boosted; vs CB3 exactly what feedback5 changed since its base (CB2, CB4, CB5)
The merge:
- server/sim/battle/players.js: CB3's onOwnBoard hunk is byte-identical to CB4's (git kept one); its comment and
  docs/SIM.md's onOwnBoard row now name 乌尔比安's S3 【移动】 next to the 突袭 landing (DESIGN §25.17.2 / §25.18).
- test/sim/facing-invariance.test.js: CB3's scenario setup (onOwnBoard off on the open field) and the CB4 merge's
  突袭 test (its enemy inside the board) merged cleanly, both kept.
- data/assets.json: CB3 had regenerated it offline without 银灰's entry (his official impact file was not on disk);
  `node tools/fetch-assets.mjs --add-only` (shared public/assets, add-only) downloaded p_imp_spear_n.mp3 — 8.8 KB,
  the only new file (ok 1, skipped 7968; the 117 misses are the known upstream gaps) — and rewrote the manifest.
  Field-wise JSON compare with CB3's manifest: only audio.sfx.units.char_172_svrash = { hit: p_imp_spear_n } plus hash
  and stats (files / bytes / sfxUnits +1); against feedback5: CB3's four operators (银灰 now the spear impact and no
  S3 swing, 雷蛇 / 初雪 / 圣约送葬人 without the skill-mode impact) plus hash / stats. §25.17.6 says so.
- docs/history/0.2.0.md: §25.17 placed in order, the intro's per-stream list and workstream list name CB3.

Golden moves outside CB3's commit list: coop2-NORMAL-3 fields 砾 from round 3 (her double hit) and 刺玫 in rounds 4-7
(instrumented); solo-FUNNY-1 (in CB3's list through the counters) fields no counter operator on feedback5's path, only
砾, whose two half hits change no kill, leak, LP or end stat there, so its digest stays.

Gate: non-browser suites 5003 / 5003, npm run golden ok, test/golden.test.js 9 / 9, lint 0 errors, check:imports ok,
typecheck ok.
2026-10-07 03:41:48 +08:00
sganggs 6ed3aed335 feedback5: merge CB4 — community reports (enemies / bosses): a 突袭 member lands only on its own player's board (never a boss field's hand / 临时整备区 rows nor the other half of a 联防 or boss field), a silenced 萨卡兹枯朽战士 leaves no 污染秽蚀, 萨卡兹穿刺手's acceleration ends with a stun or 束缚 and its first hit after a block adds move speed × 600 as its own instance, 自制投石机 ignores its block when it picks a target (no attack on the 排气格栅's hidden blocker), the briefing types' 7–9 waves, 新硎's 断刃, a freed prisoner in 联防, 鸭爵's 0–2 swaps and the moving leaders' routes pinned, four reports not reproduced; §25.18; golden: vs feedback5 CB4's own rules — roster-016, boss-boss_2/3/4/5/6-pair, hidden-boss_8/10-pair, standin-04/06/08, diy-028, diy-124, matches solo-NORMAL-1, solo-HARD-1, solo-ABYSS-1, coop2-HARD-4, coop4-ABYSS-7, coop2-NORMAL-8-serverrun; vs CB4 exactly what feedback5 changed since its base (CB2's roster 13 / bonds 7 / fields 6, CB5's 18 bot matches)
Merge fix: test/sim/facing-invariance.test.js — the 突袭 rotation check put its enemy on the board's top row (9, 9),
so the facing-RIGHT landing tile it expected, (8, 8), lies above the player's board, where CB4's onOwnBoard rule (the
official 再部署 goes where the player deploys; community reports 40 / 16.3) now refuses it; the member landed on
(10, 8). The enemy stands at (10, 6), inside rows 9–12 / cols 2–10, so all four diagonal tiles are candidates in every
direction and the test checks the facing tie-break as before. It failed on fb5-cb4 itself (the stream did not run the
file). The §25 intro's stream lines joined into one sentence again.

Golden moves outside CB4's commit list are its rules on feedback5's paths (instrumented): solo-HARD-1 and solo-ABYSS-1
now have silenced 枯朽战士 deaths (8 / 15) and 突袭 candidates the own-board filter refuses; coop2-ABYSS-10-boosted,
coop2-NORMAL-3 and coop2-NORMAL-14-standins (in CB4's list) have no silenced 枯朽战士 death on this path, and their
digests are identical with the own-board filter switched off (the refused tiles were never the chosen ones).

Gate: non-browser suites 4968 / 4968, npm run golden ok, test/golden.test.js 9 / 9, lint 0 errors, check:imports ok,
typecheck ok, docs-consistency + docs-paths 31 / 31.
2026-10-07 03:21:57 +08:00
sganggs de78d49f9b feedback5 CB3: DESIGN §25.17 — the community reports of 2026-10-06 for operator kits and triggers (five fixed, five answered, 乌尔比安's revive tile a question for the owner); kit comments follow the counter rule
docs/history/0.2.0.md: §25.17 in §25's style (seen / official / cause / now / [ASSUMED] / golden / tests) and the intro list;
docs/design/engine.md cites §25.17.5 for the in-place revive; the header comments of 星熊, 斩业星熊, 年 and 余 say "every enemy
damage instance" instead of "every attack". No code change.
2026-10-07 02:47:47 +08:00
sganggs 3d472e2304 feedback5 CB3: an in-place 复活 (M3茧甲, 埃芒加德) starts a deploy-timed skill again, so a 突袭 member with one jumps at once after the revive instead of waiting out the 10 s idle (community report of 2026-10-06, item 44)
Official: PRTS 盟约记录 备注 — "复活" is 退场 + a 0-time / 0-cost redeploy, i.e. a new deployment, after which a deploy-timed
skill ("部署后…秒内") runs again; a 突袭 member counts such a running window as 技能就绪 (bonds/addon/battle.js raidPoll,
GitHub #49 / #109) and jumps when nothing is in its range. Cause: the remake revives in place (fatal hook) — her window, over
by then, stayed over, and only the idle trigger was left (measured: 缄默德克萨斯 S3 jumped 10.00 s after an M3茧甲 / 埃芒加德
revive, 0.23 s after 不屈's real redeploy). Now items/battle.js revivedInPlace also restarts an activateOnDeploy skill on the
next tick: activated anew when its window had ended, its window back to the full duration when it still ran. The SP reset
and the other 部署时 effects of PRTS's form stay unmodelled (§21.21).

Golden: 1 scenario — roster-012: the elite 缄默德克萨斯 is revived in place three times (101 s, 105 s, 113 s) and her S3 runs
again each time (checked instrumented). Tests: test/sim/feedback5-raid-revive.test.js (3; the M3茧甲 / 埃芒加德 jump and the
window cases fail on the parent, 不屈 is the unchanged control). Docs: docs/SIM.md and docs/design/engine.md (fatal hook).
2026-10-07 02:33:10 +08:00
sganggs f1e462ef62 feedback5 CB2: persistent ground areas stay readable when they stack — a zone re-sent under one key updates in place, persistent areas are dimmer and share their light where they overlap (community report of 2026-10-06 「炼金单元等范围持续性技能特效太亮(尤其是多层叠加以后)」)
Cause: 引星棘刺 S2's drifting alchemy unit is re-sent every second (position and radius change) and the client drew each
event as a new additive zone lasting the rest of the unit's life — up to twelve layers on one spot; overlapping units
(锡人's charges, several alchemists) added up the same way (render/fx/zones.js: disc alpha 0.28, edge 0.75, ADD blend).
Now: the sim fx carries `key` (kits/ops/chess_char_5_15-thorn2.js) and zones.js updates the zone under that key in place;
zoneAlpha draws a persistent area (> 3 real s) at 0.16 / 0.5 and ÷ √n among the n persistent areas overlapping it (centres
closer than ¾ of their radii summed); short bursts and telegraphs unchanged.

Golden: unchanged (fx events are counted by kind; the snapshots do not carry fx).
Tests: test/render/feedback5-zone-stack.test.js (3, fail on the parent).
2026-10-07 02:32:28 +08:00
sganggs 5877800a67 feedback5 CB3: the "受到攻击时" counters answer every damage instance from an enemy, not its attacks only — 菲莱 S2 now blasts on 深溟巢涌者's pulse, so do 星熊 S2, 泡泡, 刺玫 S2, 余 S1, 玛恩纳 无动于衷, 年 S2 and 斩业星熊 (community report of 2026-10-06, item 30)
The report's 退行的潮涌者 is the 巢涌者 (深溟 / 富营养的巢涌者 in this mode): no normal attack, its talent hurts every operator in
range once a second. Official (ArknightsGameData buff_template_data): its pulse is an AdvancedApplyDamage with the enemy as
source (enemy_dsubrl_aoe[aura]); the counters fire on ON_TAKE_DAMAGE — philae_s_2 with no filter, inverse_damage (星熊 S2),
inverse_damage[magic] + nian_s_2 (年 S2), bubble_s_2 / bubble_t_1 (泡泡), vendla_s_2 (刺玫), yu_s_1[inverse_damage] (余 S1),
hsgma2_s_1 / hsgma2_e_003_tr_take (斩业星熊), mlynar_t_2[inverse] (玛恩纳) on a source of the other side; 棘刺 S2 (普通伤害
filter) and 信仰搅拌机 S3 already took any damage. Cause: the kits required dmg.isAttack. Now kits/shared/tier1.js
byEnemyAttack = any enemy damage instance but a 流失, an element 损伤, 无来源 damage or another counter / reflection (tags
'counter' / 'reflect'); 菲莱 S2 any instance but a 流失 or a counter. test/content/op_nian.test.js pinned "a non-attack hit
returns nothing" for 年 S2 — updated on purpose (answered now; a 流失 still is not).

Golden: 19 scenarios where an enemy's non-attack damage (skills, pulses, areas) reached one of these operators — their counter
now answers it (more damage, fx thorns / aoe): roster-002, -005, -008, -010, -012, -016, -033, -044; bond-lateranoShip-low;
fields boss-boss_2-solo, boss-boss_4-pair, boss-boss_4-solo, hidden-boss_8-pair, hidden-boss_8-solo; matches solo-FUNNY-1,
solo-FUNNY-2, coop4-ABYSS-7, coop2-ABYSS-10-boosted; diy-051. Tests: test/sim/feedback5-counters-any-damage.test.js (6; 5
fail on the parent, the first checks the 巢涌者 never attacks). Docs: docs/SIM.md (re-entrancy rule).
2026-10-07 02:30:07 +08:00
sganggs 9b164fdc66 feedback5 CB3: 乌尔比安's S3 moves only onto a tile of his own board — no longer behind the red gate of the one-helper 联防 map nor onto a boss field's other half (community report of 2026-10-06, item 27)
Official: PRTS 乌尔比安 S3 备注 ③ — the 【移动】 takes the anchor tile if it can be deployed on, else the tile one beyond, else
his own tile. Cause: "deployable" was any standable tile of the battle rect; UNITE_RECT holds both halves of the 联防 map, and
on 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 to the right half, where no enemy walks, and he stood there for the whole skill. Now the landing must also
lie on his player's board: Battle.onOwnBoard(ps, r, c), the board region GEO.FIELD mapped onto the field (the hunk is
byte-identical to CB4's 219ab31, which uses it for the 突袭 landing, so the two merge cleanly).

Golden: 1 scenario — fields hidden-boss_9-solo: his first cast from (2,5) landed on (2,11), the solo boss field's right
half (checked instrumented); he now stays and the fight differs from there. Tests: test/sim/feedback5-ulpia-own-board.test.js
(4; the one-helper and the two-helper 联防 cases fail on the parent); test/sim/facing-invariance.test.js — its open field
has no boards, so its setup counts every tile as the player's own (the own-board rule is a board-position rule, like the
deployment order the scenario already avoids).
2026-10-07 02:30:07 +08:00
sganggs 17c96843ee feedback5 CB2: the countdown summons (医疗探机, 诅咒娃娃, 海嗣; 自选 工程蓄水炮, 沙地兽, 打字机, 本能的召唤) take no damage — 活性源石 included —, are never healed, and their bar shows the life left (community report of 2026-10-06 「赫默的无人机、浊心斯卡蒂的海嗣等这种召唤物不会受到外来伤害…血量随时间减少」)
Official: PRTS 斯卡蒂的海嗣 备注 「持有禁疗、无敌」, the token prefabs of 海嗣 and 沙地兽 carry abnormal flags 5 + 7 (无敌,
禁疗), 工程蓄水炮 7 (禁疗); the report describes the official mode for the drone too — [ASSUMED] 无敌 + 禁疗 for the summons
the base prefabs give no flag (医疗探机, 诅咒娃娃, 打字机, 本能的召唤), and the bar as a timer.
Cause: content/tokens.js / the kits only made them untargetable: a 海嗣 on 活性源石 lost 70 of its 100 HP every second, a
hurt drone drew every medic's heals, and the bar was plain HP. Now: COUNTDOWN_SUMMONS / startCountdown (called where each
lifetime is scheduled: tokens.js scheduleLifetime, 浊心斯卡蒂, 温蒂, 莱伊, 鸿雪, 酒神 kits) give 无敌 + 禁疗 and
Unit.countdown; snapshot.js sends hp = maxHp × the share of the life left (the sim HP stays full, so no selector sees a
low-HP summon). Attacked summons (沙之碑, 狼群 …) are unchanged. The 吟游者 trait therefore cannot refill such a bar (item 32).

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 enemy and leader damage stays up: fights change).
Tests: test/sim/feedback5-countdown-summons.test.js (7; fails on the parent: no COUNTDOWN_SUMMONS — and there the 海嗣
lost 70 HP to an 活性源石 tick). Docs: SIM.md token pieces, PLAYING.md 作战中.
2026-10-07 02:27:33 +08:00
sganggs 64f8bf912a feedback5 CB2: 赫默's S2 医疗无人机 casts the moment its SP is full — the placed drone takes the field at once, injured ally or not; her SP stops while the stock is full (community report of 2026-10-06 「赫默的无人机在2技能好了之后应该秒放」)
Official: the client skill skchr_silent_2 (AUTO) has no `_trigger`, `_allowNoTarget` 1, `_checkHasTargetBeforeDoCast` 0
and a RechargeToken action — no cast condition; `_stopSpWhenTokenIsFull` 1 = PRTS S2 备注 「医疗探机库存达到上限后赫默获得
阻回,直到库存被消耗为止」.
Cause: kits/ops/chess_char_2_02-silent.js left the data's DEFAULT rule with `heal`, so the cast waited for an injured ally
in her range (SP full at 26 s with nobody hurt: no cast, no drone). Now: trigger SP_FULL; a refreshed 阻回 (noSp) while
her stock holds `cnt` drones.

Golden: roster-003 / roster-005 (赫默 and her placed drone: the drone comes back at each full SP), bond-visiShip-low /
-high (赫默 on the 远见 team, same).
Tests: test/content/feedback5-silent-drone.test.js (2, fail on the parent).
2026-10-07 02:20:10 +08:00
sganggs a1d118a01f feedback5 CB1: the 炎佑 no longer spawns on 外勤医疗's map-character slot — the medic / Touch stands beside it (community report 「Touch策略给的医疗干员会跟炎盟约的炎祐冲突,无法同时出场」, item 23)
Both spawn at battle start; tokens.js airTile (the 炎佑's tile: void tiles nearest the half's centre) did not know the
stage's map-character positions (data/stages.json mapChars, the levels' predefined 预备干员-医疗 / Touch at (10, 2) …)
and took (10, 2) on 战场#08 涨潮控制 (every time) and 战场#07 排气格栅 (the second 炎佑 of 9 炎); spawnMapChar then found
its tile taken and the medic never stood (measured on every map: m04 6 / 9 炎 and m03 9 炎 — medic false). airTile now
holds those positions (mapCharKeys). Test: test/content/feedback5-yanyou-touch.test.js (fails on the parent). Golden
unchanged (no corpus battle had a 炎佑 on that tile).
2026-10-07 02:18:36 +08:00
sganggs 64aaac8387 feedback5 CB2: 琳琅诗怀雅's 破财消灾 cost restarts at 5 DP with every deployment — a redeploy no longer keeps the doubled cost; a 联防 field already started at 5 (community report of 2026-10-06 「进入联防阶段…正常对局中死亡之后再部署复活费用也应该重置」)
Official: PRTS 琳琅诗怀雅 天赋 破财消灾 备注 「再部署时重置本天赋费用消耗」; the client buff swire2_t_2 multiplies the `cost` in its
own blackboard (CalculateBlackboardValueViaParams × cost_multi) and is rebuilt at each deployment.
Cause: kits/ops/chess_char_3_04-swire2.js kept mem.saveCount for the whole battle. Now: reset on her deploy hook (battle
start, redeploy, 突袭 再部署). 联防 is a battle of its own (fresh units), so its first save always cost 5 — pinned.

Golden: roster-008 (琳琅诗怀雅 elite revived for 5 DP after a redeploy: more DP left, the fight changes), roster-049 (the
same in band 5: snapshot hashes only — DP).
Tests: test/content/feedback5-swire2-revive-cost.test.js (2: the redeploy one fails on the parent, 20 DP instead of 5;
the 联防 one is a pin).
2026-10-07 02:15:42 +08:00
sganggs 212a073af6 feedback5 CB3: 砾's normal attack hits twice at 50 % 伤害倍率 after DEF, so a 频次 enemy loses 2 per attack (community report of 2026-10-06, item 16.5)
Official: PRTS 砾 特性备注 — every normal attack in her attack animation deals two instances, each 50 % of the final damage
(after DEF / damage reduction, before 重设伤害); the second triggers no 受击回复. Cause: one instance per attack. Now the profile
field hitDmgMul (ai.js resolveHit: DamageInfo mul on each of the `hits` instances, noSp on the later ones) and 砾's kit trait
{ hits: 2, hitDmgMul: 0.5 } — the same total against normal enemies, twice the count against 频次 enemies.

Golden: 7 scenarios with 砾 on the board — roster-004, roster-005, roster-024; bond-indomShip-low / -high and
bond-kazimierzShip-low / -high (she is in 不屈 and 卡西米尔): two damage events per attack; in roster-024 and
bond-kazimierzShip-high the last blow lands on another instance, so kills (and the heals / damage that follow them) shift
between her and her neighbours (roster-024: 砾 19 -> 25 kills, 风丸 13 -> 9). Tests:
test/sim/feedback5-gravel-double-hit.test.js (2, both fail on the parent). Docs: docs/SIM.md (profile flags).
2026-10-07 02:12:37 +08:00
sganggs 5d3ca339e4 feedback5 CB2: 琳琅诗怀雅's S1 仗义疏财 heals herself too — the 3×3 around her includes her own tile (community report of 2026-10-06 「琳琅诗怀雅不会治疗自己」)
Official: S1 「下一次攻击会为周围八格内血量不足70%的一名友方单位恢复…」; the client charpack (char_1033_swire2, mode S1,
ability HealAlly) selects with range x-4 (the 3×3 with her tile), ally side, _excludeOwner 0, max HP ratio 0.7, one target.
Cause: kits/ops/chess_char_3_04-swire2.js healTarget skipped her (a === unit) and kept only Chebyshev distance 1.
Now: the lowest HP ratio below 70 % of the 3×3, herself included (her own 禁疗 still stops it); the owner's 2026-10-04
cadence (a heal without an attack, once per attack cycle) unchanged.

Golden: roster-027 (琳琅诗怀雅 elite S1 in band 4: she heals herself below 70 %).
Tests: test/content/feedback5-swire2-self-heal.test.js (2, fail on the parent).
2026-10-07 02:12:34 +08:00
sganggs 017390c93f feedback5 CB2: 刺玫's S2 sends only the counter's trait heal to her protégé — her attacks keep healing the most injured ally in range, herself included (community report of 2026-10-06 「刺玫开技能(装备源石药剂)之后不能治疗」)
Official: S2 「该角色受到攻击时刺玫对目标造成攻击力20%的法术伤害并仅对该角色触发刺玫特性」 (en "...and activates her Trait on
the ally"); the client buff vendla_tr heals through the S2TraitHealRange selector (the vendla_s_2 holder) only for a damage
whose modifier carries vendla_s_2 (the counter, vendla_s_2[extra_damage]), else through TraitHealRange (_excludeOwner 0).
Cause: kits/ops/chess_char_1_06-vendla.js sent EVERY trait heal to the protégé while the skill ran (usually at full HP),
so a 源石溶剂 carrier healed nobody for 15 s.

Golden: roster-001 / roster-002 (刺玫 S2 in band 1), bond-deputShip-low / -high, bond-suntShip-high,
bond-victoriaShip-low / -high (刺玫 on those teams), matches solo-FUNNY-2, coop2-NORMAL-3, coop3-ABYSS-5, coop4-FUNNY-6,
coop4-ABYSS-7 (bots field 刺玫: her heals land on injured allies during S2, fights change).
Tests: test/content/feedback5-vendla-heal.test.js (2, fail on the parent); kits_t1t2's 刺玫 assertion message reworded.
2026-10-07 02:09:01 +08:00
sganggs 96794c5cc7 feedback5 CB1: 佩佩's special refresh is the next manual refresh at its usual price, no free refresh comes with it (community report 「佩佩策略的特殊刷新也是要花钱的,不是免费」, item 20)
博学多通 "升级调度中心至2、4和6级后,获得1次特殊刷新:此次刷新出现的干员优先为<萨尔贡>干员" names no 免费 (德克萨斯's trait
says 「获得1次免费刷新」 for a free one); bands/meta.js read the blackboard's `price` 0 as a free refresh and granted one at
each of those level-ups (measured: level 2 → 1 free refresh, the special refresh cost 0, the next 1). Now the level-up
only marks the next manual refresh special: it costs the refresh price (unless another free refresh pays it) and fills
the chess slots with <萨尔贡> first as before. [ASSUMED] `cnt` / `price` 0 change nothing. Test: test/content/bands.test.js
(佩佩, fails on the parent). Golden unchanged (no corpus match levels a 佩佩 shop).
2026-10-07 02:08:24 +08:00
sganggs fdb3ae1b46 feedback5 CB4: 自制投石机's targeting ignores its block (索敌不受阻挡影响) — blocked by an operator on the 排气格栅 with nobody else in range it does not attack, as in the official game (community report of 2026-10-06, item 24)
The 「投石车」 is 自制投石机 (enemy_10162_mnctpt), the 「蒸汽地板」 the 排气格栅 smog (隐匿 to enemy ranged attacks). PRTS
天赋 「索敌不受阻挡影响」: the blocker exception (a blocked enemy attacks its blocker whatever its selectability) does not
apply to it. New enemy profile field `blockFree` (spawns.js): attackTargets selects as if unblocked, canTargetAlly
refuses a 隐匿 / 迷彩 blocker to it, sortAllyTargets puts no blocker first. Other enemies unchanged.

Golden: standin-06 (the bounty catapult, blocked by 忍冬, now shoots by 仇恨值 — checked instrumented).
Tests: test/sim/feedback5-catapult-smog.test.js (3; 2 fail on the parent). Docs: DESIGN §25.18.7, docs/SIM.md.
2026-10-07 02:07:51 +08:00
sganggs d40cb4e79e feedback5 CB4: 萨卡兹穿刺手 — a stun or 束缚 ends its acceleration and drops the speed layers; its first hit after a block adds current move speed × 600 physical as its own instance (community report of 2026-10-06, item 36)
Official: PRTS 天赋 and the battle prefab's templates (dlancer_t_listener[a/b/c] every 0.1 s: STUNNED / UNMOVABLE end
dlancer_t[trigger], not blocked starts it; a MULTIPLIER layer every 0.5 s up to 25 tries, blocked or not;
dlancer_t_atk: DamageViaAttr MOVE_SPEED × 600, physical, ignoreForSp, then ends the trigger). Until now it kept
accelerating through a stun and kept the speed, and the hit was one attack multiplied ×(1 + 6 × layers / 25), a stun
in between included. A slow is no reset (official).

Golden: 6 scenarios, each with 萨卡兹穿刺手: roster-016, standin-04, standin-08, diy-028, diy-124, coop2-HARD-4.
Tests: test/content/enemies_bosses.test.js (3, fail on the parent). Docs: DESIGN §25.18.6.
2026-10-07 01:59:52 +08:00
sganggs a3a0ddd2be feedback5 CB1: a 复活 (埃芒加德's 命结之秘, M3茧甲) is a knock-out and an immediate free redeploy — 砾's and 瑕光's 被击倒时 / 部署时 layers fire on every revive (community report 「卡西米尔和艾芒加德策略似乎有BUG:像砾和瑕光这种死亡和部署的叠层效果…无法触发」, items 9 / 37)
PRTS 卫戍协议:盟约 下半/PRTS盟约记录, 埃芒加德 and M3茧甲 备注: "“复活”的实现方式为:受益者因移动之外的原因退场时下次部署的
再部署时间和费用归零". Both revived in place as `fatal` savers, so the operator was never knocked out nor deployed again:
砾 (<部署时> 卡西米尔 +1, <被击倒时> 不屈 +2), 瑕光 (<部署时> +4, 12 per battle), the 卡西米尔 bond's per-deployment ATK,
克莱门莎 / 卡莱莎 and every other 被击倒时 / 部署时 effect skipped the first 3 knock-outs (measured: only the 4th, real
death stacked). Now items/battle.js reviveNow, a `death` hook (M3茧甲 PRIO_RESPAWN 13, 埃芒加德 PRIO_BAND_REVIVE 12,
ahead of 阿戈尔 5 at 11 and 不屈 at 10): the knock-out stands and the operator redeploys at once, free, where it lies
(full HP, SP reset, a new deployment for 坚固维式重锤's lock — revivedInPlace and the `revives` counter are gone). The
ctx carries `revivedBy`, so 阿戈尔 5 still does not count such a knock-out as the member's first (the owner's decision
of 2026-10-05: an operator's own revive uses no slot; 埃芒加德 [ASSUMED] alike, unchanged). 淬羽赫默 S3 keeps its place
right after the hammer's lock (PRIO_REVIVE − 0.5). Tests: test/content/feedback5-revive-redeploy.test.js (fails on the
parent); bands / bonds_core / feedback1f-hammer / op_lessng / op_zuole / docs-consistency updated to the redeploy. Docs:
SIM.md (fatal, death), design/engine.md (fatal, death), PLAYING.md (复活), research 04 (M3茧甲).

Golden: the battles with M3茧甲 or 埃芒加德 whose operators fell — a revive is now a knock-out (deaths count, kill events,
redeploy, SP reset, 被击倒时 / 部署时 effects): roster-012 / 026 / 033 / 040 / 047, boss-boss_6-pair, hidden-boss_8-pair /
boss_9-pair, standin-07; matches solo-NORMAL-1, solo-HARD-1, solo-ABYSS-1.
2026-10-07 01:56:43 +08:00
sganggs 7fb6a1c8b4 feedback5 CB4: silenced at its death, 萨卡兹枯朽战士 (组长) releases no 污染秽蚀 (community report of 2026-10-06, item 10)
Official: PRTS 特殊机制 死亡爆炸 「默认可沉默」; the client's PollutedDie buff uses template projectile_on_killed, which
checks CheckAbnormalFlag SILENCED (unset) before EmitProjectile — the template of 高能源石虫's SILENCE-flagged blast. Its
handbook line alone is NORMAL, so the handbook rule missed it; kitPolluted's death ability is now `sil`, and the
silence test names the two keys as template exceptions (audit of all 243 prefabs: 刺胄之弹 is the only other such line,
left for later).

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 (silence rule + both keys; 3 fail on the parent). Docs: DESIGN §25.18.2.
2026-10-07 01:48:00 +08:00
sganggs e47b098d43 feedback5 CB1: a pair of colds on an enemy becomes the freeze, no cold is left — the 谢拉格 wind no longer freezes for good from 51 layers on (community reports 「谢拉格盟约冰冻时间没有随层数正确成长」 and 「…被在无法被任何干员攻击到的地方永控」, items 7 and 8)
PRTS 术语释义 寒冷 「友方寒冷始终需要两两一对产生友方冻结,持续时间取双方之中最高」, 异常效果 COLD 「在特定条件下转变为冻结」:
applyStatus kept the older cold on for as long as the freeze, so every later cold froze again; the wind (every 25 s,
20 + 0.1 x layers s of cold) froze an enemy anywhere for the rest of the battle once its cold outlasted 25 s, never
below. Now the pair turns into the freeze (max of the two, as before) and leaves no cold on an enemy; a cold on an
operator (敌方寒冷) keeps the old rule. The wind alone now freezes 20 + 0.1 x L s of every 50 s from 51 layers (all of
it from 300). Tests: test/sim/feedback5-kjerag-cold.test.js (fails on the parent); feedback3-cold-freeze and 灵知 S2
(kits_t4) updated to the pairing. Docs: SIM.md cold row, design/engine.md.

Golden: every scenario where a second cold met an enemy still cold (灵知, 初雪, 雪猎, 耶拉, 圣聆初雪, 凛御银灰, items,
the 谢拉格 wind) — the pair no longer leaves a cold: roster-005 / 009 / 010 / 012 / 014 / 015 / 016 / 018 / 026 / 029 /
031 / 036 / 040 / 042 / 046 / 047 / 049; bond-egirShip-high, bond-indomShip-low, bond-kjeragShip-high,
bond-maniShip-high, bond-raidShip-low, bond-steadShip-high, bond-suntShip-low; boss-boss_2-pair / boss_3-pair /
boss_4-pair / boss_6-pair, hidden-boss_8-pair / boss_10-pair; matches solo-HARD-1, solo-ABYSS-1, coop3-ABYSS-5,
coop4-FUNNY-6, coop4-ABYSS-7.
2026-10-07 01:39:50 +08:00
sganggs 219ab31a3d feedback5 CB4: a 突袭 member lands only on its own player's board — never the boss field's hand / 临时整备区 rows, never the other half of a 联防 or boss field (community reports of 2026-10-06, items 40 and 16.3)
Cause: raidTile took any standable tile of the battle rect; BOSS_RECT holds rows 0-1 (tile_achand, buildable high
ground) and UNITE_RECT both halves of the 联防 map. Battle.onOwnBoard(ps, r, c) maps the board region (rows 9-12,
cols 2-10) onto the field as mapTile maps the pieces; raidTile takes only those tiles.

Golden: 8 scenarios, each with members that landed on the partner's half on the parent (checked instrumented):
fields boss-boss_2/3/4/5/6-pair, hidden-boss_8/10-pair; matches coop2-ABYSS-10-boosted (ai_0 on the right half).
Tests: test/sim/feedback5-raid-own-board.test.js (4, fail on the parent). Docs: DESIGN §25.18.1, docs/SIM.md.
2026-10-07 01:36:53 +08:00
sganggs 714af994fc feedback5: merge W5AA — community reports of 2026-10-06: the 孤岛风云 prisoners leave the gate confined (grey) and change model as their prefabs do, the 4th attack hits freed; a bounty enemy that dies with no operator behind it pays in 联防 too (the helper whose half it fell on); 忍冬's trigger and 枯朽之种's bounty were already fixed (pinned by tests); DESIGN §25.14 after round 18's §25.13; data/enemies.json regenerated offline on the merged code (round 18's model quirks + the prisoners' clips); golden: vs feedback5 exactly W5AA's moves (26 battles, solo-ABYSS-2, coop2-NORMAL-3, coop3-ABYSS-5, solo-HARD-9-boosted), vs W5AA exactly round 18's boss-pool moves 2026-10-06 22:35:10 +08:00