Docs: record the three feedback rounds, decisions, and verification gotchas

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>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-07-12 18:33:50 +02:00
1 parent 2e5af224b8
commit 5d815a4fc8
2 files changed
+49 -14

No files matched your search

+25 -7
View File
@@ -38,14 +38,23 @@ Two runtime-only import cycles (documented in headers): input↔gameplay, zombie
Ball boys mop gore they pass. HUD shows THEM instead of CPU. Ball boys mop gore they pass. HUD shows THEM instead of CPU.
- Balance knobs in TUNE (T panel): zSpeed, zSpawnEvery, zMax, zSplatQ, zPushback. - Balance knobs in TUNE (T panel): zSpeed, zSpawnEvery, zMax, zSplatQ, zPushback.
## STATUS — plan v2 COMPLETE (phases 1–13 + feedback round, 2026-07-12) ## STATUS — plan v2 COMPLETE + three feedback rounds (2026-07-12)
Everything in PLAN.md is shipped: match structure (games/sets/changeovers, permadeath, Everything in PLAN.md is shipped: match structure (games/sets/changeovers, permadeath,
spawn director), bomb juice, new-balls weapon ladder (BOMB→TRIPLE→FIRE→GUN), enemy spawn director), bomb juice, new-balls weapon ladder (BOMB→TRIPLE→FIRE→GUN), enemy
roster (runner/brute/shield, sprites in assets), free-aim flicks (flick = aim + commits roster (runner/brute/shield), game-end sweep + 'GAME N' theater, an always-there
the special, tap = keep stock + auto-target), game-end sweep + 'GAME N' theater, an racket-zombie opponent, and the SUDDEN DEATH interlude (intro card, tennis-palette
always-there racket-zombie opponent, and the SUDDEN DEATH interlude (real line calls, lerp while the duel runs, real line calls, win = tin on the spot, lose = surge).
one duel per opponent, win = tin on the spot, lose = surge). PLAN.md records the Post-plan rounds added: TWO-STAGE serve aiming (touch = reticle + auto-lock, drag =
decisions and the tuning surface. Next: Oliver playtests and tunes via the T panel. aim, release = fire, drag-back = cancel; aimed serves commit specials, taps keep them),
the RAF-freeze fix (sweepCourt guts zombies[] under iterating loops → null guards
everywhere a kill can cascade + RAF rescheduled before update), instant absolute
machine-gun steering clamped to the visible court, RES 3 + flatter lens (camZ 42,
camF per orientation in fitViewport), 4-frame walk cycles (z_a/b/f 1–4), tiered gore
(GORE_MUL in zombies.js), generated stadium (x_crowd.png bounce-columns, x_ads.png
sponsor boards, umpire at UMP_X 5.6 — 7.1 was one pixel off-screen in portrait),
runner = glass cannon (any touch kills; runnerVMax cap), battery pass (TUNE.fps knob
default 60 — 30 was vetoed on feel; cached pile canvases). PLAN.md records all
decisions + next-arc candidates. Next: Oliver playtests and tunes via the T panel.
## PREVIOUS TASK — all four items from Oliver's feedback round are DONE and VERIFIED ## PREVIOUS TASK — all four items from Oliver's feedback round are DONE and VERIFIED
(serve cadence · flick-aim anywhere incl. over the net · zombie speed ramp · eaten): (serve cadence · flick-aim anywhere incl. over the net · zombie speed ramp · eaten):
@@ -115,5 +124,14 @@ gives clean manual stepping. `T.press('Space')` = tap. Dismiss the intro overlay
(setupPoint pins facing=1). (setupPoint pins facing=1).
- The scratchpad venv/scripts get wiped between sessions — recreate venv (requests+pillow) - The scratchpad venv/scripts get wiped between sessions — recreate venv (requests+pillow)
and slice.py lives only in scratchpad; its logic is described above if gone. and slice.py lives only in scratchpad; its logic is described above if gone.
- Don't trust single-sample gameplay sims; randomness (aiFlub 9%, aim error) needs ~12 runs. - Don't trust single-sample gameplay sims; randomness (aiFlub 9%, aim error) needs ~12 runs
(a 9/12 serve-return run is normal flub noise — re-run 24 before suspecting a regression).
- Synthetic touch tests: input.js only sets stick.moved in touchmove, so a
touchstart→touchend pair reads as a TAP — always dispatch a touchmove between them.
- Contact/kill tests must step 1/60: pellets at 26 m/s tunnel past 0.55m radii at
coarser steps and kills silently don't happen (looks exactly like a bug).
- preview_start autoPort only yields a fresh origin if the configured port is BUSY —
hold 8641 with a throwaway socket first, or you get stale cached modules again.
- Any loop over zombies[] whose body can kill (killZombie/splatter) can cascade into
sweepCourt and gut the array mid-iteration — keep the `if (!zb) continue` guards.
- Commit style: imperative summary + Co-Authored-By Claude line; push = deploy. - Commit style: imperative summary + Co-Authored-By Claude line; push = deploy.
+24 -7
View File
@@ -1,8 +1,10 @@
# PLAN — all phases shipped (v2 complete, 2026-07-12) # PLAN — all phases shipped (v2 complete + three feedback rounds, 2026-07-12)
Phases 1–13 are implemented, verified, and deployed. See git log for the per-phase Phases 1–13 are implemented, verified, and deployed, plus three post-plan feedback
record and HANDOFF.md for the current system map. This file now only records what rounds from Oliver's phone playtests (aiming rework, freeze fix + presentation,
was DECIDED, so nobody re-litigates it. 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 shape of the game (as shipped)
- **The scoreboard is the progression.** Waves = games (spawn director scales with - **The scoreboard is the progression.** Waves = games (spawn director scales with
@@ -23,11 +25,22 @@ was DECIDED, so nobody re-litigates it.
eatenR 0.9 sprite-overlap = eaten. eatenR 0.9 sprite-overlap = eaten.
## Feedback-round decisions (Oliver, 2026-07-12) ## Feedback-round decisions (Oliver, 2026-07-12)
- Zombies pass-through: resolved as (a) — touch HURTS (radius honest), not avoidance. - Zombies pass-through: resolved as (a) — touch HURTS (eatenR honest), not avoidance.
- Interlude frequency: currently every game won (fresh opponent each game). If it - 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 overstays its welcome, gate it to every 2nd opponent — one-line change in the
trigger (gameplay.js, `dueled`). trigger (gameplay.js, `dueled`).
- Multi-ball stays "one proper serve per fan" (triple serve), never rapid-fire. - 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) ## Tuning surface (T panel)
All pacing knobs are in config.js TUNE — spawn director (zSpawnEvery/Min/Step, zMax, All pacing knobs are in config.js TUNE — spawn director (zSpawnEvery/Min/Step, zMax,
@@ -36,5 +49,9 @@ zMaxCap), beats (changeoverT, gameBeatT), deliveries (ballChangeFirst/Every), ro
## If a next arc happens, candidates in rough order of value ## If a next arc happens, candidates in rough order of value
1. Balance pass from phone playtests (Oliver tunes, nothing to build). 1. Balance pass from phone playtests (Oliver tunes, nothing to build).
2. Boss variety: a second duel opponent type (sprite session first, as before). 2. PWA (manifest + icon + service worker, ~an afternoon) — full-screen home-screen
3. Meta between runs: unlock/records screen beyond best-run. 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.