Commit Graph
83 Commits
Author SHA1 Message Date
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 a611cb013c feedback5: merge W5I — real i18n phase 1: shared/i18n.js (Chinese msgids, params, data names), English game texts from the official EN client data (data/i18n/en.json), the 中文 / English switch on the title screen and in 设置, title / lobby / room / settings converted, server toasts and ticker lines with msgid + params, tools/i18n.mjs, docs/I18N.md (PR #70's translations by @YuriRestia reused, credited)
Conflict: server/match/player/basics.js imports (W5G's checkNotOwned + W5I's msg / dn). data/i18n/en.json rebuilt on the merged data (tools/build-i18n.mjs --offline): the 自选 data adds texts of CN-only operators and modules the EN client lacks, so coverage is 97.6 % (skills 95.9, talents 95.1); the coverage floors in test/i18n-data.test.js and docs/I18N.md say so. Golden unchanged; i18n / lobby / match / ui suites 1144/1144 after the rebuild, i18n e2e 1/1.
2026-10-05 22:57:53 +08:00
sganggs 5398a0cfc5 feedback5 WI: server toasts and ticker lines carry msgid + params so the client shows them in the player's language
messaging.js: a toast / CUSTOM ticker line is a string (its own msgid) or a shared/i18n.js msg(); frames keep
the Chinese `text` (older clients) and add `msgid` / `params`; config.broadcasts lines carry their `args`
(the client fills the localized broadcast template; the player name {0} is never translated). Templated call
sites send msg(): the grant toast 「X:获得Y」, the summon-range and terrain withdrawals, the 联防 line,
eliminated / left lines, the 远见 / 奇迹 stack payouts and the 维多利亚 hammers; game-data names go as dn().
The protocol stays backward compatible (new fields optional). Tests that captured m.toast's argument render
it with renderMessage. No gameplay change: golden unchanged.
2026-10-05 20:19:58 +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 8a43624935 feedback5 WE: 联防 is played on its own map, the escaped template level (GitHub #41, item 3) — act2autochess constData escapedBattleTemplateMapSinglePlayer / MultiPlayer = level_act1autochess_escaped_single / _multi name the level of the 联防 battle, and its map is the field: two road halves (cols 3–9 and 11–17, rows 9–12) joined at col 10, no water, crates or devices (until 0.1.3 the round's stage, opened to both halves). tools/build-data.mjs builds both into data/stages.json after the 11 battle stages (kind 'unite', helpers 1 / 2, weight 0, inactive, no modes, the name 联防阵地(N名玩家) the remake's own label [ASSUMED]; validation ties config.unite.templates to them); regenerated offline, a JSON compare shows only the two added records. unite.js uniteStageId picks the map of the helper count (escaped_single's routes enter at col 10, escaped_multi's at col 18 through (9,10)); match/unitePhase.js fields the 联防 battle on it (the round's stage only with data that lacks it); each helper on its prep tiles, the first of two shifted 8 columns onto the right half as before (the official halves; player_map_lr_offset 8). Client: screens/game.js draws the shown field's own map and restores the board's on leaving it (a 2-line change in a file of the R5 split; render/app.js enterBattle already loads m.field stageId); the dev mock's 联防 follows. The 联防 BGM (PR #110) is unchanged. Tests: test/match/feedback5-unite-map.test.js (both combat modes, 1 and 2 helpers, degraded data), test/data.test.js, test/render/tiles.test.js. Docs: DATA §12, META §4, DESIGN §3, PLAYING §5. Golden: fields unite-1 / unite-2 (the battle's stage → the 联防 map) and the 6 co-op match scenarios with a 联防 round (coop2-NORMAL-3, coop2-HARD-4, coop3-ABYSS-5, coop4-FUNNY-6, coop4-ABYSS-7, coop2-NORMAL-8-serverrun); roster / bonds unchanged (tools/golden.mjs leaves the 联防 maps out of its stage list) 2026-10-05 18:17:08 +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 cea593561a feedback5 R2: after the move — match/bossRounds.js imports finalAssault.js once (Match.js had two import lines for it), match/watch.js drops the stale first doc line of _prepScoutSig (superseded in the review of PR #129) 2026-10-05 17:18:54 +08:00
sganggs 64443b4aab feedback5 R2: PlayerState.js → server/match/player/*.js, a pure move — the 87 class members (82 methods and the isHumanActive / botControlled / deployCap / deployCount / tempEmpty getters), verbatim with their comments, go to 9 per-concern method containers (basics, pieces, acquire, economy, placement, items, prep, round, views) that PlayerState.js installs on PlayerState.prototype in a fixed order with class-method descriptors (a name defined twice throws); HAND_SIZE, TEMP_SIZE, MAX_OFFER_SLOTS, OK and fail go to player/common.js; PlayerState.js keeps the header (+ a code-layout paragraph), the class with its constructor and the FIELD re-export. Section-header comments are replaced by the module headers. docs-consistency reads the method modules (playerText), pins layerGainRoom in player/economy.js and checks that no Match / PlayerState module has a layerRoom 2026-10-05 17:15:37 +08:00
sganggs 1ca4936f0a feedback5 R2: Match.js → server/match/match/*.js, a pure move — the 167 class members (166 methods and the soloUntimed getter), verbatim with their comments, go to 16 per-concern method containers (platform, infra, messaging, views, watch, intents, pause, phases, spDraft, prep, combat, clientCombat, reports, unitePhase, bossRounds, settle) that Match.js installs on Match.prototype in a fixed order with class-method descriptors (a name defined twice throws); the constants the modules share go to match/common.js (FLOW_TICKER_PRIORITY, DELAYS, BAND_TURN_SECONDS re-exported by Match.js; OK, fail, BOSS_CLOCK_MS), GAME_TYPES to platform.js, the boss-round budgets / rates to bossRounds.js; Match.js keeps the header (+ a code-layout paragraph), the constructor-only constants and the class with its constructor. Section-header comments are replaced by the module headers. docs-consistency reads the method modules (matchText) and pins layerGainRoom in match/settle.js 2026-10-05 17:10:38 +08:00
Luo Xingyu bce182703b Watching a teammate shows their hand, 临时整备区, equipment, strategy and effects (#129)
The prep scout of another player's board carries their 整备区 hand and 临时整备区 as units on the bench rows (like the own prep bench), the equipped items of their operators, their strategy in the drawer and their effects column (the official mode shows a teammate's hand too). The scout signature includes the hand / temp slots, so a moved card refreshes the watcher. Closes #128. Contributed by @2321Robin.
2026-10-05 16:47:33 +08:00
sganggs 9f3785636a feedback3: a prep-end item may sit unmerged through the fight, and bonds.json matches the offline build 2026-10-04 22:20:20 +08:00
sganggs c9dd2a6392 feedback3: merge WJ — 高台 only for elite 歌蕾蒂娅 with HOK-Y, live prep watch, silenced 折射, grant toasts, emote timeout glyph 2026-10-04 21:26:46 +08:00
sganggs 1005754bf3 feedback3: merge WH — ground operators are melee-position, 叙拉古 rolls on every normal hit, off bonds show as disabled, prep-end items merge next prep 2026-10-04 21:26:10 +08:00
sganggs 3500ef2d32 feedback3: merge WG — nest enemies pulse instead of attacking, children carry no bounty, a 隐匿 blocker is skipped by areas, stacked cold freezes for the longer duration 2026-10-04 21:25:40 +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 5e4fe8ae60 feedback3 WJ: toast when a bond grants a chess, and flash the new card
歌蕾蒂娅:获得X, and the same line for 余 and every other silent grantChess. A new hand or temp card uses the existing deploy flash.
2026-10-04 20:41:46 +08:00
sganggs 6e59b5e4dd feedback3 WJ: prep watch of another board updates when it changes
A scout stays subscribed to n:<pid> and gets a new prep field when that board moves, including a spectator. A shop change does not push one.
2026-10-04 20:34:32 +08:00
sganggs 9aaba7708c feedback3 WH: an item gained as prep ends waits in hand and merges at the next prep start 2026-10-04 20:34:03 +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 c0cc1d6118 feedback3 WH: mode-off bonds the player has members of show as grey 本局禁用 discs, and hand members count in that header 2026-10-04 20:31:06 +08:00
sganggs bc721b4981 feedback3 WF: a 联防 阿戈尔 who enters down keeps the revive slot their position earned (the forced exit is not a 击倒); helper order ranks the layers the combat reached; a 替身 switch is 禁疗, so a self-heal does not land 2026-10-04 20:27:14 +08:00
sganggs 95b8a24d28 feedback3 WG: a split or summoned child does not carry the kill bounty, and 联防 pays a bounty card only when the leaked enemy is that card's enemy 2026-10-04 20:15:12 +08:00
sganggs ca3d0572ad feedback3 WF: the initial deployment goes by column — the left column first, top to bottom within a column (PRTS 从上到下>从左到右 read as a scan, the 阿戈尔 devour's order; mirrored boss side from its own left); a merge's elite among several deployed copies follows it (server and client); tests whose target was the latest deployed keep it 2026-10-04 19:50:42 +08:00
sganggs 0e3429aa1f feedback3 WF: 联防 fights with the bond layers the helpers' own combat reached (the strip's count, capped like the settlement), no longer the round-start layers; the settlement still adds those gains once (PRTS 联防阶段 以其阵地当前的状态, community report #24) 2026-10-04 19:31:15 +08:00
sganggs a57c2a85e2 feedback3: merge W3D — 折桠's skill idle (community report #23), the ammo bar's real total (#35), unit sounds at the official chance and volume (#30), shots from the hands to the chest (GitHub #61), stuck model loads restarted (GitHub #68), the boss leader shown in prep with its hit tiles (#12) 2026-10-04 18:10:01 +08:00
sganggs dcc44712ad feedback3: merge W3A — 联防 carries HP ratio and SP only (GitHub #82); down operators take part in the 联防 devour (players' reports, owner's decision); 不屈 on 撤退 / 替身 switches; SP recovers during stun (洛洛 S2) 2026-10-04 17:57:44 +08:00
sganggs 8707c161b9 feedback3: merge W3E — two spectator seats per co-op room (GitHub-relayed community request #26; a remake feature): watch like an eliminated player, never act, no private data 2026-10-04 17:57:09 +08:00
sganggs 207a49103f feedback3 WD: the boss rounds' prep shows the leader on its spawn tile with its HP bar, and its hit tiles in red beside an operator's range preview (community report #12) 2026-10-04 17:42:18 +08:00
sganggs 42766172d1 feedback3 WE: spectator seats on the server — up to 2 per co-op room, never players, watch like an eliminated player, no private view (community report #26) 2026-10-04 17:20:51 +08:00
sganggs 8252be248f feedback3 WA: 联防 carries the HP ratio and the SP only — a skill running at the end of the own combat enters switched off (no free restart), the SP counts stored charges, board summons keep their SP 2026-10-04 17:16:55 +08:00
sganggs ce33795d1b feedback3 WC: the 信标 gift sends the original operator (an elite stays an elite) and still arrives when the sender is eliminated; a failed grant waits for the next round start 2026-10-04 17:06:43 +08:00
sganggs d74665f068 feedback2: WF review — the 高台 reading marked [ASSUMED] in the code comments; only 歌蕾蒂娅 is obtainable (崖心 / 见行者 are hidden chess); §22.6 notes the tile-based 地面干员 effects 2026-10-03 23:40:13 +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 3b4d44bda8 feedback1 final: merge the 0.1.1 gaps (变形同构体 pairings, 调和 +1 row, bands tied to a switched-off bond, the client-result layer bound) 2026-10-03 18:45:56 +08:00
sganggs f671c15d3f feedback1 integrate: the prep dispatcher takes every equipped item before the first one runs (follow-up to the PR #2 fix)
Step 5 read each holder's items when the walk reached that holder, so an item equipped meanwhile onto a holder not yet
walked ran in the same dispatch and an item moved to a later holder ran twice (latent: no shipped item does either).
Every [holder, item] pair is now taken before the first item runs, as the header and META already said.
2026-10-03 17:47:19 +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 cef6b219f9 feedback1 gaps: the client-result layer bound counts the lineup's layer traits
With the bots' new band picks the full-match suite's coop/FUNNY/107
reached a 6-谢拉格 freeze board at R12 whose honest +112 谢拉格 layers passed
the flat 60 + 4*round = 108, so the server rejected the client and
re-simulated (SP_VERIFY=all agrees with the client on all 57 battles).

validateClientResult now adds, per bond, what the player's IN_BATTLE layer
traits can add to it: each trait of its units and each one their ADD_BOND
traits hand out (once per operator), up to the per-battle cap the sim
applies; a trait without a cap, or a 魔王, leaves the bond bounded only by
the room under 999. Other bonds keep the flat bound. DESIGN §14 / §20.12 /
§21.26, META and the CHANGELOG say so; tests pin the R12 board and the
capped, handed-out and 魔王 cases.
2026-10-03 15:25:48 +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 016fdb3804 feedback1 gaps: 变形同构体 lists its pairings; the bond popup explains 调和's +1
The 变形同构体 item card gets its 天赋 list (gameLogic morphPairings, from
the same giveBondId the server counts with): one line per bond with the
items that pair with it, 本局禁用 marked, and on a wearer's card the pairing
it wears highlighted. A bond item's card says which bond it gives a
变形同构体 wearer.

computeBonds marks a core bond state whose count holds 调和's +1
(harmony: 1) and both bond views send it. The popup reads it: 在场 n
(含调和 +1) and a 调和 row naming the 调和 operators on that board, for
the own strip and a teammate's; the strip and chip titles say it too.
The mock harness gets the funny / morph / harmony variants.
2026-10-03 15:07:14 +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 cb01bb3fcf feedback1 integrate: the prep dispatcher walks a snapshot of equipped items (pointed out in PR #2)
Step 5 iterated holder.items live while handlers move and destroy pieces: normal 博士投影
splices itself out (the next item on that holder was skipped) and 突变细胞 transforms its
holder (the next item ran with a holder that was gone). It now walks a copy and runs an item
only while it is still equipped on its still-owned holder; the rule is in the header and
META.md. Tests use a synthetic spy handler after the 突变细胞 and after 博士投影.
2026-10-03 13:43:56 +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 f142012033 feedback1 integrate: WB follow-up - bounty lists, 机密商店 and 战术决策 from 66 official screenshots (22 matches)
Merges the 7 WB commits after the first WB merge (d1f8a49..2cb84bd): R3 one of 10 fixed
sets (9 seen), R9 one of 6 boss groups picked by the matches they came in, R11 one of the
7 seen lists of 7; R11 families 14 / 4 / 4; the 机密商店 and the 战术决策 can offer the
same card twice (R11 shop: two VI, at least one V and one 盟约之币). data/choices.json
rebuilt with tools/build-data.mjs --offline (identical to the branch's). The tactic bot
test uses a real seat (the merged bot scores tactic cards on the player's bonds).
DESIGN §21.2 / §7 / §21.20 and CHANGELOG describe the 22-match model.
2026-10-03 11:27:46 +08:00
sganggs 67e862d2b3 feedback1 WB: 战术决策 drawn with replacement like the 4 official drafts; R11 ally cards weighted by the screenshots
The user: "战术决策也按官方改成可以重复吧". The 4 official 战术决策 (R11 of
matches 7, 9, 18 and 20) show six cards each; match 7 offers 补给 twice.

- Every 战术决策 card is drawn on its own (with replacement), so the same
  card can come twice. choices.js tacticDraftCards / tacticCard.
- R11 (绝境 / 终极, the round of the screenshots; choices.json tacticDraft,
  build-data TACTIC_DRAFT): only the ally cards, weighted 1 + the official
  cards each showed on. All 24 official cards are ally cards (no 排斥 /
  责罚 / 裁决, no terrain card: about 0.04 % for the previous draw) and
  列装 / 财富 / 补给 / 整备 / 升华 made 12 of them (uniform: about 4.6).
  Other rounds (标准 / 险境, no screenshot) keep every card, uniform, with
  replacement too. The weights and the R11 terrain exclusion are assumed.
- The header is the official "进行协同调整,做好迎战准备。".
- Identical cards are separate cards: own index, own object; a pick
  applies its card once and leaves the twin pickable; two picks of a team
  card stack. Match / bot / overlay already go by index.
- Tests: official drafts vs data, generated R11 / solo / earlier rounds,
  a seeded draft with 补给 twice, co-op and solo E2E picks of twins, the
  bot, the overlay, and a headless-Chrome render (game-mock variant=tactic
  is now the official match 7 draft). Tests that drive given tactic cards
  lay them out explicitly. The 奥术 Final Assault test takes the first of
  a few seeds whose bots pair two 奥术 players (the draws moved seed 12).
2026-10-03 09:10:39 +08:00
sganggs bb6078efc2 feedback1 WB: R11 hunter events left open (the data's block order does not decide them); PLAYING 机变 row keeps the bounty payout with the bounty
The 7 seen R11 lists stay picked uniformly, assumed because that invents no list. By the blocks of
effectChoiceInfoDict, R11 would fire bounty_hunter_8..15 (beside artifact_paid_4/5 and hardbuff_select),
so the block order is no longer cited as support for '1..7'. 7, 8 or 9 events fit the 14 drafts about
equally; with 8, an unseen list would come in about 1 R11 bounty draft in 8 (open question).
2026-10-03 08:29:25 +08:00
sganggs 3b18376eb7 feedback1 WB: R11 bounty list drawn from the 7 seen lists; R9 group sizes stated as they are; official 机密商店 composition only at R11
- R11 悬赏决策: the list is one of the 7 seen lists, uniform (slots 7, taken as the events
  bounty_hunter_1..7, one block of effectChoiceInfoDict). No list is built from nothing any more;
  the rule only completes the 4 lists seen with 6 cards, so 12_8 / 16_2 / 16_6 come in about
  1 R11 bounty draft in 15 (14 drafts without one: about 39 %).
- R9: the groups hold 9, 9, 9, 9, 8 and 6 cards (comments, docs, test); match 4's base-only
  group may be a draft of another group (open). 58 -> 59 bounty drafts in the build-data note.
- 机密商店: shopDraft.rounds [11]. The official composition (VI, VI, V, 盟约之币 + 2) applies at
  R11 (绝境 / 终极, where the screenshots are); the earlier 标准 / 险境 shops keep the previous draw,
  any tier I-VI per card with replacement (repeats still possible, about 26 %).
- Tests: R11 slots / block order / never-shown rate, R9 group sizes, the non-R11 shop draw.
2026-10-03 08:09:39 +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