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>
This commit is contained in:
1 parent
811fe3f91f
commit
7bc26aec1c
4 files changed
+76
-14
No files matched your search
@@ -116,6 +116,21 @@ export function boom(vol = 0.9) { // bomb ball — sub-bass thump under a filter
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function shriek(vol = 0.35) { // a runner announces itself — harsh rising cry, the fairness contract
|
||||
try {
|
||||
const ac = audio(), t = ac.currentTime, dur = 0.7;
|
||||
const o = ac.createOscillator(); o.type = 'sawtooth';
|
||||
o.frequency.setValueAtTime(300, t);
|
||||
o.frequency.exponentialRampToValueAtTime(950, t + 0.25);
|
||||
o.frequency.exponentialRampToValueAtTime(500, t + dur);
|
||||
const bp = ac.createBiquadFilter(); bp.type = 'bandpass'; bp.frequency.value = 1400; bp.Q.value = 0.8;
|
||||
const g = ac.createGain();
|
||||
g.gain.setValueAtTime(0.001, t); g.gain.exponentialRampToValueAtTime(vol, t + 0.06);
|
||||
g.gain.exponentialRampToValueAtTime(0.001, t + dur);
|
||||
o.connect(bp).connect(g).connect(ac.destination); o.start(t); o.stop(t + dur + 0.05);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function moan(vol = 0.1) { // distant undead ambience
|
||||
try {
|
||||
const ac = audio(), t = ac.currentTime, dur = 1.2 + Math.random() * 0.8;
|
||||
|
||||
Reference in new issue
Block a user