Files
gijs_pong/.planning/phases/02-core-gameplay/02-CONTEXT.md
2026-03-10 20:50:44 +01:00

4.0 KiB

Phase 2: Core Gameplay - Context

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

## Phase Boundary

Add scoring system, second paddle (human Player 2 + AI opponent with 3 difficulty levels), and match-end condition. Phase 3 adds real UI screens — Phase 2 delivers a fully playable game using temporary on-canvas UI. No visual effects, power-ups, or menus yet.

## Implementation Decisions

Mode Activation (temporary — Phase 3 replaces with real screens)

  • Key press at game start: press '1' for Solo vs AI, press '2' for 2-Player local
  • Difficulty selected by key press before match: press '1' for Easy, '2' for Medium, '3' for Hard
  • This temporary selection state lives in GameState (e.g. GameState.mode, GameState.difficulty)
  • Phase 3 wires its mode select screen to set these same GameState values — no refactor needed

Match End (temporary — Phase 3 replaces with real game-over screen)

  • On-canvas winner text: "Player 1 Wins! Press R to restart" (or "AI Wins!")
  • R key resets state and returns to mode/difficulty key selection
  • Phase 3 replaces this on-canvas message with its game-over screen

Target Score

  • First to 7 points wins
  • Stored as a constant in GameConfig (WIN_SCORE: 7) for easy tuning later

Ball Re-serve After Score

  • ~1 second pause to let the score update register visually
  • Ball auto-serves after the pause — no player input required
  • Server direction: alternates or goes to the player who just scored (Claude's discretion)

AI Strategy

  • Predictive interception: AI calculates the ball's y-position when it reaches the AI's x-position, then moves toward that target
  • Handles wall bounces in the prediction (ball trajectory traced to AI x, accounting for reflections)

AI Difficulty via Reaction Delay + Speed Cap

  • Easy: slow max paddle speed + late reaction start (ball must cross a threshold before AI begins tracking)
  • Medium: moderate speed + small reaction delay
  • Hard: fast speed + minimal reaction delay — not perfect, still beatable with skill
  • All values stored in GameConfig as named difficulty presets (e.g. AI_EASY, AI_MEDIUM, AI_HARD objects)

Claude's Discretion

  • Exact speed/delay values per difficulty (tune for feel after initial implementation)
  • How ball serves direction is chosen after scoring
  • Score display typography and positioning (on-canvas, minimal)
  • Whether prediction re-calculates every frame or on a throttled interval
## Specific Ideas
  • No specific requirements — open to standard approaches

<code_context>

Existing Code Insights

Reusable Assets

  • GameState.paddle1: has x, y, width, height, speed, color — paddle2 should mirror this structure
  • Input.getVerticalInput(): returns -1/0/1 for Player 1 (W/S) — add getVerticalInput2() for Up/Down arrows
  • Physics.update(deltaTime): currently handles ball + paddle1 movement — extend to handle paddle2 (human or AI branch)
  • GameConfig: central constants object — add WIN_SCORE and AI difficulty presets here
  • Renderer.drawRect() / Renderer.drawCircle(): reuse for drawing paddle2, score text, etc.

Established Patterns

  • Module-object pattern: all new logic goes into existing objects (Physics, GameState, Input) or a new AI object
  • GameLoop.main() calls Physics.update() then Renderer.* — AI update should run inside Physics.update or a dedicated AI.update call before rendering
  • Single HTML file — all additions stay in index.html

Integration Points

  • Physics.update(deltaTime) is where paddle movement and collision live — Phase 2 adds paddle2 movement (human or AI) here
  • GameState needs score fields (score1, score2), match state (playing/paused/gameover), mode, and difficulty
  • GameLoop.main() needs a check after Physics.update to detect scoring (ball passes left/right edge) and trigger pause → re-serve cycle

</code_context>

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

Phase: 02-core-gameplay Context gathered: 2026-03-10