From 57357c78657b7ac34b78c4c05157b2a88b483e99 Mon Sep 17 00:00:00 2001 From: Oliver Rieger Date: Tue, 11 Aug 2026 19:07:28 +0200 Subject: [PATCH] PROJECT.md: the stream pass, and the two test traps it cost me The doc edit threw on its second assert last commit, so the code shipped without its notebook entry. Also records the two ways a drill test lies to you: one that never shoots gets caught and the sweep looks like a stalled stream (use eatenR = 0), and zombies[i] is not the same body across frames because the array shifts at the baseline. Co-Authored-By: Claude Opus 5 --- PROJECT.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/PROJECT.md b/PROJECT.md index fd439ea..9d4e960 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -551,6 +551,53 @@ came from (patch `decodeAudioData`, pair it with the pending fetch URL) and coun `AudioBufferSourceNode.start` — then "did two umpire lines overlap" is a real question with a real answer. Counting requests measures loading; counting `start()` measures sound. +**FOURTH PASS — THE STREAM. Oliver played it again:** *"daniel announcing is maximum annoying"* · +*"don't let the rush in position just let them coming from the back in steady speed.. try to space +them not too close"* · *"when one combination is done just let the new one in.. in a continuous +stream that increases in speed and difficulty"* · *"the rounds can stay, they should be continuous"*. + +**The ROUND survives as the unit; every SEAM around it is deleted.** No walk-on to a mark, no +announcement beat, no between-rounds pause, no deal. Bodies walk in from the far baseline forever, +and a round is a colour combination drawn from whoever is on court — finish one and the next is +drawn in the same frame, off the same rolling population. The bodies you were ignoring a second ago +are the ones being called now, which is a better decoy than the old fixed-batch decoy ever was. + +- **Daniel is gone from this mode.** At ~0.8 s a word he needed four seconds to read a list of four, + and with rounds running continuously that is a man talking over the entire game. Each colour has a + PITCH now (`DRILL_COLS.tone`) and a round announces itself as a four-note figure in half a second + (`blip()` in audio.js — a plain triangle with a 12 ms attack, because a hard attack clicks). + `TUNE.drillTones` 0 makes it silent. The `drill_*.m4a` recordings stay in assets: cheap to keep, + and a slower variant of the mode could want them back. +- **`PLACEMENTS` is deleted along with the marks.** Nothing rushes anywhere and nothing stops, so + there are no shapes to place — the geometry now comes from lane choice at spawn plus the depth the + stream naturally strings bodies out into. That is a net DELETION of the fanciest code in the file. +- **Spacing is best-of-9 lane sampling** against everyone still in the back half, not a retry loop: + a hard minimum would silently stall the stream at exactly the moment it is meant to be getting + harder, which reads as the mode dying. +- **A DRILL BODY HOLDS ITS LANE**, and this was the fix the screenshot forced. `updateZombies` homes + bodies onto the player's x once they cross the net — a gore-mode behaviour — so they arrived nicely + spread and then bunched into an unreadable knot right in front of you. Spawn spacing cannot survive + that. Their lane IS the puzzle here (it decides what screens what), so drill bodies walk it straight + in with nothing but the wobble. They still reach you; the lane runs past the baseline. +- **One ramp, off TIME SURVIVED** (`TUNE.drillRampT` 210 s), driving walk speed, spawn gap and round + length together. Time, not rounds won: a round-counted ramp cannot escalate while you stand still. + Speed is stamped per body AT SPAWN, so the ramp shows up as new arrivals outpacing the ones already + walking rather than as the whole court accelerating out from under you. +- **The empty-court watchdog is gone too, and nothing replaced it.** With a stream there is no state + to be stuck in: `if (!d.seq.length) newRound(d)` covers the start, a completion, a double fault and + "everything named got killed by something else". One line replaced a repair path, a cooldown and a + log entry. +- Movement is `updateZombies`' ordinary forward step now (bodies carry a real `zb.v`), so the stride + animates off distance covered for free — the round-based version drove them by hand because they + had marks to stop at. +- Tests rewritten around the stream (27): arrivals keep coming and are spaced *after the walk in*, + lanes are held by identity, the ramp raises speed / arrival rate / round length, a finished round + rolls into the next in the same frame, and being caught costs the point and the court but not the + run. **Two test traps worth remembering**: a drill test that never shoots WILL be caught (~28 s to + walk the court) and the sweep looks exactly like a stalled stream — use `TUNE.eatenR = 0`, the + established soak trick; and never compare `zombies[i]` across frames, because bodies despawn at the + baseline and the array shifts (that read as a 1.5 m lane drift that never happened). + **Open, and every one of them is Oliver's call after he plays it:** 1. **A ball that carries through the lane can complete two steps at once** — measured: one serve killed bib 1 and then bib 2 standing behind it, banking two correct steps in one shot. Had the @@ -559,11 +606,10 @@ answer. Counting requests measures loading; counting `start()` measures sound. pierce has to stop on a drill kill. Do not patch it silently — it is a design fork, not a bug. **More likely to come up now** that `column` deliberately stacks bodies in one lane. 2. ~~**The tap aims itself.**~~ CLOSED by the second pass above — the snap is gone, you aim. -3. Difficulty climbs on sequence LENGTH today (`drillSeq` 3 -> `drillSeqMax` 4, +1 every 3 rounds) - and is deliberately capped low: a longer list is a memory test and memory tests fatigue. The - `PLACEMENTS` table is where the real headroom is, and it is currently drawn at random with fixed - weights — nothing ramps. Weighting it toward `column`/`cluster` as the rounds go on is the - obvious next dial and is about four lines. +3. ~~Difficulty climbs on sequence LENGTH.~~ CLOSED by the stream — one ramp on time survived now + drives walk speed, arrival rate and round length together. What is still NOT ramped is how often + the called order fights the geometry; with lanes held, that is a question of which bodies get + called rather than of where they stand. 4. Nothing is wired to tennis scoring, the menu or the run, and the mode has no ending. That is the next job IF the answer to "tense or noisy?" comes back tense. 5. **A shambler takes two splat-quality hits.** In a mode where every shot is aimed by hand that is