Commit Graph
34 Commits
Author SHA1 Message Date
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 463352d9bc feedback5 WY: 拟态物质 with 2 copies owned and none left in the pool gives nothing instead of a random same-bond operator (GitHub #207)
The item text 「若已拥有至少2名该初始干员,则再获得1名该初始干员;否则随机获得1名同盟约初始干员」: the 否则 is the
case of fewer than 2 owned. builtinMeta's use_equip_reward_char_chess returned only when grantChess(base) gave a piece,
so an elite 溯光星源 plus 2 normal copies (all 5 Ⅵ阶 copies) fell through to the same-bond roll (白面鸮 in the report's
seed). Now with 2 owned it asks for the 3rd and stops; the item is still consumed. The bots' carrier choice
(itemTarget) skips 2 copies whose pool is out.

Tests: test/content/items.test.js (the report with the normal and golden item; 2 copies with the pool drained; 2 copies
with copies left still merge), test/match/bot-smarter.test.js (no carrier on a pair whose pool is out); both fail
without the fix. Docs: META built-ins and bot items, research 04 / 06, DESIGN §25.13.1.
Golden unchanged.
2026-10-06 20:55:49 +08:00
sganggs 2eaef154d5 feedback5 WE2: AI 托管 buys the player's own 自选 pieces more readily and levels toward them a round earlier (#13)
bot.js: the player's own slotted piece scores DIY_PIECE_BONUS (12) more; levelUp takes the
step that opens a slotted tier with copies left one round earlier (diyOpensAt). Bots field
no 自选 piece. Exports buyScoreOf / levelUp / diyOpensAt for the tests. Docs: DESIGN §6.6,
PLAYING. Golden: coop2-NORMAL-70-diy moved — the 自选 seat under AI 托管 reaches level 6 one
round earlier and fields its tier-6 Sharp at round 12.
2026-10-06 15:54:07 +08:00
sganggs 53ee0a1c6f feedback5 WE2: 重构体 only on the ground inside Mon3tr's range, 战术锚点 only on a 高台 outside 凯尔希·思衡托's (#26)
Mon3tr T1 "可以在攻击范围内的地面使用…重构体"; PRTS 战术锚点 特性 "仅可以部署在凯尔希·思衡托攻击
范围外的远程位". tools/build-data.mjs summonRecord: ownerRange also from an owner talent
naming the token, ownerRangeOutside / rangedTilesOnly from the token text. Regenerated
offline: 3 paths (重构体 ownerRange true; 战术锚点 ownerRangeOutside, rangedTilesOnly).
Match: board.js placement class 'high'; PlayerState.summonExcluded in _legal, the
re-orientation lift (+ toast), _roomForOutOfRange, the invariants and the bot; the
client mirror (piecePosition HIGH, summonExcluded, reasons; English strings added).
Golden: no scenario moved.
2026-10-06 15:34:20 +08:00
sganggs 9ce5435373 feedback5: merge W5M — the nine 0.1.4 PRs (#150 #66 #146 #74 #72 #103 #149 #109 #160) and W4A (高台 per the trait, 阿戈尔 revive slots, 联防 devour) ported into the split layout
Conflicts: server/match/bot.js (W4A's comment + W5K's player data view pgd), test/golden/diy.json (regenerated). data/ equals an offline build of the merged tools/build-data.mjs. Golden regenerated on the merged code: against feedback5 the moved roster / bonds / fields / matches / standins scenarios are exactly W5M's per-PR attribution (#160 skill events, #109 deploy-timed lifecycle, #66 灵巧 sources and hidden layers, 83fc408 歌蕾蒂娅 placement), plus coop2-NORMAL-70-diy (fields operators those PRs touch) and diy-051 / diy-052 (events.skill only: Misery's deploy passives, #160); against fb5-merge4 only feedback5's own additions (the diy kits, coop2-NORMAL-70-diy).
2026-10-06 00:33:15 +08:00
sganggs c5c52eed34 feedback5 WM: merge feedback4 at 13808e3 (W4A) — 高台 for every 「可以放置于远程位」 trait holder, the 5-阿戈尔 revive slots, the 联防 devour of whoever stands in front
Ported by hand into the split layout:
- 83fc408 board.js placeClass: the player's loadout no longer counts, as in 83fc408. feedback5's 补位 rule stays: a
  chess the player fields as its stand-in is placed by the stand-in's record (ps.fieldRecord). positionClass(rec)
  takes no module.
- 83fc408 client piecePosition → public/js/ui/gameLogic/placement.js: meleeOnHighGround(rec) on the stand-in or
  chess record, no module. The gameLogic.js shim header and deployedModuleId's comment follow; deployedModuleId is
  kept, still exported and tested.
- 83fc408 PlayerState._placementOf comment → server/match/player/placement.js.
- 83fc408 tools/golden.mjs layout: positionClass without the module, on feedback5's stand-in body (recOf) and in
  diyLayout.
- bonds/core.js (6ab9a06, 8a2e0c7) applied cleanly; it equals 13808e3's plus feedback5's i18n toast. shared/highGround.js
  equals 13808e3's.
- data/: only bonds.json (the 阿戈尔 spec text). node tools/build-data.mjs --offline on the merged tree rewrites all
  15 files byte-identical.

Golden regenerated: 16 scenarios moved, all by 83fc408. Each fields 歌蕾蒂娅 (normal, or elite with HOK-X / no
module), whom tools/golden.mjs now lays out beside the enemy path like a ranged operator instead of on the busiest
melee tile: roster-010, roster-012, roster-029, roster-040, roster-041; bond-deputShip-high, bond-indomShip-low,
bond-preciShip-low, bond-preciShip-high, bond-suntShip-low, bond-swiftShip-high; boss-boss_2-pair, boss-boss_4-pair,
boss-boss_6-pair, hidden-boss_8-pair, hidden-boss_10-pair. This is the list in 83fc408's own message. With the
阿戈尔 commits reverted the digests are the same, so those two move nothing in this corpus. The standins, diy and
matches families are unchanged: no stand-in or 自选 piece there is 歌蕾蒂娅, 崖心 or 见行者.
2026-10-06 00:06:41 +08:00
sganggs 4bee542e61 feedback5 WK: 自选编队 on the server — room.diy { picks } (lenient: illegal picks dropped, only malformed input is BAD_MSG; stored per session / seat; a match takes the picks its seat had at the start, a change during a match is for the next one; welcome lists diyKitted), PlayerState.diy with the player's data view (a slotted DIY slot is its operator for every rule: bonds from its factions, no 特质, the pick's skill and module, the slot's tier / price / merge), a per-player stock per slotted piece (8 at tier 5, 5 at tier 6 [ASSUMED]; never in the shared pool; none when every bond of it is banned), DIY pieces in that player's shop rolls and reward offers once the 调度中心 reaches the slot's level, battleInput diy, m.private.diy / diyBanned, prep scouting and results name the operator, 信标 never sends a 自选 piece to a teammate [ASSUMED]
The owner's decisions of 2026-10-05 (picks, slots, shop per player, bans); research 0.2.0 §2. Golden unchanged (no scenario slots a DIY pick).
Tests: test/match/diy-shop.test.js (9), test/lobby-diy.test.js (4).
2026-10-05 23:35:01 +08:00
sganggs 83fc408a55 feedback4: every melee chess whose trait reads 可以放置于远程位 may stand on a 高台, normal or elite, any module
The owner's decision of 2026-10-05 reverses the one of 2026-10-04 (elite 歌蕾蒂娅 with HOK-Y only) and follows PRTS:
the line is the 钩索师 / 推击手 branch trait (歌蕾蒂娅, 崖心, 见行者, normal and elite) and every module keeps it, so
the loadout no longer matters. Raised with the PRTS source in PR #69 by @sunstricken (its own change covered only
歌蕾蒂娅; its test page is not taken). GitHub #153.

- shared/highGround.js: meleeOnHighGround(rec) reads the trait without a module (traitBase, else trait); no module id.
- board.js positionClass(rec) widens those six records; placeClass(ps, rec) = positionClass(rec) for every server
  check (g.move, swaps, merge tile, evictions, audit, invariants). The client's piecePosition mirrors it.
- bot.js: the existing 高台 preference (a 高台 whose range covers the road) now applies to all six; comments.
- Docs: DESIGN §3 and §6.6, DATA (placement), PLAYING §4, META, research 03 C2, code comments. data/ unchanged
  (build-data --offline gives identical files).
- Tests: board, feedback1-placement (each holder with default / no module / every module on each 高台, a 重装
  refused, client highlights, swap, battle, bots), gameLogic.

Golden: 16 scenarios moved, every one because tools/golden.mjs lays operators out by positionClass and now places
歌蕾蒂娅 (normal, or elite with HOK-X) beside the enemy path like a ranged operator instead of on the busiest melee
tile, which shifts the others: roster-010, roster-012, roster-029, roster-040, roster-041; bond-deputShip-high,
bond-indomShip-low, bond-preciShip-low, bond-preciShip-high, bond-suntShip-low, bond-swiftShip-high; boss-boss_2-pair,
boss-boss_4-pair, boss-boss_6-pair, hidden-boss_8-pair, hidden-boss_10-pair. roster-031 (elite with HOK-Y, already
widened) and all matches are unchanged.
2026-10-05 23:20:56 +08:00
sganggs 24205581e1 feedback5 WG: 补位 on the server — room.ownership { notOwned } (lenient check, stored per session / seat, a match takes the list its seat had at the start), PlayerState.standIns: the player's not-owned NORMAL chess fight as their stand-ins (battleInput standIn: true in every field, the stand-in's position / range, no summons), m.private.standIns, stand-in art in prep scouting 2026-10-05 19:13:46 +08:00
sganggs db1b44bb71 feedback5 WE: the 整备区 rules of PRTS 卫戍协议/帮助 §手牌区 (GitHub #82, second part) — a full regular hand refuses every purchase and reward pick, also one whose copy would complete a merge at once ("当常规手牌区全满无空位时,玩家将无法执行使手牌溢出的操作" — "例如招募/购入等通常情况下会增加手牌的操作"; BWIKI 盟约 says the same with no exception; the reporter checked it in the official game), and a free regular slot pulls the 临时整备区 in at once ("常规手牌区出现空位时自动移入"): PlayerState._fillHandFromTemp runs in every recompute, the temp row right to left (the order it fills, [ASSUMED]) into the hand's free slots right to left — after a sale, a deployment from the hand, a merge that consumed hand copies, an item equipped / destroyed / used, a summon stack removed with its owner. invariants.js: temp holds pieces only while the hand is full. The client's refusal path follows (gameLogic.shopBlockReason: 整备区已满 on every card — a one-line change in a file the R5 split moves). Bots: a full hand never tries a purchase, an affordable third copy of a held pair sheds the weakest hand single first (never one of this prep), resolveTemp decides temp right to left. Tests: test/match/feedback5-hand.test.js; merge / hardening / playtest6-elite-to-board / economy / prep-bench / uiFixes updated to the rule. Docs: META §1 Hand, DESIGN §6, PLAYING §3, research 00-INDEX / 01 (the old "a merge-completing purchase is allowed" corrected). Golden: 3 match scenarios moved (coop2-NORMAL-3, solo-HARD-9-boosted, coop2-ABYSS-10-boosted — bot seats that reached a full hand: the merge-completing purchase refused or a single shed first, temp pieces moving in by themselves); every battle digest unchanged 2026-10-05 18:17:08 +08:00
sganggs 7e711582b0 feedback3 WJ: the bot places elite 歌蕾蒂娅 with HOK-Y on a 高台 that covers the road 2026-10-04 21:11:41 +08:00
sganggs 5ef4fac137 feedback3 WJ: 高台 only for elite 歌蕾蒂娅 with HOK-Y
The trait line is on every hookmaster and is not trusted. Placement is the loadout at place time: golden 歌蕾蒂娅 carrying uniequip_003_glady may use a ranged tile; everyone else stays on the ground.
2026-10-04 20:31:46 +08:00
sganggs 9d15538865 feedback2 WF: 钩索师 and 推击手 (歌蕾蒂娅, 崖心, 见行者) may stand on a 高台 — chess.json placement 'all' from the branch trait 可以放置于远程位; server, client highlights; bots keep them on the ground as blockers 2026-10-03 23:03:26 +08:00
sganggs 77eaeaa15f feedback1 final: merge the 突变细胞 bench rule (carrier destroyed, tile freed, the new operator gained into the 整备区; pointed out in PR #2)
Conflicts resolved keeping both sides:
- effectsMeta.js header: the QA residual's "every [holder, item] pair, taken before the first item runs" and "an item
  moved during it runs at most once", with the cell branch's wording of what 突变细胞 does mid-walk.
- DESIGN §6.6: the band pick that skips a strategy tied to a switched-off bond and the deployment of the operator a
  transformation gains / the bench shed that spares it.
- DESIGN §21.25: PR #2's bench rule credited (the cell branch) plus the QA residual's snapshot-timing sentence.
- PLAYING: the new 突变细胞 sentence with the residual's hammer sentence (revives, borrowed hammers, the lend window).
- docs-consistency: both new tests (batch 6 QA residuals; 突变细胞 after the WA merge).
2026-10-03 18:48:30 +08:00
sganggs 1f29b8a3d0 feedback1 gaps: bands.json bondIds is built once and read by the bot
The band -> bond derivation moves out of GameData into shared/bandBonds.js,
which tools/build-data.mjs runs per band to write bands.json bondIds
(regenerated with --offline; 9 bands are tied, the build checks the ids).
GameData.bandBondIds reads the field, so the server and the client share
one source. DATA.md documents the field; the test checks the helper on
synthetic bands and that the data matches it.
2026-10-03 15:56:33 +08:00
sganggs 3dcbcd572b feedback1 cell: bots let their placement step judge the operator a 突变细胞 transformation gained
With the bench rule the gained operator starts the next prep on the bench while its carrier's deployment
is free. The buy loop's pre-emptive bench shed sells the weakest bench single by piece value while the
bench is crowded, before the placement step runs: in 20 solo 绝境 matches on 昆图斯 it sold 44 of 222
gained operators that way.

- bot.js: botPrepEndSteps remembers the chess owned when the prep ends (rememberOwned); the shed's
  keepFresh now also spares a piece gained since then (a transformation's operator, battle-result /
  round-start grants), so the lineup step decides about it. No memory yet (a first prep, a seat just
  put under AI 托管) changes nothing.
- botbench, decisions only: 昆图斯 (seeds 201-220) 绝境 7 -> 11 / 20 wins with the fix (8 on the WA
  build), 险境 16 -> 17 / 20 (15); the bots' own strategies unchanged within noise (solo 绝境 8 / 12 both,
  solo 险境 19 / 24 both, co-op 绝境 4 AI 9 -> 8 / 36).
- Test: a real solo 绝境 昆图斯 bot match (seed 9 sold its R7 operator in the R8 prep before the fix):
  no gained operator shed in its first prep, none waiting on the bench beside a free deployment.
- DESIGN §21.1 / §21.6 / §6.6, META and the CHANGELOG line say so.
2026-10-03 15:47:51 +08:00
sganggs 91c9b21d7f feedback1 cell: a 突变细胞 transformation gains the new operator into the 整备区 and frees the carrier's tile (pointed out in PR #2)
Official gameplay footage (bilibili BV1vzyVBuEN9 at about 8:24, BV1Qkw1zMEoR at about 7:25) shows the
next prep with the carrier's tile empty, one more deployment left, and the returned equipment plus the
new tier+1 operator on the bench, deployed by hand afterwards. That is the PRTS 备注 read as written
("生效时,原干员销毁,获得一名高一阶的随机初始干员"): a destroy followed by a gain. The closed PR #2 made
the same claim from a playtest.

- PlayerState.transformChess: the carrier is destroyed wherever it stands (board tile freed, summons
  removed, copies back to the pool); its equipment, the cell included, returns to the hand first
  (overflow temp, auto-merge); then the new operator is gained through acquireChess like any gained
  operator (hand, overflow temp, the no-room rule of every gain; no summon card until it is deployed).
  The returnItems option is gone (the cell's built-in was its only caller).
- A merge the gain completes merges like any gained copy: the elite takes a consumed deployed copy's
  tile, else the hand. _mergeChess loses fromKey / fromDir, so the destroyed carrier's tile never
  counts (PR #2 had kept that path; not adopted); audit.js drops its exception for it.
- builtinMeta, ctx.transform, items/meta.js and bot.js comments follow. Bots and AI 托管 deploy the
  gained operator in their normal lineup step (no bot change needed; a real co-op round pins it).
- ITEM_RULES note and implFormula for the item card; data/items.json rebuilt with build-data --offline.
- Tests: facing, merge, playtest6-elite-to-board and items no longer pin the kept tile; feedback1-meta
  covers a deployed and a bench carrier, hand full -> temp, hand and temp full, a merge with and
  without a deployed copy (never the carrier's tile), 商业包装方案's count on the returned item, and bots /
  AI 托管 redeploying; feedback1-cell checks the new note.
2026-10-03 15:18:42 +08:00
sganggs 481b76027d feedback1 gaps: bots skip strategies built around a bond the mode switches off
GameData.bandBondIds reads a band's tie from its own data: the bond names
in <...> of its text (the official note naming the bond among them) and
the bond ids / bond pools of its blackboards (choices.json pools[pool].bond
for pool_char_later). botPickBand weighs a band tied to a bond in
modeInactiveBonds 0, keeps one rng draw per pick and falls back to the
default band when every offered band is excluded. In 标准 潘格尼尼,
克莱门莎 and 玛恩纳 are no longer picked (seeds 1-200: 5/200 solo and
23/800 co-op before, 0 after); the other modes keep the same picks.
2026-10-03 15:07:05 +08:00
sganggs a80b163aed feedback1 integrate: the bot's bench shed never sells a piece of this prep
The buy loop's pre-emptive shed sold the single it had just bought back for 1 (the buy picks
by lineup gain, the shed by piece value). Same-prep buy then sell in co-op 绝境 seeds 21-26:
29 -> 3. Seeds 1-40: solo 绝境 22 -> 24 wins, co-op 9 -> 10 on the 22-match bounty lists;
decision time unchanged.
2026-10-03 11:52:52 +08:00
sganggs ff4ff3f350 feedback1 integrate: bot reconciled with the merged rules
- plans each unit with the range it is deployed with (loadoutRecord attackRangeGrid, the grid of the server's
  summonRange and the card)
- an attack on every enemy in range (阵法术师 / 轰击术师 rangeAoe) counts double in its DPS value, splash and chain a little
- botbench seeds 1-40 before/after and the decision time (unchanged) in BALANCE.md
2026-10-03 08:09:29 +08:00
sganggs 0a15c6e41d feedback1 integrate: ticker lines by broadcast priority; AI 托管 keeps a human's items out of temp
- the strip queues by the official broadcast priority (BOSS_HIT 30 > CHAR_DAMAGE 20 > SHOP_LEVEL 11 > ...),
  match-flow notices at 25, never cutting the line on screen short
- on a human seat under AI 托管 an item left in temp with a full hand gets a hand slot (a bench operator sold)
2026-10-03 07:57:28 +08:00
sganggs 88d419b095 feedback1 integrate: WF smarter bots (same decision time)
# Conflicts:
#	docs/META.md
#	server/match/bot.js
2026-10-03 07:07:23 +08:00
sganggs b1644f5ad7 feedback1 integrate: WC 深水区 refuses deployment; tactical points only inside the summoner's attack range
# Conflicts:
#	server/match/bot.js
2026-10-03 06:35:09 +08:00
sganggs 774c59c1d4 feedback1 WF: a bench chess carrying a Mutation Cell is not sold before its transformation 2026-10-03 03:32:53 +08:00
sganggs f4e55a7e29 feedback1 WF: review fixes — golden 博士投影 and 突变细胞 carriers, bounty Arts kept, 坎诺特 banks its capital, teammates' bonds from their bond strips, server summon range, tighter cost guard 2026-10-03 03:30:02 +08:00
sganggs 3f104168fe feedback1 WF: bot A/B numbers in BALANCE.md; guard a record lookup in the buy loop 2026-10-03 02:46:20 +08:00
sganggs 85d8bd40b4 feedback1 WA: return the Mutation Cell before summon cards; bots keep it
Review follow-ups for reports #1 and #4.

- transformChess: the returned equipment is stowed before the new operator's
  summon stack is granted (as in _mergeChess); when the transformation
  completes a merge, the carrier's equipment goes through _mergeChess, which
  also returns it before the elite's summons. A summon card no longer pushes
  the returned 突变细胞 into temp, where it would be lost at the deadline.
- bot: a 突变细胞 left in temp with a full hand gets a hand slot (sell the
  weakest single hand chess, else destroy the cheapest other hand item, else
  sell any hand chess) instead of being destroyed.
- 拉普兰德's per-piece counter key is module-prefixed; the re-bought copy
  case is marked [ASSUMED] in the code and docs/META.md.
- .dhint--rule gets a style; sources quote PRTS 卫戍协议/帮助 exactly
  ("在失去该干员(干员出售、销毁、合并等)…时自动卸除").
2026-10-03 02:28:39 +08:00
sganggs 7f20776b9e feedback1 WF: smarter AI players (merge hunting, bond plan, bounty threat model, item carriers, armour-aware DPS, tactician points) 2026-10-03 02:15:31 +08:00
sganggs c92867656d feedback1 WC: no deployment in the water, tactical points inside the tactician's range
Player reports #3 and #9 after the 0.1.0 release.

#3 On 战场#08(下半) 涨潮控制 (act2autochess_m04) operators could be placed in the
pool and 突袭 members jumped into it. The 深水区 (tile_deepsea) has buildableType
ALL in the level file, but it refuses deployment (PRTS 地形 深水区 "地形机制:拒绝
部署"; the season-1 战场#05 puts a 特制水上平台 - "在水上建立可以部署任意单位的
平台" - on every one of its water tiles).
- grid.js DEPLOY_REFUSED_TILES: the legend's effective build is NONE, so
  canStand (突袭 landing tile, tactical points, summon tiles) never picks the
  water; a hard-blocked 射击台 / mound tile takes no melee unit either.
- build-data: stages.json legend `buildable` is the effective type (the level's
  value kept in `buildableType`), deployTiles exclude the water, a 特制水上平台
  makes its tile deployable (act1 m05, inactive). board.js / gameLogic.js
  deploy maps follow (water platforms included); bots plan on the same map.
- Gate routes are unchanged; the water now counts as non-blockable ground in
  the path tie-break (audit lists updated).

#9 伺夜's 狼群 and 缪尔赛思's 流形 ("只能部署在召唤者攻击范围内", tokens.json
`ownerRange`) could be placed anywhere.
- PlayerState._legal / summonRange: a range-bound summon only on a tile of its
  owner's attack range (loadout grid rotated by the owner's facing); swaps with
  the owner are checked from the owner's new tile; re-orienting (or promoting)
  the owner sends a summon left outside back onto its stack with a toast.
- The client lights and accepts the same tiles (gameLogic.summonRange), the bot
  plans inside them, the invariants check it, the 伺夜 kit re-uses the piece's
  tile only inside her range.

Tests: test/match/feedback1-placement, test/sim/feedback1-water, the opt-in
headless-Chrome test/ui/feedback1-placement.e2e (fastServer hook SP_STAGE);
existing summon / deploy / pathing tests moved off the water tiles.
2026-10-03 02:01:34 +08:00
sganggs f8e35d5055 feedback1 WA: Lappland counts her own first refresh; Mutation Cell is not consumed
Player reports after 0.1.0, #1 and #4.

#1 拉普兰德 (garrison_123, SERVER_GAIN_BOND_LAYER_BY_REFRESH_CNT) checked the
player's refresh count of the round, so a copy bought after the round's first
manual refresh never stacked that round. Players report the official
behaviour: the first refresh after acquiring her also stacks. Each copy now
counts the manual refreshes it witnessed this round (board or hand) through a
per-piece round counter (PlayerState.pieceRoundCount, ctx.incPieceCounter); an
elite merged this round keeps the highest count of its copies [ASSUMED]. The
"本回合每刷新过1次" multiplier traits keep the player's count.

#4 突变细胞 destroyed itself after one transformation. Official text never
says 销毁 (every consumable's does), PRTS notes "原干员销毁,获得一名高一阶的随机
初始干员", and players re-inject the cell every round. The built-in now replaces
the carrier with a random normal operator one tier higher (max 6) and returns
the carrier's equipment, the cell included, to the hand
(transformChess returnItems); the content override is gone. The item card
shows the rule (items.json note, build-data ITEM_RULES); bots inject their
least valuable single normal operator below tier 6 (bot.js cellTarget).
2026-10-03 01:47:52 +08:00
sganggs 620f88c0d8 Playtest #6 follow-up (v2.5.1): leader HP review — 直接乘算, one debuff instance, 999 layer cap, 限伤; elite to the board; 假想敌:胄 kit
- co-op leaders died within seconds: leader HP is the official data (40 values pinned); bond / strategy / item /
  机变 / 特质 "+X%" bonuses now add up (PRTS 直接乘算) instead of compounding; a same-named enemy debuff keeps one
  (strongest) instance per target (奥术 across a pair field); leader parts pass damage 1:1; fixed co-op pool (the user's call)
- official limits read from the client: each bond stops at 999 layers (MAX_GARRISON_STACK); a leader hit of 300000+ in
  boss / hidden battles is cancelled (MAX_BATTLE_DAMAGE, 限伤) — shared/constants.js switches, research 11
- a merge that consumes a deployed copy puts the elite on that tile and facing (user-confirmed); gold target highlight,
  promotion effect
- 假想敌:胄 per PRTS: one shell, shells within range, any drone death costs 2 % max HP, 剑/锤 sorties and 瘫痪
- DESIGN §20.10–§20.14; 2842 unit tests, all 28 browser suites green; Chrome = Node on boss fields
2026-10-02 04:19:28 +08:00
sganggs 6464e4b46a Playtest #6 fixes: summons placed by hand, boss pool stall, bounties, 联防 leak counter, distinct offers, 机变 card text, phone buy tap, skill triggers, blocking, push force, 孤立, enemies, element bar
- #1 #2 skill / device summons (赫默's drone, 巫恋's doll, 凯瑟琳's devices) are hand cards placed by the player;
  placed summons deploy once at battle start, then a skill summon re-appears at its tile on each cast (the user's call)
- #3 叙拉古 隐匿 ends on time (32 + 0.4 × layers s); 忍冬 S3 迷彩 lasts until her next cast (official), kept apart from 隐匿
- #4 multi-round bounty cards last two battles (the user's call; MULTI_ROUND_BOUNTY_BATTLES), blue / red card text
- #5 the shared boss pool's float dust (≈3.6e-12 HP) stalled Final Assault leaders at 0 %; < 1 HP now clears the pool,
  and the team LP reaching 0 first is a defeat (PRTS)
- #6 #10 机变 cards show their official effect text; an invisible 详情 button no longer swallows the confirming tap on phones
- #7 live ×N counter of a leaker's enemies still on the 联防 field (LP loss stays capped at 10)
- #8 #15 #16 skill triggers per 技能策略: skill-range triggers, injured-ally heals (古米, 塞雷娅), tank take-damage
  triggers with a 3 s cooldown; 新约能天使 S2 shields the highest-aggro operator in range
- #9 official per-enemy model scales (威龙)
- #11 element bar under the unit's HP bar (white = 元素值 left, element-coloured refill after a burst), floor rounding
- #12 枯朽战车 kit per PRTS; every ranged enemy reaches its target's 0.25 collider
- #13 恐惧 wander (萨科塔之翼 at half HP, operator fears make enemies flee) with re-planning after pushes
- #14 push / pull distance by 力度 − 重量 (PRTS table); #17 every blocker attacks what it blocks; ASPD floor 20
- #18 炎佑 is 孤立: no heals or ally buffs
- #19 every free pick-one chess offer (promotion reward, 信标, 寻呼模块) shows different operators
- DESIGN §20 and the normative lines, SIM / META / DATA / PLAYING updated; 2747 unit tests and all 27 browser suites
  green; dev recordings regenerated
2026-10-01 19:08:23 +08:00
sganggs 15291c2293 Playtest #5 fixes: hovering enemies, target order, blocking hand-over, 联防 knocked-out, elements, huge-boss hit area, maps, gear icon, phone HUD, 至简 price
- #1 近地悬浮 enemies count as air units (Unit.isFlying): ground-only attacks, splash, terrain and traps skip them;
  PRTS 不可对空 skill effects made ground-only; 掠海漂移体 / 吉兆飞鳞 drop modes; the bot plans them as air
- #2 an operator knocked out before 联防 is fielded and force-exited (PRTS 强制退场): it lies on its tile with the
  redeploy ring and redeploys (full timer [ASSUMED]); partners, observers and the server fallback included
- #3 element audit of every operator, item and enemy: 海嗣 numbers are official; bursts are 无来源, 元素脆弱 only
  raises 元素伤害, 元素抗性 applied, 盟约·辅助干员 fills all three gauges, 菲莱 / 哈洛德 / 纯烬 / enemy kits fixed
- #4 blocking by the official contact radius (0.7071): another operator in contact takes over at once when the
  blocker dies, withdraws or is stunned; melee blockers attack what they block
- #5 enemy target order per PRTS 索敌: blocker, special priority, taunt, last deployed; initial deploy 从上到下>从左到右,
  operators before summons; special priorities break ties by taunt then deploy order
- #6 act2 m01's normal-field blower machines (row 13) are drawn in the normal / 联防 views
- #7 Final Assault prep legality reads the player's half of the boss field (fence tiles deployable); all 11 stages
  audited against the official level files
- #8 regular settings gear; #9 the prep camera keeps the bench and temp rows clear of the shop bar on phones
- #10 huge bosses have the official 4.95 × 2.95 hit area (sim/body.js) and are 自缚 / unblockable
- #11 至简 costs 1: 购买价格为N's bb.price is a discount off the tier price, applied before other price effects
- DESIGN §19 and the normative §3 / §5 / §6 / §7 lines, SIM / META / DATA / PLAYING updated; 2595 unit tests and
  every browser suite green; dev recordings regenerated
2026-09-30 19:12:36 +08:00
sganggs 01a44cd288 卫戍协议:盟约 web remake — initial import
Online co-op browser remake of Arknights' Stronghold Protocol: Alliance
(client-simulated combat, official waves/bonds/items/strategies, 3D board,
facing wheel, operator loadout, official emotes, deployment scripts).
2026-09-29 16:21:31 +08:00