// Sound effect keys — must match the keys loaded in PreloadScene. export const SFX = { CARD_DEAL: 'sfx-card-deal', CARD_PLACE: 'sfx-card-place', CARD_SHOW: 'sfx-card-show', CARD_SHUFFLE: 'sfx-card-shuffle', COINS: 'sfx-coins', PURCHASE: 'sfx-purchase', CASINO_BLACKJACK: 'sfx-casino-blackjack', CASINO_LOSE: 'sfx-casino-lose', CASINO_WIN: 'sfx-casino-win', CHIP_BET: 'sfx-chip-bet', DICE_ROLL: 'sfx-dice-roll', PENCIL_WRITE: 'sfx-pencil-write', BINGO_BALLS: 'sfx-bingo-balls', PIECE_CLICK: 'sfx-piece-click', ROULETTE: 'sfx-roulette', BATTLESHIP_HIT: 'sfx-battleship-hit', BATTLESHIP_MISS: 'sfx-battleship-miss', BATTLESHIP_LAUNCH: 'sfx-battleship-launch', MASTERMIND_GLITCH_1: 'sfx-mastermind-glitch-1', MASTERMIND_GLITCH_2: 'sfx-mastermind-glitch-2', MASTERMIND_PLACE: 'sfx-mastermind-place', MASTERMIND_GRANTED: 'sfx-mastermind-access-granted', MASTERMIND_DENIED: 'sfx-mastermind-access-denied', MASTERMIND_COLOR: 'sfx-mastermind-color', MASTERMIND_MATCH: 'sfx-mastermind-match', MASTERMIND_CALCULATE: 'sfx-mastermind-calculate', VICTORY_SHORT: 'sfx-victory-short', SCIFI_LAUNCH: 'sfx-scifi-launch', SCIFI_EXPLODE: 'sfx-scifi-explode', SCIFI_RISER: 'sfx-scifi-riser', SCIFI_REVEAL: 'sfx-scifi-reveal', SCIFI_WOOSH: 'sfx-scifi-woosh', SCIFI_PLINK: 'sfx-scifi-plink', SCIFI_PLONK: 'sfx-scifi-plonk', SWORD_HIT: 'sfx-sword-hit', SWORD_SLICE: 'sfx-sword-slice', MONOPOLY_PURCHASE: 'sfx-monopoly-purchase', MONOPOLY_EXPENSE: 'sfx-monopoly-expense', MONOPAY: 'sfx-monopoly-pay', MONOPOLY_PAID: 'sfx-monopoly-paid', EIGHTBIT_SELECT: 'sfx-8bit-select', EIGHTBIT_ACTIVATE: 'sfx-8bit-activate', EIGHTBIT_ACTION: 'sfx-8bit-action', EIGHTBIT_MOVE: 'sfx-8bit-move', CLICK: 'sfx-click', EIGHTBIT_JUMP: 'sfx-8bit-jump', EIGHTBIT_CARD: 'sfx-card-deal-8bit', EIGHTBIT_EXPLODE: 'sfx-8bit-explode', EIGHTBIT_EXPLODE_2: 'sfx-8bit-explode2', EIGHTBIT_COUNT: 'sfx-8bit-count', EIGHTBIT_WIN: 'sfx-casino-win-8bit', SQUISH: 'sfx-squish', SQUASH: 'sfx-squash', WOOSH: 'sfx-woosh', // Loaded in PreloadScene since the Zuma work; named here so games stop // reaching for the raw cache keys. WATER_SPLASH: 'sfx-water-splash', WATER_SINK: 'sfx-water-sink', WATER_RAISE: 'sfx-water-raise', WATER_DRY: 'sfx-water-dry', JELLO_MONSTERS: 'sfx-jello-monsters', COUNTDOWN_TICK: 'sfx-countdown-tick', COUNTDOWN_GO: 'sfx-countdown-go', UI_PICK: 'sfx-ui-pick', UI_ACTIVATE: 'sfx-ui-activate', UI_FLIP: 'sfx-ui-flip', UI_PLACE: 'sfx-ui-place', UI_CHIME: 'sfx-ui-chime', GEM_MATCH_1: 'sfx-gem-match-1', GEM_MATCH_2: 'sfx-gem-match-2', GEM_MATCH_4: 'sfx-gem-match-4', GEM_MATCH_5: 'sfx-gem-match-5', GEM_CHAIN: 'sfx-gem-chain', GEM_DROP: 'sfx-gem-drop', GEM_BIG_DROP: 'sfx-gem-big-drop', FIREWORK: 'sfx-firework', SW_LIGHT_1: 'sfx-sw-light-1', SW_LIGHT_2: 'sfx-sw-light-2', SW_LIGHT_3: 'sfx-sw-light-3', SW_DARK_1: 'sfx-sw-dark-1', SW_DARK_2: 'sfx-sw-dark-2', SW_DARK_3: 'sfx-sw-dark-3', ENERGY_HUM: 'sfx-energy-hum', LASER_ZAP: 'sfx-laser-zap', REWIND: 'sfx-rewind', ENGINE_START: 'sfx-engine-start', ENGINE_HEAVY: 'sfx-engine-heavy', ENGINE_FAST: 'sfx-engine-fast', ENGINE_MEDIUM: 'sfx-engine-medium', ENGINE_REV: 'sfx-engine-rev', KART_COIN: 'sfx-kart-coin', KART_FLATTEN: 'sfx-kart-flatten', KART_THUMP: 'sfx-kart-thump', KART_SHRINK: 'sfx-kart-shrink', KART_SPIN: 'sfx-kart-spin', KART_HIT: 'sfx-kart-hit', KART_SHELL: 'sfx-kart-shell', KART_STAR: 'sfx-kart-star', KART_SPINNER: 'sfx-kart-spinner', VEGA_SELECT: 'sfx-vega-select', VEGA_BUILD: 'sfx-vega-build', VEGA_CLOSE: 'sfx-vega-close', VEGA_NEWTURN: 'sfx-vega-newturn', VEGA_UNIT: 'sfx-vega-unit', VEGA_VIEW: 'sfx-vega-view', VEGA_WARP: 'sfx-vega-warp', VEGA_STAR: 'sfx-vega-star', VEGA_ZOOMIN: 'sfx-vega-zoomin', VEGA_ZOOMOUT: 'sfx-vega-zoomout', VEGA_VIEWCOLONY: 'sfx-vega-viewcolony', VEGA_ENDTURN: 'sfx-vega-endturn', VEGA_COUNTER: 'sfx-vega-counter', VEGA_GNN_STING: 'sfx-vega-gnn-sting', VEGA_GNN_LOOP: 'sfx-vega-gnn-loop', VEGA_COUNCIL_INTRO: 'sfx-vega-council-intro', VEGA_COUNCIL_LOOP: 'sfx-vega-council-loop', // Beam cues split by the firing ship's Mark (I-VII); missile cues split the // same way but only two ways, and further split into launch vs. impact. // See VegaCombatView.js's weaponSfxKey()/missileLaunchSfxKey()/ // missileHitSfxKey() for the Mark bands. VEGA_WEAPON_123: 'sfx-vega-weapon-123', VEGA_WEAPON_45: 'sfx-vega-weapon-45', VEGA_WEAPON_67: 'sfx-vega-weapon-67', VEGA_MISSILE_LAUNCH_12345: 'sfx-vega-missle-launch-12345', VEGA_MISSILE_LAUNCH_67: 'sfx-vega-missle-launch-67', VEGA_MISSILE_HIT_12345: 'sfx-vega-missle-hit-12345', VEGA_MISSILE_HIT_67: 'sfx-vega-missle-hit-67', // Planetary defence battery fire — VegaCombatViewV2.js's handleEvents // plays this instead of a weaponSfxKey() band whenever the shooter is the // planet (ev.weaponKind is null for a planet's fire events, since it has // no weapon mount to band by Mark). VEGA_PLANET_BEAM: 'sfx-vega-planet-beam', // One destroy cue per warship class — see VegaCombatView.js's/ // VegaCombatViewV2.js's destroySfxKey(). Only the four combatant hulls // (frigate/destroyer/cruiser/battleship) have a clip; other hulls play no // destroy cue. Cache key spelling is the correct "frigate" even though the // clip on disk is named "vega-destroy-friggate.mp3" (typo in the filename // Brian recorded) — see the asset manifest entry. VEGA_DESTROY_FRIGATE: 'sfx-vega-destroy-frigate', VEGA_DESTROY_DESTROYER: 'sfx-vega-destroy-destroyer', VEGA_DESTROY_CRUISER: 'sfx-vega-destroy-cruiser', VEGA_DESTROY_BATTLESHIP: 'sfx-vega-destroy-battleship', }; export function playSound(scene, key) { try { scene.sound.play(key); } catch (_) {} } // Same, but with a Phaser sound config — `{ rate, volume, detune }`. Use this // for pitch-shifted cues rather than `scene.sound.add(...)`, which leaks a // Sound object per call. export function playSoundEx(scene, key, config) { try { scene.sound.play(key, config); } catch (_) {} } // Picks and plays one of several keys at random (e.g. variations of the same cue). export function playRandomSound(scene, keys) { playSound(scene, keys[Math.floor(Math.random() * keys.length)]); } const SW_LIGHT_KEYS = [SFX.SW_LIGHT_1, SFX.SW_LIGHT_2, SFX.SW_LIGHT_3]; const SW_DARK_KEYS = [SFX.SW_DARK_1, SFX.SW_DARK_2, SFX.SW_DARK_3]; // SWDBG: Force track shifting toward the Rebel (light) or Empire (dark) side. export function playForceMove(scene, towardLight) { playRandomSound(scene, towardLight ? SW_LIGHT_KEYS : SW_DARK_KEYS); } // chip-bet is limited to one simultaneous instance. let _chipBetSound = null; export function playChipBet(scene) { if (_chipBetSound?.isPlaying) return; _chipBetSound?.destroy(); _chipBetSound = scene.sound.add(SFX.CHIP_BET); _chipBetSound.play(); } // Each plays at most one simultaneous instance (tie battles would otherwise double up). let _scifiLaunchSound = null; export function playScifiLaunch(scene) { if (_scifiLaunchSound?.isPlaying) return; _scifiLaunchSound?.destroy(); _scifiLaunchSound = scene.sound.add(SFX.SCIFI_LAUNCH); _scifiLaunchSound.play(); } let _scifiExplodeSound = null; export function playScifiExplode(scene) { if (_scifiExplodeSound?.isPlaying) return; _scifiExplodeSound?.destroy(); _scifiExplodeSound = scene.sound.add(SFX.SCIFI_EXPLODE); _scifiExplodeSound.play(); } let _scifiRiserSound = null; export function playScifiRiser(scene) { if (_scifiRiserSound?.isPlaying) return; _scifiRiserSound?.destroy(); _scifiRiserSound = scene.sound.add(SFX.SCIFI_RISER); _scifiRiserSound.play(); } let _scifiRevealSound = null; export function playScifiReveal(scene) { if (_scifiRevealSound?.isPlaying) return; _scifiRevealSound?.destroy(); _scifiRevealSound = scene.sound.add(SFX.SCIFI_REVEAL); _scifiRevealSound.play(); } let _scifiWooshSound = null; export function playScifiWoosh(scene) { if (_scifiWooshSound?.isPlaying) return; _scifiWooshSound?.destroy(); _scifiWooshSound = scene.sound.add(SFX.SCIFI_WOOSH); _scifiWooshSound.play(); } // Dot Link: plink/plonk with adjustable rate — even colour index → plink, odd → plonk export function playDotLinkSound(scene, colorIdx, pathLength) { const soundKey = colorIdx % 2 === 0 ? SFX.SCIFI_PLINK : SFX.SCIFI_PLONK; const rate = 1 + (pathLength - 1) * 0.5; const sound = scene.sound.add(soundKey); sound.setRate(rate); sound.play(); }