diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 3a58bf5..f29ca78 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -13,8 +13,8 @@ Requirements for initial release. Each maps to roadmap phases. - [x] **CORE-02**: Each player controls a paddle that deflects the ball - [x] **CORE-03**: Ball angle changes based on where it hits the paddle (not purely geometric) - [x] **CORE-04**: Ball speed increases gradually over the course of a match -- [ ] **CORE-05**: Player scores a point when ball passes opponent's paddle -- [ ] **CORE-06**: Match ends when a player reaches the target score (first to N points) +- [x] **CORE-05**: Player scores a point when ball passes opponent's paddle +- [x] **CORE-06**: Match ends when a player reaches the target score (first to N points) - [x] **CORE-07**: Player 1 controls paddle with keyboard (W/S keys) - [x] **CORE-08**: Player 2 controls paddle with keyboard (Up/Down arrow keys) @@ -102,8 +102,8 @@ Which phases cover which requirements. Updated during roadmap creation. | CORE-02 | 1 | Complete | | CORE-03 | 1 | Complete | | CORE-04 | 1 | Complete | -| CORE-05 | 2 | Pending | -| CORE-06 | 2 | Pending | +| CORE-05 | 2 | Complete | +| CORE-06 | 2 | Complete | | CORE-07 | 1 | Complete | | CORE-08 | 2 | Complete | | AI-01 | 2 | Complete | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 5ca1c36..3091ad0 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -10,7 +10,7 @@ ## Phases - [ ] **Phase 1: Foundation** - Game loop, rendering, input, physics, collision -- [ ] **Phase 2: Core Gameplay** - AI opponent, second paddle, score tracking, state management +- [x] **Phase 2: Core Gameplay** - AI opponent, second paddle, score tracking, state management (completed 2026-03-10) - [ ] **Phase 3: Complete Experience** - Screens, menus, audio, pause functionality - [ ] **Phase 4: Polish & Depth** - Visual effects, power-ups, multiple arenas - [ ] **Phase 5: Release** - Performance tuning, cross-browser testing, final validation @@ -60,7 +60,7 @@ Plans: 5. Match ends when a player reaches target score with clear game-over state 6. No memory leaks or event listener cleanup issues after multiple rounds -**Plans:** 1/2 plans executed +**Plans:** 2/2 plans complete Plans: - [ ] 02-01-PLAN.md — Paddle2, AI system (predictive interception + 3 difficulty levels), extended Input/Physics @@ -142,7 +142,7 @@ Plans: | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| | 1. Foundation | 1/2 | In Progress | — | -| 2. Core Gameplay | 1/2 | In Progress| | +| 2. Core Gameplay | 2/2 | Complete | 2026-03-10 | | 3. Complete Experience | 0/? | Not started | — | | 4. Polish & Depth | 0/? | Not started | — | | 5. Release | 0/? | Not started | — | diff --git a/.planning/STATE.md b/.planning/STATE.md index 179ecc3..96aa710 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,13 +3,13 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: unknown -stopped_at: Completed 02-01-PLAN.md -last_updated: "2026-03-10T20:07:22.163Z" +stopped_at: Completed 02-02-PLAN.md +last_updated: "2026-03-10T20:20:14.256Z" progress: total_phases: 5 - completed_phases: 1 + completed_phases: 2 total_plans: 4 - completed_plans: 3 + completed_plans: 4 --- # STATE: Super Pong Next Gen @@ -26,12 +26,12 @@ progress: | Attribute | Value | |-----------|-------| | **Phase** | 02-core-gameplay | -| **Plan** | Plan 1/2 — COMPLETE | -| **Status** | Phase 02 in progress — paddle2, AI module, predictive ray-cast, 3 difficulty levels done | -| **Progress** | 75% (3/4 plans complete; Phase 1 complete, Phase 2 plan 1 complete) | +| **Plan** | Plan 2/2 — COMPLETE | +| **Status** | Phase 02 COMPLETE — full playable Pong with state machine, scoring, AI, and match-end | +| **Progress** | 100% (4/4 plans complete; Phase 1 complete, Phase 2 complete) | ``` -[████████░░] 75% — Phase 2: 1/2 plans complete +[██████████] 100% — Phase 2: 2/2 plans complete ``` --- @@ -49,6 +49,7 @@ progress: --- | Phase 02-core-gameplay P01 | 2min | 2 tasks | 1 files | +| Phase 02-core-gameplay P02 | 5min | 2 tasks | 1 files | ## Accumulated Context @@ -92,6 +93,12 @@ progress: 14. **Physics.onResize() calls init() for full reposition:** Ensures paddle2 (and paddle1) are properly repositioned on window resize rather than just updating width/height dimensions. +15. **GameLoop owns scoring/serve, Physics owns physics:** Scoring detection is in GameLoop.main() after Physics.update() — Physics no longer auto-resets ball on out-of-bounds. This separation allows GameLoop to increment scores before re-serving. + +16. **pauseTime on GameLoop, not GameState:** Post-score pause timer is transient per-point timing; storing it on GameLoop (not GameState) keeps GameState clean for restart. + +17. **Ball hidden during 'scored' pause:** drawCircle guarded by `gs.gameState !== 'scored'` — gives players a visual signal that a point was scored before the ball re-serves. + ### Coverage Validation **Total v1 Requirements:** 37 @@ -120,12 +127,12 @@ progress: ### What Just Happened -Phase 02 Plan 01 executed: paddle2 added to GameState (mirrors paddle1 structure), Input extended with ArrowUp/ArrowDown + named handler refs + cleanup(), AI module added with predictive ray-cast interception (wall-bounce simulation) and 3 difficulty presets (AI_EASY/MEDIUM/HARD). Physics._checkPaddle2Collision() added with 5-zone deflection sending ball LEFT. Physics.update() extended with paddle2 movement branch. Requirements CORE-08, AI-01, AI-02, AI-03, AI-04 satisfied. +Phase 02 Plan 02 executed: GameLoop.main() rewritten with full state machine (modeSelect → diffSelect → playing → scored → gameover). Scoring detection added to GameLoop (after Physics.update()). Physics.update() auto-reset removed so GameLoop owns scoring. Mode/difficulty selection screens rendered on canvas. Winner overlay with R-key restart. pauseTime field added to GameLoop for 1s post-score pause. Phase 1 debug speed text removed. Requirements CORE-05, CORE-06 satisfied. Phase 2 complete. ### What Comes Next -1. Execute Phase 2 Plan 02 — mode selection UI, scoring system, win/game-over states, ball tunneling safeguards -2. Continue through phases 3-5 after Phase 2 complete +1. Execute Phase 3 — menus, audio (WebAudio), pause/resume screen +2. Continue through phases 4-5 after Phase 3 complete ### Known Blockers @@ -137,7 +144,7 @@ None. ### Last Session -Stopped at: Completed 02-01-PLAN.md +Stopped at: Completed 02-02-PLAN.md --- diff --git a/.planning/config.json b/.planning/config.json index b3735bc..8403544 100644 --- a/.planning/config.json +++ b/.planning/config.json @@ -8,6 +8,7 @@ "research": true, "plan_check": true, "verifier": true, - "nyquist_validation": true + "nyquist_validation": true, + "_auto_chain_active": false } -} +} \ No newline at end of file diff --git a/.planning/phases/02-core-gameplay/02-01-SUMMARY.md b/.planning/phases/02-core-gameplay/02-01-SUMMARY.md index 65b5ab6..1b664f6 100644 --- a/.planning/phases/02-core-gameplay/02-01-SUMMARY.md +++ b/.planning/phases/02-core-gameplay/02-01-SUMMARY.md @@ -104,3 +104,10 @@ None - no external service configuration required. --- *Phase: 02-core-gameplay* *Completed: 2026-03-10* + +## Self-Check: PASSED + +- index.html: FOUND +- 02-01-SUMMARY.md: FOUND +- Commit a2f0bc3 (Task 1): FOUND +- Commit 398bc4a (Task 2): FOUND diff --git a/.planning/phases/02-core-gameplay/02-02-SUMMARY.md b/.planning/phases/02-core-gameplay/02-02-SUMMARY.md new file mode 100644 index 0000000..cbb6959 --- /dev/null +++ b/.planning/phases/02-core-gameplay/02-02-SUMMARY.md @@ -0,0 +1,116 @@ +--- +phase: 02-core-gameplay +plan: 02 +subsystem: ui +tags: [canvas, game-loop, state-machine, scoring, pong, vanilla-js] + +# Dependency graph +requires: + - phase: 02-core-gameplay/02-01 + provides: paddle2, AI module, predictive ray-cast, 3 difficulty presets, Input cleanup + +provides: + - Full game state machine (modeSelect → diffSelect → playing → scored → gameover) + - Scoring detection (ball exits left/right edge → score1/score2 increment) + - 1-second post-score pause with auto-serve + - Match-end condition (first to WIN_SCORE=7 wins) + - Mode selection UI (1=Solo vs AI, 2=2-Player) + - Difficulty selection UI (1=Easy, 2=Medium, 3=Hard) + - Winner overlay with "Press R to play again" + - R-key restart (scores reset, back to modeSelect) + - Center divider dashed line rendering + - Score numbers rendered on canvas (top-left / top-right) + +affects: [03-menus-audio, 04-effects-powerups, 05-polish-release] + +# Tech tracking +tech-stack: + added: [] + patterns: + - State machine pattern via gameState string field driving render/update branches + - GameLoop owns scoring detection; Physics.update() no longer owns out-of-bounds reset + - pauseTime field on GameLoop tracks scored-state start for 1s serve delay + +key-files: + created: [] + modified: + - index.html + +key-decisions: + - "GameLoop owns scoring/serve, not Physics: removed auto-reset from Physics.update() so GameLoop can increment scores before calling serveBall()" + - "modeSelect state renders full-screen prompt and returns early — no physics/paddles rendered until game starts" + - "pauseTime stored on GameLoop object (not GameState) — transient timing data that doesn't need to survive restart" + - "Ball hidden during 'scored' pause state (gameState !== 'scored' guard on drawCircle) — clean visual signal to players" + - "2-Player mode skips diffSelect entirely — straight to playing after pressing 2" + - "Winner identity set on GameState.winner as 'player1' | 'ai' | 'player2' — AI win labeled 'AI', not 'Player 2'" + +patterns-established: + - "State machine pattern: gameState string drives render/update branches in GameLoop.main()" + - "GameLoop owns game-level events (scoring, match end, serve); Physics owns physics-level events (collision, deflection)" + +requirements-completed: [CORE-05, CORE-06] + +# Metrics +duration: ~5min (continuation after human-verify checkpoint) +completed: 2026-03-10 +--- + +# Phase 2 Plan 02: Core Gameplay State Machine Summary + +**Full game loop with state machine, mode/difficulty selection UI, scoring detection, 1s re-serve pause, match-end at 7 points, and R-key restart — all in a single index.html** + +## Performance + +- **Duration:** ~5 min +- **Started:** 2026-03-10T20:10:00Z +- **Completed:** 2026-03-10T20:15:00Z +- **Tasks:** 2 (1 auto + 1 checkpoint) +- **Files modified:** 1 + +## Accomplishments + +- Game state machine fully wired: modeSelect → diffSelect → playing → scored → gameover → modeSelect +- Scoring detection moved to GameLoop (after Physics.update()), Physics auto-reset removed — scores now correctly increment +- Mode/difficulty selection screens rendered on canvas with clear key prompts +- Winner overlay with player name and restart prompt; R-key cleanly resets all state +- Phase 1 debug speed text removed; center divider dashed line added + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: State machine — mode/difficulty selection, scoring, match end, and restart** - `77071a5` (feat) +2. **Task 2: Checkpoint: Verify Phase 2 complete gameplay** - approved by user (no code commit) + +## Files Created/Modified + +- `index.html` - GameLoop.main() rewritten with full state machine; Input._handleKeyDown extended with mode/difficulty/restart keys; Physics.update() out-of-bounds auto-reset removed; pauseTime field added to GameLoop + +## Decisions Made + +- GameLoop owns scoring detection and serve calls — Physics.update() no longer has out-of-bounds reset. This separation is critical: if Physics auto-resets, GameLoop never sees the scoring condition. +- Ball hidden during `scored` pause via guard on drawCircle — cleaner player feedback than showing stationary ball. +- 2-Player mode bypasses difficulty selection entirely (no AI to configure). +- pauseTime stored on GameLoop (not GameState) — it's transient per-point timing that doesn't need to survive an R-key restart. + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- Phase 2 complete: full playable Pong with mode selection, AI opponent, scoring, match end, and restart +- Phase 3 (menus, audio, pause) can proceed — GameState fields (gameState, mode, difficulty, score1, score2, winner) are stable contracts +- No blockers + +--- +*Phase: 02-core-gameplay* +*Completed: 2026-03-10*