The blood you have left, the bodies behind you, and a face for staging

Three things, all in service of the match reading as its own mode:

BLOOD, COUNTED. The vignette says "worse" and never says "how many". One pip
per hit left, top-right beside the board, in the panel language the game/sets
bar already uses; the last two breathe. Pips rather than a bar on purpose —
the pool is 4 or 8, and a smooth readout of a small integer is the exact
ambiguity being fixed.

OPPONENTS FELLED IS THE MEASURE (handoff slice 1). Blood-only scoring means a
lost game costs nothing but the blood already spent, so games survived is not
the achievement. The in-play bar prints OPPONENT n · m FELLED instead of the
game/sets line, the death screen says BLED OUT / FELLED n OPPONENTS · m GAMES,
and it keeps its own matchBest — drillBest's pattern. The kills-to-next-point
pips are hidden in a match: nothing there is killed for points, and they were
colliding with the new line anyway.

STAGING WEARS A DIFFERENT ICON. Both builds live on the same phone and two
identical bloody tennis balls is a coin toss. Driven by HOSTNAME, not by the
branch — the block is identical on staging and main, so it never conflicts on
a merge and never has to be remembered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-12 08:53:02 +02:00
1 parent a54cfa5f4f
commit 8011186cda
10 files changed
+113 -9

No files matched your search

+11
View File
@@ -302,6 +302,17 @@ export function killPlayer() {
// runGames/sets/splatT are all still intact at this point.
const b = endRun(G.runGames, G.sets[0], G.splatT);
G.best = b; G.newBest = b.newBest; // b is {games, sets, newBest}; render reads games/sets
// THE MATCH MEASURES SOMETHING ELSE. Blood-only scoring (model A) means a lost game costs nothing
// but the blood already spent, so "games survived" is not the achievement — OPPONENTS FELLED is.
// Kept on G.match (which survives to the death screen; restartRun is what clears it) with its own
// localStorage best, the pattern drillBest already set. Games ride along as the length of the run.
if (G.match) {
const felled = G.match.opp - 1;
let best = 0;
try { best = Number(localStorage.getItem('matchBest')) || 0;
if (felled > best) localStorage.setItem('matchBest', String(felled)); } catch {}
G.match.felled = felled; G.match.best = best; G.match.newBest = felled > best;
}
}
// One hostile ball, lobbed at where the player is standing. `spread` fans a volley sideways.