You pick your own kit and your own skin, and the blood stays red

Testers asked for some control over how their player looks. From behind — the
only way you ever see him — there are two things worth controlling, and neither
needs a single new asset: the kit and the skin are one hue-bucket pixel pass over
the sheets already loaded, cached per frame and built on first draw.

The buckets are measured, not guessed, and three neighbours had to be fenced off
one at a time: the shirt's warm HIGHLIGHTS (which spattered the man with mud on
every dark pick), the drawn BLOOD on the death frames (which turned the pool
brown — the worst bug this file could ship), and the women's HAIR, which is the
same hue as his shorts and cannot be told apart from it by any rule. Her set is
played in whites and has no kit to dye, so it is flagged out and the row says so
rather than silently doing nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-15 15:00:57 +02:00
1 parent 2f0c04fad4
commit 3b639e743b
6 files changed
+321 -11

No files matched your search

+16 -1
View File
@@ -1,6 +1,6 @@
// All mutable game state in one place, plus the point-reset that re-arms it.
import { HOME, BOY_ENTER, TUNE, COURT, COURTS, TOURS } from './config.js';
import { HOME, BOY_ENTER, TUNE, COURT, COURTS, TOURS, KITS, SKINS } from './config.js';
import { gore } from './zombies.js'; // runtime-only cycle (zombies imports state): sendBoy reads gore
// to decide whether a mopping round is worth walking out for
@@ -41,6 +41,21 @@ export function selectTour(id) {
return tour;
}
// The kit and the skin, picked on the same screen and living by the same rule as the tour: nothing
// but the DRAWN PIXELS depends on either. No physics, no AI, no scoring, no sprite NAMES — the
// recolour happens after SK() has already chosen the frame (see tint/PS in render.js).
export let kit = KITS[0], skin = SKINS[0];
export function selectKit(id) {
kit = KITS.find(k => k.id === id) || KITS[0];
try { localStorage.setItem('kit', kit.id); } catch {}
return kit;
}
export function selectSkin(id) {
skin = SKINS.find(s => s.id === id) || SKINS[0];
try { localStorage.setItem('skin', skin.id); } catch {}
return skin;
}
// everything that used to be loose top-level lets
export const G = {
mode: 'tennis', // tennis | transition | splatter