# Implementation Plan — Times Table Invaders ## 1. Game name **Times Table Invaders** — a Space Invaders homage that conveys both multiplication practice and descending aliens. (Alternatives: "Alien Arithmetic", "UFO Down!", "Cosmic Times".) Used in ``, the welcome overlay, and the faded sky title. ## 2. Deliverables ``` /workspace/ ├── README.md ├── PLAN.md ← this plan ├── index.html ← single entry point (links style.css + game.js) ├── style.css ← layout, HUD, overlays, responsive rules └── game.js ← all logic; vanilla JS, classic <script> tag (no modules/build) ``` No dependencies, no build step; must work when `index.html` is opened directly (`file://`). ## 3. Technical decisions - **Scene on `<canvas>`** (stars, faded title, UFOs, ground, houses, cannon, laser, explosions): full cartoon control, easy particle effects, one render loop. - **HUD + overlays in DOM**: input / Fire button / score below the scene; welcome and game-over overlays. - **Fixed 3:4 portrait aspect** for the scene, centered and height-capped on desktop → responsive from phones to desktops with no layout branches. - **Virtual coordinate system** (~90 × 120 units) + one uniform scale + devicePixelRatio-aware backing store → resizing is trivial; all game logic is resolution-independent. - **rAF loop with delta time clamped to 50 ms** (prevents jumps after tab switches). - **localStorage** key `tti.leaderboard.v1` = JSON array of top-3 `{name, score}`; wrapped in try/catch for private browsing. ## 4. Architecture (game.js) - `CONFIG` object with every tunable: phase table, spawn/speed ramps, sizes, timings. - One `Game` state object: `ufos[]`, `stars[]`, `houses[]`, `particles[]`, laser/cannon animation state, score, elapsed time; states `WELCOME | PLAYING | GAME_OVER`. - Plain-function systems, each with update + draw: starfield, spawner/mover, difficulty, shot queue, input, leaderboard, renderer. ## 5. Game mechanics (precise) - **UFO generation**: pick table `b` from the currently unlocked set, multiplier `m` ∈ 2..12 (table 1 excluded entirely); display `b × m` or `m × b` (random order); store product. Radius ≈ 9 units; text sized to stay readable at a 360 px phone width. - **Motion**: `y += speed·dt` with per-UFO speed = phase base × rand(0.9–1.1); wobble `x = baseX + A·sin(ωt+φ)`, A ∈ [1.5, 3] units (the "ondulating trajectory"). - **No overlap**: on spawn, reject x positions within `r₁+r₂+2` of any live UFO; up to 8 retries, else defer the spawn. Multiplications always stay readable. - **Shooting**: on submit value `v`, all UFOs with product == v enter a shot queue (bottom-most first, ~200 ms apart = "rapid succession"); +1 score each. No match → cannon still fires as miss feedback. - **Game over**: any UFO's bottom reaches the ground line → freeze scene, show overlay. ## 6. Difficulty progression (elapsed time; all values tunable in CONFIG) | Phase | At | Tables added | Spawn interval | Fall speed | |---|---|---|---|---| | 1 | 0 s | 2, 10 | 4.0 s | 10 u/s | | 2 | 60 s | +4, 5 | 3.5 s | 12 u/s | | 3 | 150 s | +3, 7, 8, 9 (+6*) | 3.0 s | 14 u/s | | 4 | 300 s | +11, 12 | 2.6 s | 16 u/s | After phase 4: continuous gradual ramp — spawn interval eases down to a 1.4 s floor, fall speed rises toward ~40 u/s cap. \* Table 1 is excluded from all phases (user request). The README also omits table 6; assumption: **6 joins phase 3**. ## 7. UI spec - **Sky**: night gradient; ~90 stars regenerated each game with pulsating alpha (random phase/speed per star); faded game title centered in the sky (~7% white). - **Ground** (bottom strip of canvas): 3–5 simple cartoon houses randomized per game; cannon in the foreground, centered. - **Cannon animation**: on shot → recoil + muzzle flash; laser beam (bright core + wide glow) from barrel tip to target for ~150 ms per hit; explosion = 18–26 fading particles + expanding ring (~450 ms), UFO disappears quickly. - **HUD below the scene**: `[ input ] [ Fire ] [ score ]`. Input: `inputmode=numeric`, digits-only filter, hard cap at 3 digits (extras ignored), auto-focused on load/start/after each submit, Enter or Fire submits, field cleared after submit. Score counter sits next to the Fire button. - **Responsive**: scene width = `min(100%, height-derived)`; touch-friendly targets (≥44 px); works 360×640 → 1920×1080. ## 8. Leaderboard & screens - **Top 3** in localStorage. On game over, if score > 0 and qualifies (fewer than 3 entries or strictly greater than the lowest) → congratulation popup with a name field (≤16 chars, required) → insert at correct rank, evict lowest, persist. - **Welcome overlay**: game title, 2–3 line instructions, leaderboard table (rank / name / score, with "no scores yet" empty state), Start button → regenerates stars/houses, resets state, focuses input, starts the loop. ## 9. Implementation steps 1. Write this plan to `/workspace/PLAN.md`. 2. Scaffold `index.html` + `style.css` + `game.js` (layout, canvas, HUD, both overlays); verify layout in a browser. 3. Engine: virtual coords, DPR-aware resize handling, rAF loop with clamped dt, state machine. 4. Background: starfield + pulsation, faded title, ground/houses, cannon idle drawing. 5. UFOs: phase-based spawning, wobble motion, overlap-safe placement, cartoon UFO rendering with `a × b`. 6. Shooting: input rules, match detection, sequential shot queue, laser/recoil/flash, explosion particles, score updates. 7. Post-phase-4 gradual speed/spawn ramp. 8. Game-over flow + leaderboard persistence + name-entry popup. 9. Welcome overlay wiring (Start, leaderboard display). 10. Responsive pass + edge cases (empty input, rapid double-Enter, resize mid-game, `file://`), then run the QA checklist. ## 10. QA checklist (manual) - Opens from `file://`, no console errors, vanilla JS only - Correct answer destroys matching UFO(s); multiple matches all destroyed in sequence; +1 each - Wrong/empty input: cannon fires, nothing hit, field cleared and refocused - Digits-only enforcement; >3 digits ignored; Enter and Fire both submit - Early game shows only 2/10 tables; later phases add tables; late game gets faster - UFOs never overlap illegibly; wobble visible; stars pulse and differ per game; faded title present - Cannon animates on shot; explosions quick - A landed UFO ends the game - Top-3 popup asks for a name; leaderboard ranks/saves/evicts correctly and persists across reloads - Playable at phone and desktop sizes ## Flagged assumptions 1. Name: **Times Table Invaders** (alternatives listed in §1). 2. Table 6 included in phase 3 (the README's phase list omits it); table 1 excluded from all phases. 3. No audio — out of scope (possible WebAudio stretch goal).