Commit Graph
801 Commits
Author SHA1 Message Date
sganggs 1205336a27 feedback7 R22-FIELDS: an enemy whose route ends on a corner portal stays hidden 3 s inside it before it comes out of [5,10], like the explicit crossings of the same tiles (review of the #337 commit); golden: 7 fields, 4 matches — solo-NORMAL-1's Hidden Core still fails
The Grok review of fb7-fields (MEDIUM): portalPickup spliced DISAPPEAR and APPEAR with nothing between, so the enemy
vanished on [1,3] / [1,17] and stood on [5,10] in the same tick, targetable at once, while the data's explicit
crossings of the same tiles hide it: WAIT 3 s in 85 of the 95, 5 s in 9, 1 s in 1. portalPickup now splices a 3 s
WAIT (PORTAL_WAIT, the modal explicit wait) between them; [ASSUMED] the 3 s, no source times this crossing. Docs: the
SIM.md sentence and the portalPickup comment.

Tests: test/sim/portal-appear.test.js — the two route-end tests record the test enemy's hidden spans: one crossing,
entrance → [5,10], hidden 3 s (± a tick); both fail on the parent (0.000 s). 9/9.

Golden (against the 0 s version; the rounds of every match unchanged):
- matches solo-NORMAL-1 (Hidden Core boss_8 胄, act1autochess_h08_01_s): still failed — hiddenCleared false, team LP 0,
  14 rounds — with the leader left at 63897 instead of 99894 (cleared with 26 LP in 0.2.1). The same course as with
  0 s: the third vtsk, which leaked at the portal at 105 s in 0.2.1, comes out of [5,10] 3 s later, walks through the
  team's line and leaks at the door at 185.5 s (170.2 s before); 0–2 of the 8 operators stand between 100 and 320 s, the
  leader stalls near 108000 from 280 s, the overtime drain from 300 game s takes the 25 LP left by 350 s while the
  redeployed operators bring the leader to 63897 (notes trace-hidden*.mjs).
- matches solo-HARD-1 (Hidden Core failed as before): pool left 2839368 → 2982555; solo-HARD-9-boosted (cleared): team LP
  361 → 376 (383 in 0.2.1); coop2-NORMAL-14-standins (Final Assault lost as before): pool left 97588 → 108473.
- fields boss-boss_2-solo (leader left 2763024 → 2757148), boss-boss_4-solo (3759921 → 3757752), boss-boss_6-pair
  (killed 6 → 5, one hllevi_2 still walking at the 200 s cap, both players still perfect; leader 6972383 → 6932482),
  boss-boss_6-solo (3904791 → 3907393), hidden-boss_8-pair (the vtsk that comes back near the cap is still inside the
  portal at 200 s: one appear fewer, the last snapshot hash), hidden-boss_8-solo (killed 8 → 6, leaks 10 → 12),
  hidden-boss_10-solo (killed 11 → 10, leader left 7323370 → 7333760).
- unchanged by the wait: solo-FUNNY-2, coop2-ABYSS-10-boosted, the other fields, and the roster / bonds / standins / diy
  families.
2026-10-08 21:05:18 +08:00
sganggs 8d896e40ea feedback7 R22-FIELDS: the path tie-break never wades into more 深水区 than the official route — on 战场#08(下半) the patrolling 铳 / 卢西恩 take the official upper road from (3,9) to (2,3) again (GitHub #375); golden: boss-boss_2-pair, coop2-ABYSS-10-boosted
GitHub #375 (FrogThai): 「水图boss会从下面这条路往蓝门走,实际应该从上路走」. The walking leaders of 战场#08(下半) 涨潮控制
(act2autochess_m04) are 铳 (level_act1autochess_h07_02 route 6; the Hidden Core 铳 on act1autochess_h08_02's patrol
routes) and 卢西恩 (act2autochess_h07_05 route 8): PATROL_MOVE (3,9) → (2,3) → (5,9). Measured (notes repro-375.mjs):
ours 「3,9 2,9 2,6 4,6 4,4 2,4 2,3」 — the lower road through the 深水区 (3,6) / (4,6) — against the official SPFA
「3,9 5,9 5,4 2,4 2,3」 along row 5 with one 深水区 (5,6); the mirrored (3,11) → (2,17) split the same way.
Cause: grid.js _buildField takes the blockable-ground preference pointer (user playtest #2) when its route crosses
strictly fewer non-blockable tiles; 深水区 is non-blockable itself (no deployment), so the lower road counted 2 against
the upper road's 3 (two floor tiles and one water tile) and won. Official pathfinding is the plain 4-neighbour SPFA
(research 08 §3.1). Now the preference pointer is taken only when its route also crosses no more 深水区 than the official
pointer's (a per-tile `deep` count beside `cost`, start excluded). Rule from the Grok triage (scratch-i1b/375.patch),
re-implemented with a precomputed Grid.deepWater mask (terrain 'deepsea': tile_deepsea and tile_deepwater).

Scope (notes dump-fields.mjs / check-official.mjs, every stage × normal / 联防 / boss rect × every walkable
destination): 48 fields change, only on the two water maps (act2 m04 boss field; the inactive act1 m05), 149 pointers,
every one back to the official pointer. The 21 accepted DEVIATIONS (战场#01 / #02 floor, #07, the inactive #05's 7
water-avoiding routes) are unchanged, as are all 154 audited gate routes and data/stages.json's groundPaths
(tools/build-data.mjs --offline into a scratch dir: every data file identical). Other boss-field preference routes of
m04 that cross fewer 深水区 than the official one stay.

Tests: test/sim/pathing-official.test.js — two new #375 tests (the four patrol legs equal the pure official waypoints;
in a real battle the 铳 climbs to row 5 and steps on the 深水区 (5,6) only), both failing on the parent;
test/sim/pathing-crosscheck.test.js — the independent reference port gets the same 深水区 rule (it flagged both the
patrol leg and a random-crate normal-field route of act2 m04 until then); test/sim/pathing-blockable.test.js — the WALK-leg
audit compares with the equal-length routes that cross no more 深水区 than ours (the 14 accepted arena exceptions
unchanged). Grid-related suites 777/777.

Golden:
- fields boss-boss_2-pair (铳 pair on act2autochess_m04, act1autochess_h07_02): the two 铳 patrol the upper roads;
  leader left 5311560 → 5301010, p1 damage up / p2 down, deaths 0 / 2 → 1 / 3; still 8 / 8 kills.
- matches coop2-ABYSS-10-boosted (act2 m04; Final Assault 卢西恩, Hidden Core 铳): still cleared, team LP 800 → 615. The
  bots' operators stand on the lower rows (the same tiles as before); with the leaders on the upper road the Final
  Assault lasts 335 game s instead of 247 and the Hidden Core 638 instead of 190, both past the 150 real-second mark:
  the overtime drain takes 17 + 168 LP (none before), no leak.
2026-10-08 20:14:37 +08:00
sganggs f14b3a062f feedback7 R22-FIELDS: 耀骑士临光's 卡西米尔 redeploy reduction (garrison 144) has no 5 % floor — the multiplier clamps at 0 like every other redeploy multiplier, so a knock-out timer can reach 0 s (GitHub #370); golden: unchanged
GitHub #370 (FrogThai): 「耀骑士临光特性赋予身前干员减再部署有上限,最多减至5秒」. Cause: content/garrisons/battle.js
applyReader, act1autochess_gar_eff_respawnTimeByBond, wrote redeployMul = max(0.05, 1 + respawn_time × steps), so the
timer stopped at 5 % of the base time — from 192 卡西米尔 layers for 144_a (raw 0.04) and from 96 for 144_b. Measured on
a 100 s base (notes repro-370.mjs): 144_a 192 / 300 layers → 5.00 s / 5.00 s, 144_b 96 / 192 / 300 → 5.00 s each.
Official: data/garrisons.json garrison_144_a bb { divide_num 3, respawn_time −0.015 } 「每叠加3层,本干员再部署时间-1.5%」,
144_b −0.03 「-3%」 — no minimum key; PRTS 耀骑士临光 has no 卫戍 note on a minimum. Now max(0, …) as items/battle.js,
bands, the 协防 bond and svrash; deploy.js already clamps the timer at 0: 144_a 192 / 300 layers → 4.00 s / 0 s,
144_b 96 / 192 / 300 → 4.00 s / 0 s / 0 s. A 0 s timer brings the operator back on the next tick, no error (notes
probe-370-redeploy.mjs). The ASPD part (garrison 159 / 160) is untouched. Patch from the Grok triage
(scratch-i1b/370.patch), the test extended with 96 layers and the 0 s return.

Tests: test/content/garrisons_battle.test.js 26/26 — the new #370 test (144_a / 144_b at 9, 96, 192, 300 layers: the
multiplier, the knock-out timer, the 0 s return) fails on the parent.
2026-10-08 19:56:44 +08:00
CXUtk f2aec39e93 feedback7 R22-FIELDS: the Hidden Core 铳's 碎铳之簧 chase the casting gun for the whole 5 s of 末日布道 instead of stopping on arrival; each gun keeps its data timer, the later call takes the springs (PR #347 by @CXUtk, its pair stagger and lock not taken); golden: hidden-boss_9-pair, hidden-boss_9-solo, coop2-ABYSS-10-boosted
PR #347 by @CXUtk, applied with changes. Kept: 追逐模式 lasts the gain's whole 5 s — PRTS 假想敌:铳 末日布道 "令全场的
“碎铳之簧”获得5秒增益…增益期间切换为追逐模式", “碎铳之簧” 追逐模式 "持续追踪令其进入该形态的场上的假想敌:铳移动" (no
arrival clause, unlike the 铳's own 冲锋模式, which ends "到达目标所在位置后"); data skill 2: cooldown 45, initCooldown 20,
dog_duration 5, move_speed 8. kitSpring no longer ends the chase when it reaches the gun or comes within 1 tile; with no
gun left on the field the spring holds still until the gain ends (until 0.2.1 that ended the chase at once).
Not taken (the maintainer's decision on the Grok triage): the second gun's half-cooldown first-call delay and the cond
that refused a call while any spring was chasing — neither is in the data, and the lock contradicts the handbook's
「持续召唤场上所有“碎铳之簧”向自身移动」 (a call takes every spring to its caster). Both guns keep their data timers, so on a
pair field the mirrored gun's call, a tick after the first, retargets the springs for a new 5 s.

Measured (notes repro-347.mjs): a spring 0.2 tile from the gun chased 0.03 s, one 5 tiles away 2.97 s; now 5.03 s both.

Tests: test/content/hidden-gun-pursuit.test.js (new, 5; the arena harness and two tests are the PR's): the full 5 s
next to a moving gun and with no gun left fail on the parent; the pair timing (20 s after each gun's spawn, then every
45 s, the two calls a tick apart), a mid-chase call retargeting the springs for a new 5 s and the solo timing guard
against the stagger / lock. test/sim/feedback1e-healers.test.js E2 audit: the fields whose leaders / parts a healer must
block run 200 s instead of 120 — on the solo 铳 field the springs now first meet a healer at 145 s (at 21 s until now).

Golden (on top of the portal commit):
- fields hidden-boss_9-pair: the springs spend 5 s invulnerable per call, so they take less (actrpa 855522 → 722451,
  actrpb 798033 → 660498, actrpc 1384683 → 1168947) and pass less on; leader left 3511007 → 3747749; p2's deaths
  7 → 12 (longer tramples); still 8 / 8 kills, no leak.
- fields hidden-boss_9-solo: leader left 1932856 → 2011732; the springs take less; 隐德来希's candles (5601_entlec, an
  enemy-side summon) 6 → 8.
- matches coop2-ABYSS-10-boosted (hidden boss_9): still cleared at 800 LP; the seats' leader damage shifts
  (7523075 / 6369365 → 6992346 / 6900614).
2026-10-08 19:13:21 +08:00
2321Robin a87cc1e9fd feedback7 R22-FIELDS: boss-field portals teleport — a route ending on a portal entrance comes out of the far exit and leaks at that side's blue door, the four appear-less crossings reappear at the exit (GitHub #336, PR #337 by @2321Robin); golden: 8 fields, 6 matches
PR #337 by @2321Robin (GitHub #336, both with a recording of the official game), applied with small changes: the exit
distance uses detmath hypot (PR #373 bans Math.hypot in the sim), comments cite the data counts as measured here
(137 routes end on [1,3] / [1,17]; 95 explicit DISAPPEAR / APPEAR pairs, all → [5,10]), the end-teleport's zero wait
is marked [ASSUMED] beside the pairing, and the test reads the test enemy's own leaks (the templates' escorts leak too)
and checks the entrance itself is no leak.

- simdata.js portalAppear: act1autochess_h07_02 #4, act1autochess_h08_02 #5 / #9 and act2autochess_h07_05 #6 write
  DISAPPEAR → WAIT → MOVE[5,10] with no APPEAR (the level files too); the exit APPEAR is inserted before that move.
  Before, the enemy walked the rest of its route hidden and leaked unseen.
- ai.js portalPickup: a route that ends on tile_telin (the boss / Hidden Core circuits) vanishes the enemy, brings it
  out of the farthest telout ([5,10]) and walks it to the nearest blue door ([2,2] / [2,18]), where it leaks. Before,
  stepping into the corner portal was the leak. Mid-route crossings are unchanged (every MOVE onto an entrance in the
  data is followed by an explicit DISAPPEAR).

Golden — only boss / Hidden Core fields and the matches' final rounds move (no round row of any match moves):
- fields boss-boss_2-solo (铳): the 2 lrrook escorts still leak, now at the door after the portal, and take 120652
  damage instead of 66943; leader left 2761255 → 2763024.
- fields boss-boss_4-solo (昆图斯): the 2 dspred leaks now happen at the door; one more operator death (6 → 7);
  leader left 3759559 → 3759921.
- fields boss-boss_6-pair (阿利斯泰尔): the 2 hllevi_2 that leaked at the portals are killed on the way back:
  killed 4 → 6, both players perfect (1 leak each → 0); leader left 7017881 → 6972383.
- fields boss-boss_6-solo: killed 5 → 8, leaks 5 → 2 (the 3 msfshu that leaked are killed; the 2 hllevi_2 leak at the
  door); leader damage 105194 → 75209.
- fields hidden-boss_8-pair (胄): p2's one vtsk leak is gone — that vtsk is still walking to the door at the 200 s
  cap; p2 perfect.
- fields hidden-boss_8-solo: killed 3 → 8, total 13 → 19 (more sfshu die, so more msfshu split off: 3 → 9), leaks
  10 → 10; leader damage 402606 → 191576 (the escorts that come back out of [5,10] draw the fire).
- fields hidden-boss_9-pair (铳): from portalAppear alone — h08_02's routes #5 / #9 no longer count the portal hop as
  8 tiles of walking, so the targeting order of those escorts changes; leader left 3570058 → 3511007.
- fields hidden-boss_10-solo (管): the yokai_3 escort crosses back (taken 68252 → 101682), 4 more operator deaths;
  leader left 7323878 → 7323370.
- matches solo-FUNNY-2 (boss_5 Final Assault, lost at 8 rounds): pool left 94860 → 94412, kills 143 → 144.
- matches solo-NORMAL-1 (m03, hidden boss_8 胄, act1autochess_h08_01_s): the Hidden Core goes from cleared to failed
  (hiddenCleared true → false, team LP 26 → 0, roundsPassed 15 → 14, pool left 0 → 99894; victory stays true — the
  Final Assault was won). The fight is identical until 105 s, when the third vtsk escort reaches the corner portal
  [1,3]: before, it leaked there (27 → 26 LP) and the leader died at 214 s. Now it comes out of [5,10], walks through
  the team's line to the blue door [2,2] and leaks at 170 s; meanwhile only 0–2 of the 8 operators stand (2–4 before),
  the leader stalls near 120000 HP, the fight passes the 150 real-second mark (300 game s) and the overtime drain (1 LP
  per real second) plus two drone leaks at the door take the last 25 LP at 348 s with 99894 HP left.
- matches solo-HARD-1 (m03, hidden boss_8): still failed at 0 LP after 14 rounds; pool left 3046117 → 2839368, kills
  419 → 422.
- matches solo-HARD-9-boosted (hidden boss_10 管): still cleared; team LP 383 → 361 — the 管 echoes (acdums) leaked
  7 times at the portal before and once at the door now, but the longer fight pays 37 overtime LP instead of 9.
- matches coop2-ABYSS-10-boosted (hidden boss_9 铳): from portalAppear alone (the remaining-distance change above);
  still cleared at 800 LP, the two seats' leader damage shifts (6609998 / 7282442 → 7523075 / 6369365) and their
  titles swap (坚若磐石 / 卫戍之星 → 卫戍之星 / 不朽盟约).
- matches coop2-NORMAL-14-standins (boss_5 Final Assault, lost at 13 rounds): pool left 107915 → 97588.

Tests: test/sim/portal-appear.test.js (new, 9; 7 fail on the parent: the APPEAR insertion, the four real routes,
the two route-end portals).
2026-10-08 19:00:50 +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 2580152a3a feedback7: merge master (#311 — Windows CI: UTF-8 zip entry names from Windows' tar, Info-ZIP Unicode Path names in the zip reader) 2026-10-08 17:46:01 +08:00
Cloudnyco 3eced7bdba 修复:Windows 上打包和读取 zip 时中文文件名出错(master 的 Windows CI 失败) (#311)
Windows' bsdtar fallback (no zip on the Actions Windows runners) now writes UTF-8 entry names (zip:hdrcharset=UTF-8), and the update tool's zip reader also takes Info-ZIP's Unicode Path extra field for names stored in the system code page. Test and maintainer-tool change only; nothing shipped changes.
2026-10-08 17:45:45 +08:00
sganggs 8ea7a13a4e feedback7: version 0.2.2-dev — 0.2.1 is released; the dev line is marked as before (README warning under the title, an orange dev badge, the 开发版 tag on the title screen, the boot-banner warning)
- Tests: version, i18n-packs, docs-consistency, package.
2026-10-08 17:38:55 +08:00
sganggs c2a2ef778c feedback6: the 联防 down-ring render test reads 德克萨斯's redeploy time and cost from the data — at full potential 60 s and 11 (it hard-coded 70 s / 13; an opt-in RENDER_E2E suite, so the R21P stream's broad run did not reach it)
- RENDER_E2E=1 unitedown.browser 1 / 1 (failed in the 0.2.1 full pass: 54 s left at 6 s).
2026-10-07 20:04:10 +08:00
sganggs 97152828c3 feedback6: version 0.2.1 — package.json / package-lock.json / APP_VERSION (DEV_BUILD turns false: the title-screen dev tag, the boot warning and the package guard go)
- CHANGELOG 0.2.1 (2026-10-07): the streams' lines collected (新功能: the update package and MANIFEST.json; 规则(按官方):
  联防 on the round's battlefield, 突袭 onto a teammate's half, full potential, the replace dialog for consumables,
  the 外勤医疗 Touch, 凋亡, 贾维's 拉普兰德, the 频次 器物 / leader summons; 界面: the collapse arrow, 自选 picks in the bond
  lists, flyers, enemy animations, the Touch card, Esc in the 自选 picker; 联机与大厅: battle messages while a battle
  loads; 工具与开发: the update build, .gitignore), one intro paragraph.
- README: the dev warning under the title removed, the release badge, 「当前版本 0.2.1」; DESIGN's version line names
  0.2.1 (§26) as the state described; §26's intro says when the dev line shipped.
- Tests: version, docs-consistency, docs-paths, package, i18n-packs, update-package, update-boot 80 / 80.
2026-10-07 19:35:30 +08:00
sganggs 1b75bb9229 feedback6: DESIGN §26.14 (every operator at full potential, from the R21P stream's draft) and §26.15 (Esc in the 自选 picker); the §26 intro lists both and the owner's full-potential decision (no host setting)
- docs-consistency / docs-paths 31 / 31.
2026-10-07 18:55:27 +08:00
sganggs de0b830465 feedback6: merge fb6-diy-esc — Esc in the 自选 picker closes only the picker (GitHub #284 by @Xinglan233, idea from PR #286)
- Golden unchanged (UI only); broad node --test 5147 / 5147; lint 0 errors; the new browser test 1 / 1 on the branch.
2026-10-07 18:54:12 +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 10ef14817b feedback6: Esc in the 自选 picker closes only the picker, like its 取消 (GitHub #284 by @Xinglan233, idea from PR #286)
- The 干员调配 overlay's capture-phase Esc closed the whole overlay while a 自选 picker was open (it only gave way to a
  .modal; the picker is a .diy-pick section without its own key handling), so one Esc went back to the lobby.
- DiyPicker registers its own capture-phase Escape handler (calls onClose, as 取消 and the × do; skipped while a .modal
  — the 导入 dialog — is open, which handles Esc first); loadout.js returns early on Escape while a .diy-pick is open.
  The second Esc closes the overlay as before. Saved picks are untouched (the draft is dropped, as with 取消).
- test/ui/diy.e2e.test.js: a real-server browser test that needs no art (5阶 slot, then a 6阶 slot with Esc pressed in
  the search field): the picker closes, the overlay and its four slots stay, sp.pref.diy is unchanged, the next Esc
  closes the overlay. Fails on the parent (「Esc keeps the 干员调配 overlay」), passes here.
- Tests: SP_E2E=1 diy.e2e (the new test) 1 / 1; client-static, i18n, ui/diy*, ui/loadout* 369 / 369; eslint clean.
2026-10-07 18:38:20 +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 cfc149e277 feedback6: DESIGN §26.2–§26.13 assembled from the streams' drafts (联防 battlefield, 自选 picks in bond lists, consumables on a full carrier, Touch, 凋亡, 贾维, .gitignore, flyer hover, enemy animation states, runner messages, 频次 / leader summons, the collapse arrow), the §26 intro and the owner's decisions 2026-10-07 18:22:08 +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 3c36cdff48 feedback6: merge R21D — with both slots full, every consumable (博士投影, 盟约之币 …) opens the replace dialog and destroys only the picked item once its effect succeeds (PRTS 卫戍协议/帮助 「达到上限强行佩戴会改为替换装备…并销毁被指定的装备」; GitHub #263, PR #264 by @SpiritedAwayCN, ported); golden as R21D's commit (10 matches: bots using a consumable on a full operator), the merged tree differs from the branch only in R21B's 联防 scenarios 2026-10-07 18:11:53 +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 f2f4657e75 feedback6 R21E: .gitignore lists .npm-cache/ — a local npm cache (npm_config_cache=./.npm-cache, npm ci --cache .npm-cache) is never committed by any contributor (GitHub #258); test/gitignore.test.js asks git itself; golden: unchanged 2026-10-07 18:03:54 +08:00
sganggs 8cef750e14 feedback6 R21D: a consume-on-equip item on a full carrier opens the replace dialog and replaces the picked item first (GitHub #263, PR #264); golden: matches 10 of 18 moved (a targeted consumable on a full carrier now destroys the oldest item), the rest unchanged
PRTS 卫戍协议/帮助 §装备: 「达到上限强行佩戴会改为替换装备:指定一件已佩戴装备替换为将要佩戴的装备,并销毁被指定的装备」,
no exception for the 装备时销毁 items. Before: a normal 博士投影 opened no dialog and its kept item pushed the OLDEST
equipped item out (replaceUid ignored); 盟约之币 and the other consumables kept both items.

- server PlayerState.equip (player/items.js): on a full carrier the consume path takes the pick (replaceUid, else the
  oldest) off before onEquip (_takeReplaced), destroys it (onDestroy reason replace) once the effect went through —
  the normal 博士投影 takes the freed slot —, and puts it back at its index when the effect refuses (博士投影 on an elite:
  nothing destroyed)
- client gameLogic equipReplaces: the replace dialog opens for every item on a full carrier, consumables included,
  except an attaching item that completes an item merge and a 博士投影 on an elite; itemAttaches removed
- bots (itemTarget): a consumable whose effect is the same on anyone goes to a carrier with a free slot first (PR #264)
- docs: design/match.md equipment rules, META §2.5, PLAYING 装备 row, research 04

golden (matches only; each traced equip by equip against the parent — the first change of state is a bot's, or the
AI 托管 human seat's, targeted consumable on a full carrier destroying its oldest item): solo-FUNNY-1 (r9 ai_0 随身身份牌),
solo-FUNNY-2 (r9 ai_0 寻呼模块), solo-HARD-2 (r9 ai_0 随身身份牌, r12 简易通讯机), coop2-NORMAL-3 (r9 ai_1 随身身份牌),
coop3-ABYSS-5 (r11 ai_1 随身身份牌), coop4-FUNNY-6 (r4 ai_1 随身身份牌), solo-HARD-9-boosted (r14 ai_0 随身身份牌),
coop2-ABYSS-10-boosted (r13 ai_0 随身身份牌, r14 ai_1 简易通讯机), coop2-NORMAL-14-standins (r9 ai_0 随身身份牌; now won,
14 rounds), coop2-NORMAL-70-diy (r14 h_0 随身身份牌); the bots' free-slot carrier for target-agnostic consumables moves
no scenario by itself; roster / bonds / fields / standins / diy unchanged
2026-10-07 18:03:53 +08:00
sganggs 1e58843fb4 feedback6: merge R21F — enemy flyers hover 1.3 tiles above the road instead of climbing each raised tile (GitHub #277, @FrogThai); enemy animation states from PR #275 by @xcdoge, client part: numbered skill clips, the Stun_1 / Dizzy_* spellings, run cycles (猎狗pro, 深池侦察犬), the rebirths of 巨大的丑东西 and 自在 (data/assets.json regenerated offline: enemies only); golden unchanged 2026-10-07 18:03:47 +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 76a2db7dd0 feedback6 R21F: enemy animation states, the client part of PR #275 by @xcdoge re-implemented — the resolver gives an enemy every numbered skill clip (anims.skills; the caller's first index stays the primary, operators unchanged, 宴's PREFAB_SPINE_ROLES fix kept), the stun spellings Stun_1 and Dizzy_Begin/Loop/End, a separate run role (Run_Begin/Loop/End); the renderer walks an enemy faster than moveSpeed 1 on its Run cycle (猎狗pro, 深池侦察犬 ×2; [ASSUMED] threshold), swaps an enemy's skill clip on a cast event (UnitView.setSkillSlot; a form in force is kept), and plays the 重生 of 巨大的丑东西 (Revive, then the fleeing 大祭司 Idle_2 / Move_2 / Stun_2) and 自在 (Revive_01); data/assets.json regenerated offline: 18 enemies gain anims.skills, 6 anims.run, 3 a stun clip (巨大的丑东西, 斩胄之剑, 破胄之锤), nothing else; the sim's cast slot (a new event) is not part of it; golden: unchanged 2026-10-07 17:59:11 +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 53ccf5d8fe feedback6: merge R21G — battle control messages that arrive while the sim loads or catches up (takeover, forced end, a duplicate start, pool, pause) are held and applied in order (PR #266 by @siruimei07, ported); golden unchanged 2026-10-07 17:57:18 +08:00
sganggs d0d59f4012 feedback6: merge R21C — the player's 自选 picks are listed in their bonds' member lists (dimmed until owned, ✕ when banned; a watched teammate's 自选 row opens its operator); golden unchanged 2026-10-07 17:55:35 +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 d84b961c80 feedback6 R21G: a b.start is registered as pending before the sim loads, so a b.end (takeover / forced, the first end counts), a second b.start of the same battle, b.pool and the solo pause that arrive during the load or the silent catch-up are applied to it in order once the Battle exists (they were dropped); a superseded authority is still built, the next prep's clear stops the preparation (PR #266 by @siruimei07, re-implemented on the current runner); docs/design/network.md §14 Client runner + b.end; golden: unchanged 2026-10-07 17:51:26 +08:00
sganggs 14df10a5a3 feedback6 R21F: an enemy flyer hovers FLY_HOVER above the road whatever tile it crosses (GitHub #277: one high-ground / forbidden block on its way lifted it 0.42 / 0.3 tiles and dropped it again like a step) — UnitView.sync keeps every enemy at z 0, operators and summons keep their tile top, the flyer's shadow lies on the tile under it (shadowZ) on the 2D and the 3D board; golden: unchanged 2026-10-07 17:49:51 +08:00
sganggs 41fd3c7e39 feedback6 R21C: the bond popup lists every 自选 pick of the player (m.private.diy, the V and VI slots) in each bond its operator carries — dimmed like an unowned member until a copy is owned (not bought, or not in the shop yet), ✕ like a banned member when all its bonds are off this match (m.private.diyBanned), one row per slot drawn as its normal form with the 「自选」 tag, a tap opening the operator's card; 在场 and the 成员 header count an unowned pick for nothing, the order rule is kept (the owner's report of 2026-10-07 「自选编队的干员在局内对应盟约展开的名单里没有显示出来」); a watched teammate's popup still lists only their 自选 pieces on the field (m.public sends no picks), and such a row now hands the unit's pick to the card (BondPopup onMember → the detail target's diy → resolveDetail) instead of opening the empty 甄选干员 slot's card; golden: unchanged (client) 2026-10-07 17:43:37 +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 0983e780e8 feedback6: the bond strip's collapse button is a bare half-transparent arrow (‹ / ›) instead of the boxed 「收起」 / 「盟约」 tab — the owner's request after 0.2.0; full opacity on hover / focus, the 44 × 44 touch target and the aria-label kept (test/ui/bond-collapse.e2e.test.js 2/2) 2026-10-07 17:37:45 +08:00
sganggs 783bd30afd feedback6: merge R21A — 突袭 may land on a teammate's half when both halves are occupied (two-helper 联防, Final Assault / Hidden Core pair; the owner's decision of 2026-10-07), Battle.onFieldBoard; DESIGN §26 / §26.1 (docs/history/0.2.1.md); golden as R21A's commit (boss-boss_2/3/4/5/6-pair, hidden-boss_8/10-pair, coop4-ABYSS-7) 2026-10-07 17:14:51 +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 ac6de8a12d feedback6: the i18n template test reads the app range from APP_VERSION like tools/i18n.mjs appRange (it hard-coded >=0.2.0; 0.2.1-dev writes >=0.2.1) 2026-10-07 16:51:35 +08:00
sganggs ee43fb7c14 feedback6: merge fb5-patch-pkg — from 0.2.1 on every release also ships an update zip (only the files changed since the earlier 0.2.x releases; the server checks the install against MANIFEST.json and deletes the files the new version dropped on its first start; manual download, no auto-update — the owner's decision of 2026-10-07); README English summary: both the update-zip sentence and the Languages line kept 2026-10-07 16:47:27 +08:00
sganggs 40cfe2d3d3 feedback6: version 0.2.1-dev — 0.2.0 is released; the dev line is marked as before (README warning under the title, an orange dev badge, the 开发版 tag on the title screen, the boot-banner warning, the package guard: DEV_BUILD from the version) 2026-10-07 16:45:46 +08:00
sganggs 1303321407 feedback5: two render tests took 宴's S2 (index 1) from the real manifest as their "skill without an idle clip" — that was the kneeling clip of §25.22.9; they now use her S1 分神 (index 0, the same clips) and check that her S2 plays no skill clip 2026-10-07 14:43:29 +08:00
sganggs aa5502c364 feedback5: §25.22 intro — one sentence's punctuation 2026-10-07 14:32:40 +08:00
sganggs 1ca769ba16 feedback5: 阿戈尔's devour block count checked for 水月 (伏击客, base block 0) and converted members (community report of 2026-10-07) — not reproduced: he takes every marked unit's block and blocks with it, the prep card shows it; face to face the second member marks nothing back (PRTS 「不会向…“已将标记付与自身的单位”付与自身标记」); pin tests test/content/feedback5-egir-block.test.js, CHANGELOG 核实后不是问题, §25.22.10; golden unchanged (tests and docs) 2026-10-07 14:32:29 +08:00
sganggs caee1dbed9 feedback5: 宴 stands during 落地斩·破门 — her one unnumbered skill set (Skill_Start / Loop / End) is S1 分神's sit-down rest, and the by-name resolver gave it to S2 too, so she knelt through the opening seconds of every battle (the owner's playtest of 2026-10-07); tools/assets/spine.mjs PREFAB_SPINE_ROLES now also fixes operator models by character id (front and back): 宴's S2 plays her ordinary clips (via 'attack'), S1 keeps the rest; data/assets.json rebuilt offline (only her entries changed); test/feedback5-utage-anims.test.js; CHANGELOG 界面, §25.22.9; golden unchanged (client art only) 2026-10-07 13:28:12 +08:00
sganggs f24d2a9016 feedback5: DESIGN §25.22 covers the community reports too (header, intro, 25.22.1–8 in order), §25.23 the Japanese, Korean and Traditional Chinese interfaces, the §25 intro list and decisions of 2026-10-07 2026-10-07 13:09:23 +08:00
sganggs b942ff2e71 feedback5: the boss-field browser test survives the bots' re-draft — its game-time safety net 600 → 1200 s (the Hidden Core b1 board clears at ~511 s, its 催泪瓦斯 copy at ~619 s since GitHub #232 re-drafted seed 22's earlier rounds) and the 奥术 check also counts the heavy-hitter copy (洛洛 + 深靛 = 奥术 2; the bots stopped drafting it); every other check unchanged; golden unchanged (test only) 2026-10-07 13:08:44 +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