PLAN.md: two-stage aiming, runner-glass, fps-60, and no-engine decisions added to the don't-re-litigate list; PWA/App Store noted as a next-arc candidate. HANDOFF.md: status covers the post-plan rounds; gotchas gain the synthetic-touch, 1/60-stepping, port-hold, and zombies[]-mutation lessons. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
58 lines
3.8 KiB
Markdown
58 lines
3.8 KiB
Markdown
# PLAN — all phases shipped (v2 complete + three feedback rounds, 2026-07-12)
|
||
|
||
Phases 1–13 are implemented, verified, and deployed, plus three post-plan feedback
|
||
rounds from Oliver's phone playtests (aiming rework, freeze fix + presentation,
|
||
aesthetics/stadium, runner + battery). See git log for the per-round record and
|
||
HANDOFF.md for the current system map. This file now only records what was DECIDED,
|
||
so nobody re-litigates it.
|
||
|
||
## The shape of the game (as shipped)
|
||
- **The scoreboard is the progression.** Waves = games (spawn director scales with
|
||
G.runGames), 6 games = a set = a horde, odd games end in changeovers, deliveries
|
||
follow the new-balls rule. Permadeath: eaten = run over, best run persisted.
|
||
- **Game-end theater**: at every game end the surviving wave collapses (sweepCourt),
|
||
a real beat plays (gameBeatT / changeoverT), and 'GAME N' announces the next wave.
|
||
- **An opponent, always**: every game you win spawns a racket zombie if none is alive.
|
||
With the court clear and an un-dueled opponent waiting, the umpire restores order:
|
||
SUDDEN DEATH — one point under real tennis line calls. Win = the next tin on the
|
||
spot; lose = a game on their scoreboard + a 5-shambler surge. One duel per opponent.
|
||
- **Weapon ladder** (deliveries cycle): BOMB → TRIPLE → FIRE → GUN. One tin at a time.
|
||
Specials fire ONLY on deliberate serves: flick = aim + commit, tap = keep the stock.
|
||
- **Free-aim**: a flick maps to a landing point (length = depth, zSnap magnetism);
|
||
taps keep the auto-target assist.
|
||
- **Roster**: runner (set 1 game 3+, shriek, solo), brute (set 2, hp 2, pushback-proof),
|
||
shield zombie (set 3, chair blocks front, stagger = kill window). Touch is honest:
|
||
eatenR 0.9 sprite-overlap = eaten.
|
||
|
||
## Feedback-round decisions (Oliver, 2026-07-12)
|
||
- Zombies pass-through: resolved as (a) — touch HURTS (eatenR honest), not avoidance.
|
||
- Interlude frequency: currently every game won (fresh opponent each game). If it
|
||
overstays its welcome, gate it to every 2nd opponent — one-line change in the
|
||
trigger (gameplay.js, `dueled`).
|
||
- Multi-ball stays "one proper serve per fan" (triple serve), never rapid-fire.
|
||
- Serve aiming is TWO-STAGE: touch shows the reticle at once (auto-lock on the most
|
||
advanced zombie), drag aims, release fires, drag-back cancels. A flick is just a
|
||
fast drag now. Specials commit only on aimed serves; tap-toss keeps the stock and
|
||
the PERFECT power ceiling. Do not regress to blind flicks.
|
||
- Runner counter: GLASS CANNON (any ball contact kills it) + runnerVMax cap — NOT a
|
||
dedicated weapon (you'd never hold it when the shriek comes).
|
||
- fps default 60 — Oliver felt 30 immediately and vetoed it. The TUNE.fps knob stays
|
||
as an opt-in battery saver. Battery wins that DID stick: cached pile canvases,
|
||
matchMedia hoist, RAF rescheduled before update (also the freeze insurance).
|
||
- Engine port ruled out (third failed-rewrite risk; feel is the asset). If rendering
|
||
ever truly outgrows canvas 2D, swap ONLY render.js for a WebGL backend.
|
||
|
||
## Tuning surface (T panel)
|
||
All pacing knobs are in config.js TUNE — spawn director (zSpawnEvery/Min/Step, zMax,
|
||
zMaxCap), beats (changeoverT, gameBeatT), deliveries (ballChangeFirst/Every), roster
|
||
(runnerSpeed, bruteHp, shieldDown), aim (zSnap), stakes (eatenR).
|
||
|
||
## If a next arc happens, candidates in rough order of value
|
||
1. Balance pass from phone playtests (Oliver tunes, nothing to build).
|
||
2. PWA (manifest + icon + service worker, ~an afternoon) — full-screen home-screen
|
||
app, offline, keeps the instant deploy loop. Oliver is also interested in SELLING
|
||
it at 0.99 someday → that path is Capacitor + App Store (dev account €99/yr,
|
||
Apple as merchant of record); informational only so far, do not build unasked.
|
||
3. Boss variety: a second duel opponent type (sprite session first, as before).
|
||
4. Meta between runs: unlock/records screen beyond best-run.
|