Earn the praise, and give the quiet face a shadow too

PERFECT fired on almost every serve, and it was not a threshold that had drifted
— it was the wrong test entirely. pullFrac CLAMPS at pullFull, so pullQuality is
exactly 1.0 for any pull of 130 px or more, and 130 px is an ordinary comfortable
thumb drag. "quality > 0.999" therefore meant "you pulled far enough", which is
not an achievement and is why it read as noise.

So hitServe takes `perfect` as its own argument now. The toss ritual keeps
earning it the honest way, on the 45 ms perfectMs window. The slingshot earns it
by STOPPING in a band at the top of the draw (pullFull..pullFull*perfectBand,
130-166 px) — a target you can miss, rather than a ceiling you cannot. The pull
already clicks when it crosses the splatter threshold; it clicks brighter when it
enters the band and goes silent when you pull past, so the window is learnable by
feel instead of being invisible skill.

And the word rotates: PERFECT, TEXTBOOK, IMMACULATE, OH LOVELY, UNPLAYABLE, SHOT
OF THE DAY. Cycled rather than random — the same word twice running is what makes
one read as a stuck HUD element rather than as praise. The umpire has still never
acknowledged the massacre, so a clean shot gets the line it would get at Wimbledon.

Also: the card band grew 72 -> 80 px, because the second sub line ended 4 px off
the bottom edge and looked like it had fallen out. And the quiet face floats as
much as the loud one does, so it gets the same 1 px shadow — the control hints,
the gesture-demo labels, the card subs, the modal body and prompt, the death
summary lines. The scoreboard and the rack keep theirs off: both already sit on
dark panels, and a shadow under 6 px type on a flat fill only smears it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-03 22:21:56 +02:00
1 parent 55c0f75c37
commit 9c7ee42bfa
6 files changed
+69 -29

No files matched your search

+13 -3
View File
@@ -331,9 +331,19 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
`stick.aimable` is false there, so the drag is still the absolute steer it always was.
- **Two type registers, and the register IS the message's category.** Silkscreen for the HUD, the
rack, the control hints and `RESUMING IN` — things you read at leisure. Bangers (`B()` in render)
for `SET`, `CHAPTER`, `EPIC!`, `PERFECT` and every free-floating flash — things shouted at you.
Free-floating text carries a 1px shadow (`shadowText`) and one shared y (`FLASH_Y`), because it
has no panel and has to survive the crowd, sunlit clay and blood behind it.
for `SET`, `CHAPTER`, `EPIC!`, the praise words and every free-floating flash — things shouted at
you. EVERY floating string goes through `shadowText`, both faces, because none of them has a panel
and all of them have to survive the crowd, sunlit clay and blood behind them. The scoreboard and
the rack are the two exceptions: they sit on their own dark panels, and a 1 px shadow under 6-8 px
type on a flat dark fill only smears it.
- **Praise is a narrow window, not a ceiling.** `pullQuality` SATURATES: `pullFrac` clamps at
`pullFull`, so every pull past 130 px is exactly quality 1.0 and the old `quality > 0.999` test
praised nearly every serve — *"it displays perfect a lot even when nothing special happened"*.
`hitServe` takes `perfect` as its own argument now: the toss ritual still earns it on the 45 ms
`perfectMs` window, the slingshot earns it by STOPPING in `pullFull..pullFull*perfectBand`. The
draw clicks brighter when you enter that band and goes quiet when you overshoot — without that
audible target it would be invisible skill. The word itself rotates through `PRAISE` (cycled, not
random: the same word twice running reads as a stuck HUD element, not as praise).
## Session log: the sidestep, and two type registers (2026-08-03)