feat: 30 comedy sound effects, replace 75% round-end TTS with SFX

Comedy sounds (all procedural Web Audio, no samples):
- Vine Boom, Air Horn (MLG), Bruh, Fart, Record Scratch
- Rubber Chicken, Squeaky Toy, Wet Slap, Bone Crack, Cartoon Run
- Rim Shot (ba dum tss), Slide Whistle Up/Down, Yippee, Ding
- Taco Bell Bong, Windows Error, Meme Thud
- Sad Trombone, Emotional Damage, Dun Dun Dunnnn
- Fail Horn, Price Is Right Fail, Buzzer, Sad Violin
- Mission Failed, Crickets

Wiring:
- Round-end narration: 75% comedy SFX, 25% TTS (was 100% TTS)
- Critical rounds get Emotional Damage, draws get random fail
- Showboat loop: 40% chance of comedy sound punctuation after each
- KO finish: 50% chance of comedy fail sound on loser
- sfxRandomSilly expanded with comedy sounds
- New exports: sfxRandomComedy, sfxRandomFail

Also adds bulletTimeAttack combat choreography + ultimateBulletTimeBarrage
(tier 3+ ultimate) to fight system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 16:55:14 +00:00
co-authored by Claude Opus 4.6
parent d3f026d356
commit a59b0748a7
3 changed files with 618 additions and 57 deletions
+14 -1
View File
@@ -9,6 +9,7 @@ import {
setMusicIntensity, stopAllAudio,
setMasterMute, isMasterMuted, ensureAudioContext,
speakQuestion, speakAnswer, speakNarration,
sfxRandomComedy, sfxRandomFail, sfxVineBoom, sfxEmotionalDamage,
} from '../game/sounds'
interface Round {
@@ -411,7 +412,19 @@ async function _doReplay() {
if (round.narration) {
logItems.value.push({ type: 'narration', round: round.roundNumber, text: `>> ${round.narration}`, color: 'neon-yellow' })
scrollLog()
if (doTTS) await speakNarration(round.narration)
// 75% comedy SFX instead of TTS narration — much funnier and faster
if (doTTS && Math.random() < 0.25) {
await speakNarration(round.narration)
} else {
// Play a comedy sound that matches the round result
if (isCritical) {
sfxEmotionalDamage()
} else if (!aWon && !bWon) {
sfxRandomFail()
} else {
sfxRandomComedy()
}
}
await sleep(insanityMode.value ? 30 : 200)
}