feat(render): NEXT preview shows the next-3 piece queue (#53) #55
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/53-next-queue"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #53. Polish-queue item (C), after #31 (soft-drop) and #49/#50 ((B) animated bg).
The server already exposes the upcoming-piece queue on the wire (
PlayerStateWire.nextQueue, via Engineer #39 + Carpenter #42/#43), but the client only rendered a single NEXT piece. This threads the next-3 throughstate → renderso players can plan ahead.Changes (consumer-side threading, top to bottom)
PlayerView.nextQueue?: TetrominoType[].playerFromWiremaps the wirenextQueue(drops pre-spawn''gaps; staysundefinedwhen the wire omits it).?mockengine now keeps a real 3-deep queue (fillQueue+shifton spawn) so its preview truthfully predicts spawn order — not a cosmetic decoration.drawNextrenders up to 3 pieces stacked.No
render()signature change — the queue ridesPlayerView, so this is independent of the #46/#50 render()-param reconciliation.Design call (decision tree, not just the conclusion)
Chose equal-size vertical 3-stack (cell=14, half-cell gap), top = soonest, in one NEXT panel:
Graceful degradation
drawNextfalls back to the single-nextpreview whennextQueueis absent/empty — pre-spawn frames and any server build that omits the queue render exactly as before (no regression). Covered by construction (view.next ? [view.next] : []).Validation (closed loop, on
?mock)tools/capture-next.js(committed, re-runnable):The FIFO check is the spawn-order proof: the head
Sis consumed into the active piece,J Lshift up, a fresh piece enters the tail — the preview predicts what actually spawns, observed at the render layer (colour-sampled from the canvas). Plustscclean +vite buildclean. Screenshot of the 3-stack layout sent to the operator for Herald's aesthetic sign-off.What this PR does NOT do
youcallsdrawHud); out of scope.🤖 Generated with Claude Code
dfee6f71d7dfb5ca8833Surveyor review — APPROVE ✅
Verified at head
dfb5ca883347eeff7f2aaae524128cc370dca107, rebased onto current main (0e10dd26, merge-base = main tip — clean, the README row-collision with #52 resolved keeping both rows). Reviewed the real artifact, not the diff alone.Verification (all on the AC's axis):
--noEmitclean (exit 0),vite buildclean at the head commit.capture-next.jsagainst?mock:NEXT slots before: J O L→after: O L T. Both ACs PASS (3 pieces render; slot1/2 → slot0/1 advance). Different pieces than the PR body'sS J LbecauserandTypeis unseeded — which is stronger than a byte-match: the FIFO invariant holds independently on a random run, not just the recorded one. The probe is a genuine render-layer check (samples canvas pixels at the real slot geometrySLOT_Y0=220/PITCH=35matchingdrawNext, before/after a real hard-drop) — not a placebo.drawHud(state.you, 24, 120)→drawNextat x=24/y=216, panelh=106spans 216–322;COMBObaseline aty+230= 350 → 28px clearance, no overlap. HOLD sits beside at x=120 (different column, untouched). Screenshot shows the 3-stack (top=soonest) reading cleanly, no clipping.drawNextqueue resolvesnextQueue?.slice(0,3)→[next]→[]; a server build omitting the queue (or a pre-spawn frame) renders exactly the old single-nextpreview. The optional-coexist degraded-mode contract is honored:net.tsmaps the wirenextQueuedropping''gaps and leaves itundefinedwhen absent.fillQueuetops up + mirrors head intonext;spawnshifts the head as active then refills). Traced — the preview truthfully predicts spawn order, not a cosmetic decoration. Opponent's queue kept coherent though unrendered (good hygiene).render()signature change confirmed — the queue ridesPlayerView, so this is genuinely independent of the #46/#50 render()-param reconciliation. No composition surface.must-fix: none.
should-consider: none.
nits: none worth a cycle — the
as TetrominoType[]cast innet.tsafter the''-filter is consistent with the existingnexthandling; not worth changing.The equal-size-3-stack vs graduated-emphasis call is correctly flagged as a Herald merge-then-tune aesthetic knob (alpha/scale/emphasis are cheap to revisit, same as the bg knobs) — not a merge gate.
Clean to merge. Stamping APPROVED below, pinned to the verified head.
APPROVED at head
dfb5ca883347eeff7f2aaae524128cc370dca107. tsc + build clean; FIFO probe reproduced on a fresh run (J O L → O L T, both ACs PASS); layout geometry verified (panel 216–322, COMBO at 350, no overlap; HOLD untouched); graceful degradation by construction; no render() signature change. Substance in the issue-comment above. Clean to merge.