Give the machine, fire, gun and boss their missing sounds
All four synthesized in audio.js like every other weapon: a squeaking castor, a court-wide crackle clock plus a throttled catch, a real gun crack, and one shared boss voice (stomp per stride, wind-up breath, bark, pain, death roar) pitched by body size. Closes OPEN 13 pending the phone verdict. v355. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d05b49909e
commit
74aa209753
5 files changed
+248
-14
No files matched your search
@@ -95,7 +95,7 @@ const { mirror, netMsg, netTest, netTick, netAgain } = await import('./src/net.j
|
||||
// the drill's first-sight modal freezes the world (that is what modals do) — dismiss it the way a
|
||||
// player would, so the tests step a live court
|
||||
const startDrill = (...a) => { const r = _startDrill(...a); G.modal = null; G.modalQ.length = 0; return r; };
|
||||
const { zombies, spawnZombie, pellets, parts, explode, hurtPlayer } = await import('./src/zombies.js');
|
||||
const { zombies, spawnZombie, pellets, parts, explode, hurtPlayer, firePellet } = await import('./src/zombies.js');
|
||||
const { killPlayer } = await import('./src/zombies.js');
|
||||
const { drillQueue, drillLegal, arrival, drillMult, DRILL_TYPES } = await import('./src/drill.js');
|
||||
const cfg = await import('./src/config.js');
|
||||
@@ -2127,6 +2127,44 @@ test('netplay: the friend\'s strike makes a noise, pitched off the ball it just
|
||||
audio.sfxTest.log = null;
|
||||
});
|
||||
|
||||
// ---- OPEN 13: the four missing sounds (2026-09-23). Synthesized, so the ear is the phone's job;
|
||||
// what the suite pins is that each one fires at its EVENT, and that fire stays one clock, not a
|
||||
// sound per body.
|
||||
test('the machine squeaks, fire crackles and catches, the gun cracks, the boss stomps and growls', () => {
|
||||
const heard = n => audio.sfxTest.log.includes(n);
|
||||
freshSplatter();
|
||||
audio.sfxTest.log = [];
|
||||
spawnZombie(0, 8, 'm');
|
||||
const m = zombies[zombies.length - 1]; m.rollTo = 3; m.rollT = 0; m.fireT = 99;
|
||||
for (let i = 0; i < 60 * 4 && !heard('squeak'); i++) { update(DT); G.hp = 9; }
|
||||
assert.ok(heard('squeak'), 'a rolling machine announces itself');
|
||||
|
||||
freshSplatter();
|
||||
audio.sfxTest.log = [];
|
||||
for (let k = 0; k < 8; k++) spawnZombie(-1.4 + k * 0.4, 6, 'a');
|
||||
zombies[0].burnT = 3;
|
||||
update(DT);
|
||||
assert.ok(heard('crackle'), 'a burning body crackles');
|
||||
assert.equal(audio.sfxTest.log.filter(n => n === 'whump').length, 1, 'an epidemic lights the row, and says so ONCE');
|
||||
const lit = zombies.filter(z => z.burnT > 0).length;
|
||||
audio.sfxTest.log = [];
|
||||
for (let i = 0; i < 60; i++) update(DT);
|
||||
const crackles = audio.sfxTest.log.filter(n => n === 'crackle').length;
|
||||
assert.ok(lit >= 3 && crackles >= 3 && crackles <= 16, `one court clock, not one per body: ${crackles} crackles/s for ${lit} lit`);
|
||||
|
||||
audio.sfxTest.log = [];
|
||||
for (let k = 0; k < 4; k++) firePellet();
|
||||
assert.equal(audio.sfxTest.log.filter(n => n === 'gunshot').length, 2, 'the gun cracks every other round');
|
||||
|
||||
freshSplatter();
|
||||
startBossFight(1);
|
||||
audio.sfxTest.log = [];
|
||||
for (let i = 0; i < 60 * 30 && !(heard('stomp') && heard('growl')); i++) { update(DT); G.hp = 9; }
|
||||
assert.ok(heard('stomp'), 'the boss has feet');
|
||||
assert.ok(heard('growl'), 'and a throat: the wind-up draws breath');
|
||||
audio.sfxTest.log = null;
|
||||
});
|
||||
|
||||
// ---- THE REMATCH. The relay cannot re-pair (its room code is popped on pairing), so playing the
|
||||
// same friend again is the SOCKET THAT IS STILL OPEN: one 'again' frame, both phones reset the run
|
||||
// under the decisions the room already carries. The desync to guard against is the two courts
|
||||
|
||||
Reference in new issue
Block a user