feedback5 CB5: the boss round's prep shows both players of a pair together — the partner's pieces on the other half, as the battle places them — and frames the pair's two avatars in the official green (community report of 2026-10-06, item 51)

The own half was already the official one (the right-hand player on the right half with the
right_boss_*_camera_param camera, its layout mirrored col c -> 20 - c with RIGHT <-> LEFT, so its operators
face the leader as before: research 09 §1.2, DESIGN §15); the partner's half stood empty and nothing framed
the pair.
Server: in a boss round's prep m.private.bossMate { playerId, side, units } = the partner's board as UnitInfo
on its half (Match.bossMateView, finalAssault.js bossFieldPlacement); markPrivate marks the partner's
m.private with the mover's, so it follows live; a scout of either player (Match.prepFieldMeta) carries both
halves (`mate`), and its signature covers the partner's board.
Client: render/app.js syncMates draws the partner's units read-only ('m:<uid>' views: never picked, dragged
or swept with the own pieces) and the whole boss field is lit; the team panel frames the pair's avatars
(gameLogic teamFrameIds: the players still in by seat, two by two, as prepCamera — the boss field in the
fight) from the round start through the Final Assault / Hidden Core, with the official ui/battle
bg_team_border tinted the autochess green (#4ed8af; a plain ring without the local art); none for a lone
player, an eliminated player, a spectator seat, or 联防.
Overlap with PR #191 (same-field frames, issue #190; not merged): it published m.public bossPairing and
framed the partner alone in gold, 联防 included, plus a banner naming the partner; here the pairing is read
as the prep camera already does, both avatars get the official green frame, boss rounds only.
[ASSUMED] the partner's bench is not shown; one frame per avatar.

Golden unchanged. Tests: test/match/feedback5-boss-pair-prep.test.js (new, 4), the item 55 test now checks
the scouted player's own pieces (the partner's stand on the other half); SP_E2E
test/ui/feedback5-boss-pair.e2e.test.js (new, 2: both halves and the frames in prep and fight; item 55's
eliminated guest on the boss field with the leader). Docs: design/client.md §10 / §15, design/network.md,
PLAYING.md.
This commit is contained in:
sganggs committed 2026-10-07 02:29:49 +08:00
1 parent f14f03a59f
commit ef10164773
16 files changed
+436 -33

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ Platform additions (implemented): `welcome.{resumed, version}`, `welcome.diyKitt
C→S (all carry `rid`): `g.infoReady` · `g.band {bandId}` · `g.bandSkip` · `g.bandFocus {bandId?}` (the strategy highlighted in the draft screen — what a timed-out turn takes; absent / null clears it; `WRONG_PHASE` outside BAND_DRAFT, `ALREADY` after the pick, `BAD_TARGET` for a band not allowed; §18.2) · `g.buy {slot}` · `g.refresh` · `g.freeze` · `g.levelUp` · `g.sell {uid}` · `g.move {uid, to:{area:'board', row, col}|{area:'hand', idx}, dir?}` · `g.equip {itemUid, targetUid, replaceUid?}` (`replaceUid`: which equipped item a third one replaces, §6.2) · `g.art {itemUid, row, col, dir?}` (`dir` ∈ UP|RIGHT|DOWN|LEFT from the deploy wheel, §3; absent ⇒ `to.dir`, then RIGHT; `g.move` onto the piece's own tile re-orients it; board pieces in `m.private` / `m.field {prep:true}` carry `dir`) · `g.destroy {uid}` (hand / temp items only; equipped items are locked, §6.2) · `g.reward {idx}` · `g.choice {idx}` · `g.ready {ready}` · `g.emote {id}` · `g.watch {fieldId, playerId?}` (`playerId`: the player tapped — a shared 联防 / boss pair field shows two; what an eliminated viewer follows, §25) · `g.autoplay {on}` · `g.pause {on}` (solo battles only, §14 Solo pause) · `g.unitStats {seq?}` (ROUND_START / SP_DRAFT / PREP, else `WRONG_PHASE`; eliminated: `ELIMINATED`) → push `m.unitStats` (§18.5) · `g.leave`
S→C:
- `m.public` — full public state on every change (throttled ≤ 10/s): `{ phase, round, lastRound, deadline, serverNow, modeId, difficulty, stageId, factions, disabledBonds, bannedChess, bossId, hiddenBossId?, teamLp?, bossHp?:{hp,max}, overtimeAt? /* FA / HC: ms epoch the overtime drain starts, §4 */, paused /* solo pause, §14 */, draft?:{order,turn,picks,skipsLeft,turnDeadline,turnSeconds /* one turn's length, 0 untimed; deadline = turnDeadline (§18.2) */,untimed}, sp?:{family,cards /* bounty cards carry descRaw?, §20.6 */,turn,picks}, players:[{playerId, seat, name, isBot, connected, alive, lp, bandId, shopLevel, boardCount, ready, bonds:[{bondId,count,active,tier,layers,harmony? /* 调和's +1 is in count, §21.26 */}], fieldId, status, pendingLp? /* COMBAT / 联防 of a normal round: the LP the player's own battle will cost at settlement so far, min(lpCapPerRound, counted leaks) — in 联防 min(lpCapPerRound, uniteLeft) — omitted when 0 and in every other phase (§17.5 live LP) */, uniteLeft? /* 联防: the leaker's enemies still standing — not spawned yet + alive + counted leaks, uncapped, live (§20.6) */}] , fields:[{fieldId, kind, players:[playerId...]}] }`
- `m.private` — the recipient's full PlayerState view (§6.2 minus server-only data) on every change.
- `m.private` — the recipient's full PlayerState view (§6.2 minus server-only data) on every change; in a boss round's prep also `bossMate { playerId, side, units }` — the pair partner's board on its half of the boss field (UnitInfo, mirrored on the right half), re-sent when the partner moves (0.2.0, community report item 51).
- `m.field` — field meta when watching starts: `{ fieldId, kind, rect, stageId, units: [UnitInfo], effects? }` (the units on the field, knocked-out operators waiting to redeploy included — `Battle.fieldMeta`, §18.3). The prep-scouting field (`Match.prepFieldMeta`) puts the scouted player's **hand (整备区) and 临时整备区 into `units` as well**: held pieces as units on the hand row (row 7, col = hand slot) and temp pieces on the temp row (row 8, cols 4..8 = the temp slots; PRTS 帮助 counts the temp area with the hand; a held item is a `kind: 'item'` unit the client draws as its floating plate) — the scout renders exactly like the own prep bench, for every watcher alike, the spectator seat's copy equal to a teammate's (§23.19's "never a private view" stays the no-`m.private` rule); the scout signature `_prepScoutSig` carries the hand / temp slots, so a piece moved to another slot is a change — and carries `effects`: the scouted player's effects view (策略 / 机变 / 悬赏 …), the watched player's effects column ready-made
- NOTE: game time in `b.snap`/`b.ev` is carried as **`gt`** (the frame's `t` is the message type).
- Active finite zero-SP timed skills display `sp=timeLeft`, `spMax=duration` and `UF.SKILL`; after end they display