Let the player choose a court before the match

Three courts, picked on a second start-screen stage: CENTRE COURT (grass),
TERRE ROUGE (clay) and THE SLAB (hard). A court is a row in config.COURTS and
four PNGs — render() never learns their names.

Each row carries two palettes, because every court still rots: what "drained"
means on orange clay is not what it means on green lawn. Mow stripes became a
flag rather than a colour — recolouring the lawn and leaving the bands on still
read as grass. Bounce is two numbers copied into TUNE on selection, so the three
bounce sites in gameplay.js and the T panel stay untouched: grass skids low and
fast, clay sits up and drags, hard is the old baseline.

Per-court crowd sheets and ad strips. Each court's clap frame is generated from
its OWN seated sheet, not from x_crowd2 — pairing one court's crowd with
another's applause cross-fades between two different crowds.

The picker is a second panel in the existing #intro overlay, rows built from the
table. Last pick is remembered and comes up pre-highlighted; 1..N or Enter on a
keyboard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-01 10:25:30 +02:00
1 parent 6378ff2a1b
commit fa30fb94c4
15 files changed
+166 -36

No files matched your search

+33
View File
@@ -409,6 +409,39 @@ Known generator quirks, all still true:
- **Colour-match any regenerated frame** of an existing pair before shipping: fit a per-channel
linear map onto the original's mean and sd, then verify with a mean-difference number.
## Session log: court types (2026-08-01)
Three courts, picked on a second start-screen stage. A court is pure DATA — `COURTS` in config.js
— so adding one is a table row plus four PNGs, never a change to `render()`.
- **Each court carries TWO palettes, not one.** Every court still rots when the horde arrives, so
the row holds a `tennis` palette and a drained `splatter` one and `palette()` lerps between them
exactly as before. A single palette plus a global rot filter was the tempting shortcut and it is
wrong: what "drained" means is different on orange clay than on green lawn.
- **Mow stripes are a flag, not a colour.** `court.stripes`. Recolouring the lawn to terracotta and
leaving the bands on still read as grass — the banding is the grass tell, not the hue.
- **Physics is two numbers copied into TUNE on selection** (`selectCourt` in state.js). Grass skids
low and fast (0.50/0.84), clay sits up and drags (0.66/0.70), hard is the old baseline
(0.58/0.78). Doing it this way means the three bounce call sites in gameplay.js never learn that
courts exist, and the T panel still edits the live values.
- **A court's clap frame must come from its own sheet.** `x_crowd`/`x_crowd2` are a matched pair —
same people, arms up. Pairing court A's seated sheet with court B's clap sheet cross-fades
between two different crowds, which is the flicker class this codebase keeps re-learning. The
clay/hard clap sheets were generated FROM their own seated sheet ("same image, arms raised"),
not from `x_crowd2`, for exactly this reason.
- **Ad-strip aspect is load-bearing.** `render()` draws the sheet at a fixed `AD_H` of 14 px and
derives tile width from the sheet's own aspect, so a strip that comes back 6:1 instead of 9:1
renders its lettering at half size and goes unreadable. The first clay roll was 6.34:1 and was
thrown away; re-rolling with `x_ads_h.png` as the input (already 9.27:1) fixed it. **Check the
aspect of a regenerated ad strip before installing it.**
- **The picker is DOM, not canvas** — a second panel inside the existing `#intro` overlay, rows
built from `COURTS` in main.js. Same Silkscreen card, no new `G.mode`, no canvas UI code. Last
pick is remembered in `localStorage` and comes up pre-highlighted; keys 1..N pick, Enter takes
the highlighted one.
Not done: clay ball-marks (the `gore` decal loop already draws flat ground ellipses, so a pale
scuff per bounce is one call), per-court bounce SOUND, per-court crowd density.
## Session log: the serve is the gesture (2026-08-01)
Oliver's notes on the art pass: the zombies are good, the runner "flickers very hard", and the