87 lines
6.6 KiB
Markdown
87 lines
6.6 KiB
Markdown
# 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 `<title>`, 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).
|