Phase 4: bomb balls

Ball boys deliver a bomb ball every TUNE.bombEvery (8) splatter kills, up
to TUNE.bombMax (3) in stock (G.bombs / G.killMeter in state). The next
serve auto-consumes one (hitServe, splatter-only) — no extra input, keeping
one-handed play. A bomb detonates on first zombie contact (regardless of
pace) or, if it misses everyone, on its first bounce: explode() splatters
everything within TUNE.bombRadius (2.5m), each kill feeding ball.kills so
the Phase-2 fanfare escalates naturally, and leaves a crater — big stain,
size-3 pile, 40 particles, 0.1s hitstop, boom(). New synth boom() in
audio.js. Bomb ball renders black with a flickering orange fuse; the HUD
shows stocked bombs as black/orange pips by the YOU line. Both explode
sites set phase='over' so the serve loop doesn't stall on the killed ball.

Alternative delivery ideas Oliver floated but not built: umpire throws it,
or court pickup.

Verified via window.T: 8th kill earns a bomb (meter resets); a serve
consumes one and renders #111 black + orange fuse; a pow-0 bomb amid 4
clustered zombies kills all 4 with 'MASSACRE ×4', boom, hitstop 0.1,
crater stain (r1.4) + size-4 pile; a bomb that misses still craters on
first bounce; bombs never leak into tennis (mode guard); 3 HUD pips; no
console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 4.8 committed 2026-07-11 22:13:06 +02:00
1 parent ad4c8041b9
commit 06025bdccf
6 files changed
+67 -5

No files matched your search

+3
View File
@@ -24,6 +24,9 @@ export const TUNE = {
zPushback: 1.4, // m a staggered zombie is knocked back
splatterOverT: 0.1, // s the spent-ball 'over' beat lasts before the next serve is armed
zPierce: 0.75, // pace a ball keeps after a splatter — hot balls plow through lined-up pairs
bombEvery: 8, // splatter kills between bomb-ball rewards
bombMax: 3, // bomb balls you can stock at once
bombRadius: 2.5, // m blast radius of a bomb ball
missHud: 1, // show the last miss reason on screen (full log: T.G.missLog)
};