The crowd is drawn again, in detail — and the stand now moves one spectator at a time

Oliver on the first pass: "the new lighter areas read as rather sloppy artwork.
please regenerate the crowd art and make it more detailed. also the animation
also looks pretty artificial. the flashes from the fotographs are too rare and
the whole thing somehow does not translate well to the other courts. also when
the opponent makes a point there is an aww-sample (which has an applaus trail)
so the crowd should still clap but more subtle."

The paint pass is deleted — recolouring blobs of an old drawing is not drawing,
and the reason it looked necessary was a wrong conclusion: the roll scripts read
OPENROUTER_API_KEY from the repo's .env, so the art could be rolled all along.

_crowdroll.py rolls the crowd itself: individually drawn spectators with hats,
sunglasses, drinks, cameras, flags and banners, empty seats, stairways, and
three zombies sitting in the middle of it behaving like furniture. ONE roll now
serves all three courts through a per-channel histogram match onto each court's
old palette, so anything the art gains shows up on clay and at night too.

_crowdpass.py keeps only what was empty stand in the seated roll and became a
person in the clap roll — the raised arms, 1.2% of the sheet — so the clap frame
cannot drift by construction, and writes a box around each pair of arms into
src/crowd.js. render.js raises ONE SPECTATOR AT A TIME out of that table, each
on their own period: the 16-column strip swap moved a seventeenth of the crowd
as a block, which is what read as machinery. crowd.pop is now a head count, so
the same code covers a dozen people and the whole stand, and past 0.75 the wave
travels person by person.

aww() sets a small crowd.pop of its own — the sample is a groan that settles
into applause, and the stand has to match what you can hear. flashEvery 5.0 ->
1.9, because at a five-second mean over a stand this wide nobody ever saw one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-21 13:30:34 +02:00
1 parent 74afd5988c
commit 5f53a686c8
14 files changed
+499 -398

No files matched your search

+5 -3
View File
@@ -285,11 +285,13 @@ export const TUNE = {
// acknowledged that the match had changed; now he comments on it, disapprovingly.
racketHpPerGame: 0.12, // the racket zombie stiffens as the run goes on (floored into whole hp)
// CAMERA FLASHES IN THE STAND (render.tickFlashes). MEAN seconds between them — the actual gap is
// jittered 0.35x..1.95x so they never tick, and halved again while the crowd is cheering. Turn
// flashEvery UP to quieten them; it is the one knob. Life is deliberately shorter than a frame
// jittered 0.35x..1.95x so they never tick, and shortens with the size of whatever the crowd is
// reacting to (crowd.pop). Turn flashEvery UP to quieten them; it is the one knob. It was 5.0
// and Oliver could not see them at all — "the flashes from the fotographs are too rare" — which
// at a mean of five seconds, jittered, in a stand this wide, is not surprising. Life is deliberately shorter than a frame
// pair at 60 fps would need: a flash you can look AT is a light, a flash you only catch is a
// photograph being taken.
flashEvery: 5.0,
flashEvery: 1.9,
flashLife: 0.16,
// ...and how often ONE column of the stand gets to its feet on its own when nothing is being
// cheered (render's drawClapColumns). Between points the crowd used to be a photograph. This is