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

109 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 3: Complete Experience - Context
**Gathered:** 2026-03-10
**Status:** Ready for planning
<domain>
## 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.
</domain>
<decisions>
## 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
</decisions>
<specifics>
## 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
</specifics>
<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>
## Deferred Ideas
- None — discussion stayed within phase scope
</deferred>
---
*Phase: 03-complete-experience*
*Context gathered: 2026-03-10*