Files
gijs_pong/.planning/phases/03-complete-experience/03-CONTEXT.md
2026-03-10 21:31:43 +01:00

5.2 KiB
Raw Blame History

Phase 3: Complete Experience - Context

Gathered: 2026-03-10 Status: Ready for planning

## Phase Boundary

Transform the game from a bare mechanic into a polished, navigable experience. Deliver: title screen, mode select, settings (AI difficulty + sound toggle + color scheme), game over screen, and audio feedback respecting browser autoplay policy. Replaces Phase 2's temporary key-prompt screens with real, styled screens.

## Implementation Decisions

Visual Style

  • Neon arcade aesthetic — magenta/hot pink as the default accent color on black background
  • Consistent neon treatment across ALL screens (title, mode select, settings, game over) — coherent visual language
  • Title screen: large glowing title text with color accent, feels like an arcade cabinet
  • Game over screen: displays final score + winner — e.g. "PLAYER 1 WINS 7 4" — not just the winner name

Screen Navigation

  • Arrow keys to move between options, Enter/Space to confirm selection
  • Escape or Backspace to go back to the previous screen
  • Screen navigation flow is Claude's discretion (connect: title → mode select → game, title → settings → title)
  • Settings is accessible from the title screen only — not in-game

Title Screen Structure

  • Title screen has a menu with at least: Play, Settings
  • "Play" navigates to mode select (Solo vs AI / 2-Player), then difficulty select (if AI mode)
  • Phase 2's 'modeSelect' and 'diffSelect' gameStates stay but get styled to match the neon aesthetic

Settings Screen

  • AI difficulty: Easy / Medium / Hard (sets GameState.difficulty)
  • Sound: On / Off toggle (sets GameState.soundEnabled)
  • Color scheme: cycle through preset neon palettes — Magenta, Cyan, Lime, White
    • Palette swap affects: ball color, paddle colors, and UI accent color globally
    • Store active palette in GameConfig or GameState; all draw calls reference it
  • Navigation: arrow keys highlight the current setting, Left/Right (or Enter) changes value

Color Scheme

  • Palettes are named presets (e.g. PALETTE_MAGENTA, PALETTE_CYAN, PALETTE_LIME, PALETTE_WHITE)
  • Each preset defines: accent color (ball/paddle/UI highlights), glow color (shadow/blur)
  • Default palette: Magenta (#ff00cc or similar hot pink)

Audio Character

  • Modern synthesized tones using WebAudio API — sine/triangle wave, slight reverb envelope
  • Three clearly distinct sounds:
    • Paddle hit: mid-range tone, short attack (recognizable rally sound)
    • Wall hit: higher-pitch tone, shorter duration (quick snap)
    • Score: single deep thud — low-frequency impact tone, weightier than the other two
  • AudioContext initialized only after first user interaction (keydown/click) — satisfies AUD-04
  • GameState.soundEnabled flag (set by settings) gates all playSound calls

Claude's Discretion

  • Exact screen transition order / gameState names for new states (title, settings, etc.)
  • Glow implementation (canvas shadowBlur or manual outer-ring draw)
  • Exact frequencies and envelope parameters for audio tones (within the described character)
  • Typography sizing, spacing, and layout of each screen
  • Whether modeSelect/diffSelect are merged into one screen or kept separate
## Specific Ideas
  • Neon magenta on black is the hero palette — the project aims for a "whoa" first impression
  • Audio should feel like modern indie game audio, not chip-tune — synthesized but clean

<code_context>

Existing Code Insights

Reusable Assets

  • Renderer.ctx: all screen drawing uses this canvas context — new screens render via the same draw path
  • Renderer.drawRect() / Renderer.drawCircle(): reuse for UI elements; canvas shadowBlur can add glow
  • GameState.gameState: string-based state machine already drives the render switch — add new states ('title', 'settings')
  • GameState.mode / GameState.difficulty: already in place; settings screen just sets these values
  • Input keydown handler: already handles mode/difficulty selection — extend for arrow key menu navigation
  • GameConfig: central constants — add palette definitions and WIN_SCORE is already there

Established Patterns

  • Single HTML file — all new code (Audio module, menu nav) goes in index.html
  • Module-object pattern: add a new Audio object with init(), play(event), setEnabled(bool)
  • GameLoop.main() render switch: add cases for 'title' and 'settings' gameStates
  • Phase 2's 'modeSelect' and 'diffSelect' cases stay in the switch — just get styled with neon palette

Integration Points

  • GameState.gameState = 'modeSelect' currently starts Phase 2 flow — Phase 3 adds 'title' before it
  • Score display uses hardcoded '#fff' — switch to GameConfig.palette.accent or equivalent
  • Ball/paddle colors are '#fff' in GameState defaults — make them reference the active palette
  • Input keydown: currently responds to Digit1/2/3 for mode/difficulty — add ArrowUp/Down/Enter/Escape for menu nav
  • WebAudio AudioContext must be created inside a user gesture handler (already in Input.init's keydown)

</code_context>

## Deferred Ideas
  • None — discussion stayed within phase scope

Phase: 03-complete-experience Context gathered: 2026-03-10