Game runs during countdown-in phase — pieces controllable before BREAK! (gameplay correctness) #110

Closed
opened 2026-06-22 21:10:19 +02:00 by bosun · 1 comment
Owner

Behavior (operator playtest 2026-06-22, deployed round-18)

During the "Lockdown... BREAK!" countdown-in phase before a game starts, the pieces are already active and the player can control them (move, rotate, drop). The game effectively runs during what should be a pre-game-start freeze period.

Severity: substantive

Gameplay-correctness bug. The countdown phase exists specifically to give the player a moment to focus before the game starts; if pieces are already active, the countdown serves no functional purpose and may give players whose reaction time aligns with the countdown an unintended advantage in versus mode.

Fix-direction (Shipwright lane)

Probe-first: locate the game-tick / input-dispatch handler; identify which phase guard determines "is the player allowed to control pieces"; ensure that guard returns false during countdown-in phase.

Likely options:

  1. Gate piece-control inputs on state.phase === 'playing' (NOT 'countdown' or similar)
  2. Gate game-tick (auto-fall, lock timer, etc.) on same condition
  3. Possibly the entire game-loop should be paused during countdown, not just input

Acceptance criteria

  1. Probe identifies current phase model + which guards control input/tick
  2. During countdown-in phase: pieces visible (player can see what's coming) but NOT controllable (keyboard/touch input does nothing; game-tick does not advance)
  3. On countdown→playing transition: control becomes active immediately
  4. No regression on normal playing-phase behavior
  5. Harness #81 extended with countdown-locked test row (mutation-provable: revert the lock → harness reds)

Cross-refs

  • Possible interaction with #87 abort/forfeit (countdown-during-abort-overlay behavior)
  • Operator playtest 2026-06-22

Anchor

2026-06-22 operator playtest of round-18. Discovered during multi-AC verification session.

## Behavior (operator playtest 2026-06-22, deployed round-18) During the "Lockdown... BREAK!" countdown-in phase before a game starts, the pieces are already active and the player can control them (move, rotate, drop). The game effectively runs during what should be a pre-game-start freeze period. ## Severity: substantive Gameplay-correctness bug. The countdown phase exists specifically to give the player a moment to focus before the game starts; if pieces are already active, the countdown serves no functional purpose and may give players whose reaction time aligns with the countdown an unintended advantage in versus mode. ## Fix-direction (Shipwright lane) Probe-first: locate the game-tick / input-dispatch handler; identify which phase guard determines "is the player allowed to control pieces"; ensure that guard returns false during countdown-in phase. Likely options: 1. Gate piece-control inputs on `state.phase === 'playing'` (NOT 'countdown' or similar) 2. Gate game-tick (auto-fall, lock timer, etc.) on same condition 3. Possibly the entire game-loop should be paused during countdown, not just input ## Acceptance criteria 1. **Probe** identifies current phase model + which guards control input/tick 2. During countdown-in phase: pieces visible (player can see what's coming) but NOT controllable (keyboard/touch input does nothing; game-tick does not advance) 3. On countdown→playing transition: control becomes active immediately 4. No regression on normal playing-phase behavior 5. Harness #81 extended with countdown-locked test row (mutation-provable: revert the lock → harness reds) ## Cross-refs - Possible interaction with #87 abort/forfeit (countdown-during-abort-overlay behavior) - Operator playtest 2026-06-22 ## Anchor 2026-06-22 operator playtest of round-18. Discovered during multi-AC verification session.
Owner

AC-tick (pre-merge — PR #112)

Per the close-keyword ruling: this issue closes via Closes #110 in PR #112, with the AC2(b) server-side portion explicitly deferred to #111 (the architectural split surfaced by the probe — the countdown is a client-local cosmetic overlay; server-backed gravity is engine-room polish).

  • AC1 — probe · phase model + guards identified. The 'countdown' phase is never server-emitted (verified net.ts matched→playing + server/ grep + proto.ts); the overlay is the client-local countdownStart timer.
  • AC2(a) — not controllable · all four input/tick sites gated via shared inCountdown() (keyboard game-input, touch dispatchGameAction, softDropTick, mock gravity tick).
  • AC2(b) — game-tick does not advance · DONE for ?mock-solo (mock-tick gated → complete freeze). Server-backed gravity-hold deferred to #111 (Engineer engine-room). Honest ceiling: for real play (solo #38 + versus) server gravity still advances ~2-3 rows during the 3s window until #111 lands.
  • AC3 — control active on countdown→playing · lock lifts at COUNTDOWN_MS (the overlay-end ≡ input-unlock single-source-of-truth bound); verified by the positive-control test half.
  • AC4 — no regression on playing · 35/35 nav harness green.
  • AC5 — harness countdown-locked-input row, mutation-provable · added; mutation-proven (drop the keydown !inCountdown() guard → locked-input assertion reds) with a negative half + positive control + countdownLock precondition guard.

Reported harm (the unfair input head-start) is closed by PR #112; #111 carries the deferred server-side tick-freeze to actual closure.

## AC-tick (pre-merge — PR #112) Per the close-keyword ruling: this issue closes via `Closes #110` in PR #112, with the AC2(b) server-side portion **explicitly deferred to #111** (the architectural split surfaced by the probe — the countdown is a client-local cosmetic overlay; server-backed gravity is engine-room polish). - [x] **AC1 — probe** · phase model + guards identified. The `'countdown'` phase is never server-emitted (verified `net.ts` `matched→playing` + `server/` grep + `proto.ts`); the overlay is the client-local `countdownStart` timer. - [x] **AC2(a) — not controllable** · all four input/tick sites gated via shared `inCountdown()` (keyboard game-input, touch `dispatchGameAction`, `softDropTick`, mock gravity tick). - [x] **AC2(b) — game-tick does not advance** · DONE for `?mock`-solo (mock-tick gated → complete freeze). Server-backed gravity-hold **deferred to #111** (Engineer engine-room). Honest ceiling: for real play (solo #38 + versus) server gravity still advances ~2-3 rows during the 3s window until #111 lands. - [x] **AC3 — control active on countdown→playing** · lock lifts at `COUNTDOWN_MS` (the overlay-end ≡ input-unlock single-source-of-truth bound); verified by the positive-control test half. - [x] **AC4 — no regression on playing** · 35/35 nav harness green. - [x] **AC5 — harness countdown-locked-input row, mutation-provable** · added; mutation-proven (drop the keydown `!inCountdown()` guard → locked-input assertion reds) with a negative half + positive control + `countdownLock` precondition guard. Reported harm (the unfair input head-start) is closed by PR #112; **#111** carries the deferred server-side tick-freeze to actual closure.
bosun closed this issue 2026-06-22 21:53:18 +02:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/cellblock#110
No description provided.