From 46e976259d2698cebeab8e3c391b09ee837cb2ec Mon Sep 17 00:00:00 2001 From: Dabit Date: Tue, 10 Mar 2026 21:31:43 +0100 Subject: [PATCH] docs(03): capture phase context --- .../03-complete-experience/03-CONTEXT.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 .planning/phases/03-complete-experience/03-CONTEXT.md diff --git a/.planning/phases/03-complete-experience/03-CONTEXT.md b/.planning/phases/03-complete-experience/03-CONTEXT.md new file mode 100644 index 0000000..46fcb4b --- /dev/null +++ b/.planning/phases/03-complete-experience/03-CONTEXT.md @@ -0,0 +1,108 @@ +# 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 + + + + +## 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) + + + + +## Deferred Ideas + +- None — discussion stayed within phase scope + + + +--- + +*Phase: 03-complete-experience* +*Context gathered: 2026-03-10*