feat(banpick): server-driven deck+stake draft UI + pool-fetch seam - #16
Open
ChronoFinale wants to merge 1 commit into
Open
feat(banpick): server-driven deck+stake draft UI + pool-fetch seam#16ChronoFinale wants to merge 1 commit into
ChronoFinale wants to merge 1 commit into
Conversation
ChronoFinale
force-pushed
the
feat/banpick-server-draft
branch
5 times, most recently
from
July 23, 2026 16:21
a949529 to
2d1bafc
Compare
The deck+stake ban-pick draft engine plus the client seam that fetches a server-generated pool (pairs with the server-side draft-pool PR). Engine (api/ban_pick.lua): tuple identity is deck+stake (Red@White != Red@Gold); Random is a blind commit; two-column tile hover (deck + stake detail); cocktail composition badge; counter/buttons stay visible off-turn, greyed; per-draft stale-broadcast protection with atomic random commit + guest UI sync; draft tiles drag-locked; popups clamp to the screen on both axes. Composite-agnostic -- a pool item carries its own decks/name, no cocktail knowledge in the engine. Seam (api/matchmaking/draft.lua, networking/api_client/draft.lua): issue_draft_pool fetches the match's server pool, callback(nil) when none so the consumer chooses fallback vs abort. Server-authoritative -- no max_stake param, no client-side event posting. Visual scenarios in dev/shots.lua for the DevTools shot harness.
ChronoFinale
force-pushed
the
feat/banpick-server-draft
branch
from
July 23, 2026 16:44
2d1bafc to
42c922b
Compare
ChronoFinale
marked this pull request as ready for review
July 23, 2026 19:44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Server-driven ban-pick draft UI + pool-fetch seam
The deck+stake ban-pick draft engine and the client seam that fetches a server-generated pool. Pairs with the server-side draft PR (
BalatroMultiplayerAPI-Server); the PvP/Speedrun consumer wiring lands separately.Engine (
api/ban_pick.lua)decks/name; the engine has zero cocktail-specific knowledgeSeam (
api/matchmaking/draft.lua,networking/api_client/draft.lua)issue_draft_poolfetches the match's server pool;callback(nil)when there's none, leaving fallback-vs-abort to the consumermax_stakeparam, no client-side event postingTesting
luajit -blclean on all touched filesdev/shots.lua+dev/test_banpick_*.lua(run by the DevTools shot harness)Draft — opening for eyes on the engine + seam shape.
Screenshots — draft UI
Rendered by the DevTools shot harness (
BMP_SHOT_SUITE=1) from thedev/shots.luascenarios in this PR; each caption is that scenario'sexpect:contract. Images are hosted on the fork branchpr16-shots— they are not part of the code diff.Your turn — ban a deck

DECK BAN overlay over the menu: "Your turn: ban a deck" (green), 9 deck tiles,
Selected: 0/3, greyed Confirm Ban, blue Random.Cocktail badge — hover

Badge reads "Casjb Cocktail: Green Deck + Black Deck + Orange Deck"; its hover shows the three decks side by side with full effects. The engine renders the composite verbatim — the consumer owns the wording.
Pick phase

Final PICK step between the last two: seven tiles debuffed, two live; green "pick your deck"; the chosen survivor raised with a green Selected tag; green Confirm Pick.
More scenarios (7) — selection, blind Random, off-turn, banned tiles, tuple/cocktail hovers, Speedrun variant
2 of 3 selected

Two tiles raised with red Selected tags; counter
2/3; Confirm stays greyed until exactly 3.Random armed (blind commit)

No tiles raised; counter
?/3; Random turns red "Cancel Random"; Confirm goes green "Confirm Random" — nothing is revealed until Confirm, so there is nothing to peek at or reroll-fish.Opponent's turn

Status not green; counter and both buttons visible but greyed; layout otherwise identical.
Banned tiles

Banned tiles are debuffed (darkened X overlay) and non-interactive.
Tuple hover — stake column

Hover popup: deck name + effects on the left, stake column on the right (stake name in its colour, description, "Also applied" list). Clamped fully on screen.
Cocktail tile hover — compact

The cocktail tile's own hover is compact: title, "rotating 3-deck mix", three deck names only (no effect boxes) plus the stake column — same footprint as a normal deck hover.
Same engine, different consumer — Speedrun

The generic schedule driving Speedrun's multi-pick draft variant — same
MPAPI.BanPickengine, different consumer config.Note on the screenshots
These are captured with the full stack running locally. The engine in this PR is consumer-agnostic — it renders whatever pool and composite items a consumer hands it — so the specific content shown (the deck+stake tuples, the 1 / 3 / 3 / pick schedule, the "Casjb Cocktail" wording and composition) comes from code outside this PR that is not all upstreamed yet:
The framework code here is self-contained and testable on its own (
dev/test_banpick_*.lua); the shots just show it driven by the real consumer + server.Related — server side
The pools this UI fetches, and the weekly cocktail shown in shots 07–08, are produced server-side in feat(draft): server-generated draft pools with per-queue policy — BalatroMultiplayerAPI-Server#42. This client PR is the rendering +
fetch_draft_poolhalf of that feature.The weekly cocktail is just data, rotated at runtime via a small admin endpoint (no redeploy):
Validation is server-side and strict (1–3 distinct cocktail-eligible decks — every deck except the Cocktail deck itself — and a name ≤ 40 chars):
The
namecarries no "Cocktail" suffix — the client appends its own localized wording (so"Casjb"renders as "Casjb Cocktail"), which is why the badge text in the shots is the consumer's, not the server's.