The two dims stopped stacking, and centre court's crowd is graded off a lifted target

Oliver: "it is too dim to see anything on the centre court and the dark court."
Both were the same mistake — standBack was ADDED to a court's own dim instead of
being the default it falls back to. Centre court's crowd sheet is a night-lit
navy that is dark to begin with, and the night court dims the hard-court sheet
on top of that, so the pair of them went to mud.

standDim is now court.dim ?? TUNE.standBack, plus the rot. Centre court carries
a 0.06 of its own, the night court comes down 0.62 -> 0.5 (it no longer has the
base added to it), and clay and hard keep the 0.22 that was approved.

Centre court's sheet is also graded off a LIFTED target now — the old crowd it
matches sat at a mean luminance of 39 against clay's 96, dark enough to throw
the new roll's detail away before any dim ran. A 0.72 gamma on the target brings
the sheet to 60 and the faces come back.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-21 14:12:07 +02:00
1 parent 0250e9bd20
commit eab0a4e837
5 files changed
+29 -15

No files matched your search

+6 -5
View File
@@ -235,7 +235,7 @@ function farB(z) {
// Asset cache-buster — bump with main.js?v=N (see the img.src note below). EXPORTED because the
// menu screens hang <img> tags on the same files, and two copies of this number is one copy too
// many: the one that does not get bumped is the one that serves a cached 404.
export const SPRV = 145;
export const SPRV = 146;
// The boot bar in main.js watches this. Nothing here CHANGES when things load — every sprite was
// already requested at import — it just makes the wait visible and holds the menu back until the
// last sheet has landed. See the onerror note below for the other half of "sometimes missing".
@@ -420,14 +420,15 @@ function tickFlashes(standsBottom) {
ctx.globalAlpha = 1;
}
// How dark the STAND is: `TUNE.standBack` (every court, always — the stand is scenery a long way
// behind the court and should not compete with it) plus the court's own night (`dim` on its COURTS
// row, 0 everywhere but the night court) plus the rot the splatter palette brings with it. ONE function because it is applied
// How dark the STAND is: the court's own `dim` if it names one (centre court's crowd sheet is
// already night-dark, the night court is darker still), otherwise `TUNE.standBack` — the stand is
// scenery thirty metres back and should not compete with the court — plus the rot the splatter
// palette brings with it. ?? not ||: a court that says 0 means 0. ONE function because it is applied
// in two places and they must agree exactly — the cached sheet and the live clap columns drawn over
// it. Two copies of this number is a stand whose clapping columns pop brighter than the rest of it,
// which is the same class of bug as the crowd frames drifting apart. Capped: past ~0.85 the stand
// is a black rectangle and the applause stops reading at all.
const standDim = pt => Math.min(0.88, TUNE.standBack + (court.dim || 0) + 0.26 * pt);
const standDim = pt => Math.min(0.88, (court.dim ?? TUNE.standBack) + 0.26 * pt);
// THE STAND MOVES IN COLUMNS, and the sheets are cut to match: `assets/_crowdpass.py` guarantees
// the clap frame is pixel-identical to the seated one EXCEPT inside blobs that each sit inside ONE