feedback1 final: merge the 0.1.1 gaps (变形同构体 pairings, 调和 +1 row, bands tied to a switched-off bond, the client-result layer bound)

This commit is contained in:
sganggs committed 2026-10-03 18:45:56 +08:00
commit 3b4d44bda8
26 files changed
+1332 -65

No files matched your search

+16 -5
View File
@@ -212,6 +212,11 @@ The rest of this section is the legacy server-run mode
另一组队友的战场情况" → `BAD_TARGET 'other group hidden'`); eliminated / departed players spectate any field.
### 1.5 AI player (bot.js)
**Strategy** (`botPickBand`): weighted by starting LP among the offered bands (alone, 老鲤's withheld first-round funds
× 0.02); a band whose mechanic rides on a bond the mode switches off weighs 0 — `GameData.bandBondIds` (bands.json
`bondIds`, built by shared/bandBonds.js: the bond names in <…> of its text, the bond ids / bond pools of its blackboards)
∩ `modeInactiveBonds`: 标准's 潘格尼尼, 克莱门莎, 玛恩纳 — and with every offered band excluded it takes the default band;
one rng draw per pick (DESIGN §21.26). The strategy draft marks the same bands 本局禁用 for humans (still selectable).
Buys toward a full board first (the cap is 8 from R1; leftover funds are lost), completes the merges it can afford,
then levels on a curve (L2 ≈ R3, L3 ≈ R5, L4 ≈ R7, L5 ≈ R10, L6 ≈ R12 — the competent curve of docs/BALANCE.md; free
levels always), then spends the rest (a band that keeps its leftover funds — 坎诺特 利滚利 — holds its interest capital
@@ -535,22 +540,27 @@ Any `choice:` handler whose EffectRef reuses its own key must guard like this (o
promotion, an owner moved while hand and temp are full) the summon leaves the board and its stack comes back at the
next round start (`grantTokensFor`), so no out-of-range placement reaches the battle. The client lights and accepts
the same tiles (`ui/gameLogic.js summonRange`), the bot plans inside them. Battle side: SIM.md §1.1 token pieces.
* **Bonds**: bondsMeta.js (BOARD distinct, BOARD_AND_DECK, 绝技 elites, 调和 +1, 独行 downward, 助力 upper tiers,
变形同构体 grants). Σ activated layers for the hidden core = Σ layers of active bonds at the boss round's prep end.
* **Bonds**: bondsMeta.js (BOARD distinct, BOARD_AND_DECK, 绝技 elites, 调和 +1 — the state and the views mark it
`harmony: 1`, DESIGN §21.26 —, 独行 downward, 助力 upper tiers, 变形同构体 grants). Σ activated layers for the hidden
core = Σ layers of active bonds at the boss round's prep end.
**变形同构体** (变形者集群 "与特定装备一同装备时装备者将视为特定盟约成员", 缪尔赛思's 特质 hands it out): its wearer
with a bond item (`giveBondId`, the 14 pairings of the item's official talent) is a member of that bond — counted like
any member (on the board only: the 14 bonds are BOARD; one member per operator, normal and elite copies alike), and
so in the battle input / battle, the views, and on the client: the bond popup lists it among the members (tagged
同构, `gameLogic.bondMembers` / `grantedBonds`, the same rule as `pieceBonds`) and its card shows the granted bond
chip; a teammate's units carry their item ids for that (UnitInfo `items`, `Match.prepFieldMeta`, SIM.md §9), and a
card without an own piece (a teammate's unit, the card a 同构 row opens) lists those items read-only under 装备.
card without an own piece (a teammate's unit, the card a 同构 row opens) lists those items read-only under 装备. The
item's card lists the 14 pairings of its 天赋栏 from the same `giveBondId` (`gameLogic.morphPairings`, 本局禁用 marked),
the wearer's card highlights the pairing it wears, and a bond item's card names the bond it gives (DESIGN §21.26).
Not covered [ASSUMED]: operator talents that test "【拉特兰】/【卡西米尔】/… 干员" in the kits read the record's bonds.
**Layer cap** (research 11 §1; the client's `MAX_GARRISON_STACK` / `AddBondCount` = min(L + n, 999)): each bond's
layers stop at `BOND_LAYER_CAP` = 999 (shared/constants.js; 0 / Infinity = off). Every writer clamps with
`layerGainRoom` — `PlayerState.addLayers` (all prep-side gains: 特质, items, bands, 机变 cards, bonds; `ctx.addLayers`),
the SETTLE of the in-battle gains and the battle's own live copy (`Battle.addLayers`, SIM.md §6); a gain at the cap
adds 0 and dispatches no onLayers. The client-result check bounds a reported gain by the room left from the bond's
starting layers (`fields.js validateClientResult`, 'layer bound'); `invariants.js` flags a bond above the cap. The
starting layers and by 60 + 4·round plus what the player's IN_BATTLE layer 特质 can add to that bond (their per-battle
caps; an uncapped trait leaves only the room — `fields.js layerAllowanceOf`, DESIGN §21.26) (`validateClientResult`,
'layer bound'); `invariants.js` flags a bond above the cap. The
bond strip, its popup, the effect text and the detail card show the server's capped count. The dev tools' direct
writes (`tools/matchrun.mjs --layers N`, `tools/balance.mjs applyBoard`) stop at the cap too.
* **Waves**: waves.js header (stage/factions/boss per match, faction replacement per round with `k` copies, scaling by
@@ -660,7 +670,8 @@ drawn set; `disabledBonds` = drawn ∪ the mode's static list), `hiddenBossId`,
`players[].autoplay`, `players[].uniteLeft` (UNITE, leakers only: their enemies still standing, uncapped — §4),
`players[].bonds` = `ps.alive ? bondList(gd, ps.bondsView()) : []` — every bond with members, layers or an active tier, the same list
and order as the player's own `m.private bonds` minus `thresholds` / `countsHand` (the client reads those from
bonds.json): a teammate watching the player shows it in the bond strip (DESIGN §20.15); `[]` once the player is
bonds.json; an entry whose count holds 调和's +1 carries `harmony: 1` in both lists — the bond popup's 调和 row, DESIGN
§21.26): a teammate watching the player shows it in the bond strip (DESIGN §20.15); `[]` once the player is
eliminated (nobody can watch them; the result screen reads `m.result`'s own bonds), and per phase: `draft { order, turn, picks, skipsLeft, turnDeadline, turnSeconds, untimed }` (BAND_DRAFT),
`sp { family, name, desc, eventId, cards:[{ idx, kind:'bounty'|'item'|'tactic', id, name, desc, tier, descRaw?, coin?,
payout?, rounds?, enemyKey?, count?, price?, team?, tacticKind? }], order, turn, picks:{pid: idx}, taken:{idx: pid}, untimed }`