Commit Graph
5 Commits
Author SHA1 Message Date
wuwiandClaude Opus 4.8 eacad1ffca Sound: recorded SFX layer + a touch-easier CPU
Wire the new assets/audio/*.wav samples over the synth SFX:
- Ball hits: per-side tennis-player / tennis-opponent on serve & return,
  now with a stadium reverb tail (same convolver as umpire/aww).
- Crowd: tennis-applaus on your points/games (louder on big moments);
  tennis-aww when the opponent scores or you're eaten (reverb tail).
- Ambient bed: tennis-ambient-loop from first tap, 500Hz lowcut, low vol.
- Zombie music: zombie-mode loop when splatter kicks in (800Hz lowcut),
  fades out for the 1:1 sudden-death duel and back in after.
- Headshots: random headshot-1/-2 on every zombie kill (killZombie).

audio.js: sfx() one-shot player w/ rate+reverb opts, loopBed() beds with
duck/fade, aww() wrapper, hotter reverb send on the umpire voice.

Also: normal opponent aiFlub 0.09 -> 0.14 (a little easier to beat).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 20:33:29 +02:00
wuwiandClaude Fable 5 7bc26aec1c Phase 11: enemy roster wired — runner, brute, shield zombie
- Spawn mix (pickVariant): roster grows one type per set — runner from set 1
  game 3+ (12% slot, at most one alive, shriek on spawn = the fairness contract),
  brute from set 2 (15%), shield from set 3 (15%); classics fill the rest
- Runner ('f'): 3.2x shamble speed, faster leg cycle; new shriek() synth in audio
- Brute ('g'): hp 2 vs splat-quality balls AND pellets, 0.55x speed, 0.75m target,
  pushback-immune, 0.9m eaten radius, dies to double gore + size-2 pile, towers
  at 1.5x height
- Shield ('s'): blocks front balls with the chair (clank, ball spent), the block
  drops the chair for shieldDown 1.5s — any splat-quality ball kills in the
  window (z_s3 staggered pose renders); chair recovers after; always dies to
  bombs, melee, pellets
- TUNE: runnerSpeed 3.2, bruteHp 2, shieldDown 1.5

Verified in browser: per-variant stats; brute soft-ball immunity, 2-hit kill,
2-pellet kill, size-2 pile; shield block->window kill->chair recovery->blocks
again; melee kills f/s but not the racket boss; tier-2 spawn mix over 1500
spawns = 14/15/8/63%; all five sprites render with correct scale+occlusion;
tennis regression 11/12; no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 10:39:10 +02:00
wuwiandClaude Opus 4.8 06025bdccf 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>
2026-07-11 22:13:06 +02:00
wuwiandClaude Fable 5 69e3a0c310 Zombie town: the match continues
Win your first game and the applause cuts off mid-clap. The palette drains,
the umpire lowers his voice ('Quiet... please'), your opponent turns — torn
red polo, dragging his racket — and shamblers come over the billboard wall.
The scoreboard rewrites CPU to THEM. 'Play.'

- zombies.js: shamblers walk your way; quality shots splatter them (gore
  decal + particle burst + wet synth splat), weak sitters only stagger them
  back; one crossing your baseline is a point for THEM
- tennis scoring machinery keeps running untouched: fifteen, thirty, deuce,
  and 'Game, set... massacre' on a game win, all in recorded umpire English
- ball boys mop the gore they pass (their destiny fulfilled)
- transition: palette lerp, scripted spawns incl. the turned opponent,
  new recorded lines (quiet_dark, remain_seated, play, new_balls)
- moan ambience, drained splatter palette, all zombie params in TUNE

Verified: transition triggers on first game win, splat/stagger/baseline
scoring all correct, dead-ball flow feeds fresh serves, tennis mode
regression clean (6/6 returns, 6/6 points resolved).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 16:26:49 +02:00
wuwiandClaude Fable 5 c506a631c2 Split the monolith into ES modules; hoist scattered magic numbers
game.js (830 lines) -> 9 modules, native ES modules so still zero build step:
  dom      canvas handles (imports nothing; keeps cycles harmless)
  config   TUNE (live-tunable) + structural constants
  state    all mutable game state (G) + setupPoint/sendBoy
  audio    sfx synthesis, recorded umpire voice, reverb, speech fallback
  input    keyboard + touch, exports axes and takeFlickAim()
  gameplay ballistics, swings, serve, rules, AI, update loop
  render   camera, viewport, sprites, crowd, all drawing
  panel    T tuning UI
  main     boot, loop, intro, window.T test hooks

Deduped into named constants: bounce tempo (was in 3 places), contact
height band, intercept zone depth, home positions, player bounds, toss
params, shot depths, pose hold time, sprite scale, actor heights. Also
extracted drawShadow/drawBall/expirePose from repeated code.

One intentional import cycle (input <-> gameplay), safe: both sides only
call functions at runtime, never during module evaluation.

Regression-verified in browser sims: point cycle, CPU returns 11/12,
assist contract 8/8, corner-winner gradient intact (0/12 perfect corners
returned, 10/12 center balls returned).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 15:38:15 +02:00