diff --git a/.planning/phases/03-complete-experience/03-01-PLAN.md b/.planning/phases/03-complete-experience/03-01-PLAN.md index bff40f3..076bd2c 100644 --- a/.planning/phases/03-complete-experience/03-01-PLAN.md +++ b/.planning/phases/03-complete-experience/03-01-PLAN.md @@ -154,7 +154,10 @@ GameState.activePalette = GameConfig.PALETTES.MAGENTA; Do NOT store palette color on `paddle1.color`, `paddle2.color`, or `ball.color` — those properties stay as fallback `'#fff'`. The palette is applied at draw-call time by reading `GameState.activePalette.accent` in the renderer. This keeps the physics/AI logic untouched. - Open index.html in a browser. The game starts at a blank black screen (title state). Open the browser console and run: `console.log(GameState.activePalette.accent)` — should log `'#ff00cc'`. `console.log(GameConfig.PALETTE_KEYS)` — should log `['MAGENTA','CYAN','LIME','WHITE']`. + +Open index.html in a browser. The game starts at a blank black screen (title state). Open the browser console and run: `console.log(GameState.activePalette.accent)` — should log `'#ff00cc'`. `console.log(GameConfig.PALETTE_KEYS)` — should log `['MAGENTA','CYAN','LIME','WHITE']`. + grep -c "PALETTES" index.html && grep -c "PALETTE_KEYS" index.html && grep -c "activePalette" index.html && grep -c "soundEnabled" index.html && grep -c "selectedMenu" index.html && grep -c "previousState" index.html + GameConfig has PALETTES and PALETTE_KEYS. GameState has activePalette pointing to MAGENTA preset, soundEnabled:true, selectedMenu:0, previousState:null. gameState starts at 'title'. @@ -277,7 +280,10 @@ Replace ALL occurrences of hardcoded `'#fff'` and `'rgba(255,255,255,0.8)'` in r - Score display: change `'rgba(255,255,255,0.8)'` to `GameState.activePalette.accent` - Center divider: keep dim `rgba(255,255,255,0.2)` (neutral, not palette-colored) - Open index.html. Verify: (1) Title screen renders with neon magenta glow on black background, menu shows Play and Settings. (2) Arrow keys change which item is highlighted. (3) Enter on Play goes to mode select with neon style. (4) Enter on Settings goes to settings screen showing difficulty/sound/palette. (5) Changing Color Scheme updates the palette (ball/paddle/text all change on next gameplay screen). (6) Completing a game shows "PLAYER X WINS N – M" format with Play Again and Main Menu options. (7) Escape from settings/modeSelect returns to previous screen correctly. + +Open index.html. Verify: (1) Title screen renders with neon magenta glow on black background, menu shows Play and Settings. (2) Arrow keys change which item is highlighted. (3) Enter on Play goes to mode select with neon style. (4) Enter on Settings goes to settings screen showing difficulty/sound/palette. (5) Changing Color Scheme updates the palette (ball/paddle/text all change on next gameplay screen). (6) Completing a game shows "PLAYER X WINS N – M" format with Play Again and Main Menu options. (7) Escape from settings/modeSelect returns to previous screen correctly. + grep -c "drawNeonText\|shadowBlur" index.html && grep -c "activePalette\.accent" index.html && grep -c "'title'" index.html && grep -c "'settings'" index.html && grep -c "ArrowUp\|ArrowDown" index.html && grep -c "Audio\.isInitialized" index.html + All 5 game states (title, settings, modeSelect, diffSelect, gameover) render with neon palette. Arrow-key navigation works. Palette switching affects all game colors. Game over shows winner + full score in the specified format. diff --git a/.planning/phases/03-complete-experience/03-02-PLAN.md b/.planning/phases/03-complete-experience/03-02-PLAN.md index 600d910..418e918 100644 --- a/.planning/phases/03-complete-experience/03-02-PLAN.md +++ b/.planning/phases/03-complete-experience/03-02-PLAN.md @@ -192,7 +192,10 @@ const Audio = { - Always call `osc.stop()` to free WebAudio node resources — omitting this causes a memory leak - The `play()` guard `if (!GameState.soundEnabled || !this.isInitialized || !this.audioContext)` covers all three failure modes: settings muted, not yet init'd, context creation failed - Open browser DevTools console. Load index.html. Run `console.log(typeof Audio, Audio.isInitialized)` — should print `"object" false`. Press any key. Run `console.log(Audio.isInitialized, Audio.audioContext.state)` — should print `true "running"`. + +Open browser DevTools console. Load index.html. Run `console.log(typeof Audio, Audio.isInitialized)` — should print `"object" false`. Press any key. Run `console.log(Audio.isInitialized, Audio.audioContext.state)` — should print `true "running"`. + grep -c "AudioContext\|webkitAudioContext" index.html && grep -c "isInitialized" index.html && grep -c "soundEnabled" index.html && grep -c "paddleHit\|wallHit\|score" index.html + Audio module exists in index.html. isInitialized is false on page load. After first keypress, isInitialized is true and audioContext.state is 'running'. @@ -248,6 +251,7 @@ Open index.html. Start a game (title → play → mode select → AI mode → pl 3. Score: let a point be scored — hear a low deep thud (clearly different weight from other sounds) 4. Sound off: go to Settings, set Sound to OFF, play a game — no sounds. Set Sound to ON — sounds return. 5. No audio on page load (before first keypress): DevTools > Console > `Audio.audioContext` should be null before pressing any key. + grep -c "Audio\.play('paddleHit')" index.html && grep -c "Audio\.play('wallHit')" index.html && grep -c "Audio\.play('score')" index.html Audio.play('paddleHit') fires on paddle1 and paddle2 collisions. Audio.play('wallHit') fires on top and bottom wall bounces. Audio.play('score') fires on each point scored. Toggling soundEnabled via settings correctly mutes/unmutes. AudioContext is null until first keydown.