Files
BreakEscape/docs/SOUND_SYSTEM.md
Z. Cliffe Schreuders 9aae3f9443 feat: Implement centralized sound management system
- Created SoundManager class for handling audio playback using Phaser's sound system.
- Added methods for preloading, initializing, and playing sounds with volume control.
- Integrated UI sound helpers for easier sound attachment to DOM elements.
- Updated game.js to initialize sound manager and preload sounds.
- Modified interactions.js, unlock-system.js, and panels.js to play appropriate sounds on interactions.
- Created SOUND_SYSTEM_QUICK_REFERENCE.md for documentation on sound system usage.
- Optimized NPCBarkSystem and NPCManager with caching and event listener cleanup.
2025-11-01 00:34:26 +00:00

10 KiB

Break Escape Sound System Documentation

Overview

The Break Escape sound system is a centralized Phaser-based audio management system that handles all game sound effects, including UI interactions, item collection, lock interactions, and mini-game specific sounds.

Architecture

Core Components

1. SoundManager (js/systems/sound-manager.js)

The central sound management class that:

  • Loads all audio assets during preload phase
  • Creates and manages Phaser sound objects
  • Provides convenient playback methods
  • Manages volume levels and categories
  • Supports sound toggling and master volume control

2. UI Sounds Helper (js/systems/ui-sounds.js)

Utility module that:

  • Provides DOM element sound attachment helpers
  • Plays category-specific sounds (clicks, notifications, etc.)
  • Bridges DOM events with sound playback
  • Offers specialized functions for game-specific sounds

3. Game Integration (js/core/game.js)

Integration points:

  • Preload sounds during preload() function
  • Initialize sound manager in create() function
  • Expose sound manager globally as window.soundManager

Available Sounds

Sound Assets (36 total)

Lockpicking Mini-Game (8 sounds)

  • lockpick_binding - Binding pin feedback
  • lockpick_click - Pin click during picking
  • lockpick_overtension - Overtension/overpicking failure
  • lockpick_reset - Lock reset
  • lockpick_set - Pin set successfully
  • lockpick_success - Lock successfully picked
  • lockpick_tension - Tension wrench feedback
  • lockpick_wrong - Wrong lock manipulated

GASP Door Sounds (1 sound)

  • door_knock - Door knock/activation sound

GASP Item Interactions (3 sounds)

  • item_interact_1 - Item pickup sound variant 1
  • item_interact_2 - Item pickup sound variant 2
  • item_interact_3 - Item pickup sound variant 3

GASP Lock Interactions (5 sounds)

  • lock_interact_1 - Lock attempt sound variant 1
  • lock_interact_2 - Lock attempt sound variant 2
  • lock_interact_3 - Lock attempt sound variant 3
  • lock_interact_4 - Lock attempt sound variant 4
  • lock_and_load - Lock loading/preparation sound

GASP UI Clicks (5 sounds)

  • ui_click_1 - Button click variant 1
  • ui_click_2 - Button click variant 2
  • ui_click_3 - Button click variant 3
  • ui_click_4 - Button click variant 4
  • ui_click_6 - Button click variant 6

GASP UI Alerts (2 sounds)

  • ui_alert_1 - Alert sound variant 1
  • ui_alert_2 - Alert sound variant 2

GASP UI Confirmation (1 sound)

  • ui_confirm - Successful action confirmation

GASP UI Notifications (6 sounds)

  • ui_notification_1 through ui_notification_6 - Various notification sounds

GASP UI Reject (1 sound)

  • ui_reject - Error/rejection sound

Game-Specific Sounds (2 sounds)

  • chair_roll - Chair spinning/rolling sound
  • message_received - Incoming message notification

Usage

Basic Usage in Code

Playing a Sound

// Access the sound manager
const soundManager = window.soundManager;

// Play a specific sound
soundManager.play('ui_click_1');

// Play with options
soundManager.play('ui_click_1', { volume: 0.8, delay: 100 });

// Play random variant
soundManager.playUIClick();  // Plays random click sound
soundManager.playUINotification();  // Plays random notification
soundManager.playItemInteract();  // Plays random item sound
soundManager.playLockInteract();  // Plays random lock sound

Volume Control

// Set master volume (0-1)
soundManager.setMasterVolume(0.7);

// Set category volume
soundManager.setCategoryVolume('ui', 0.8);
soundManager.setCategoryVolume('effects', 0.9);

// Available categories: ui, interactions, notifications, effects, music

Sound State

// Toggle sound on/off
soundManager.toggle();

// Explicitly set enabled/disabled
soundManager.setEnabled(false);
soundManager.setEnabled(true);

// Check if sounds are enabled
if (soundManager.isEnabled()) {
    // Play sound
}

// Stop all sounds
soundManager.stopAll();

Using UI Sound Helpers

Attaching Sounds to DOM Elements

import { attachUISound, playUISound } from '../systems/ui-sounds.js';

// Attach sound to a single element
const button = document.getElementById('my-button');
attachUISound(button, 'click');  // Plays random click on click

// Attach sounds to all elements with a class
attachUISoundsToClass('inventory-button', 'click');

// Specialized attachment functions
attachConfirmSound(button);    // Attach confirmation sound
attachRejectSound(button);     // Attach error sound
attachItemSound(button);       // Attach item interaction sound
attachLockSound(button);       // Attach lock interaction sound
attachNotificationSound(button); // Attach notification sound

Playing Sounds Programmatically

import { playUISound, playGameSound } from '../systems/ui-sounds.js';

// Play categorized sounds
playUISound('click');           // Play random UI click
playUISound('notification');    // Play random notification
playUISound('item');            // Play random item interaction
playUISound('lock');            // Play random lock interaction
playUISound('confirm');         // Play confirmation
playUISound('alert');           // Play alert
playUISound('reject');          // Play rejection/error

// Play specific game sounds
playGameSound('door_knock');
playGameSound('chair_roll');
playGameSound('message_received');

// Direct convenience functions
import { 
    playDoorKnock, 
    playChairRoll, 
    playMessageReceived 
} from '../systems/ui-sounds.js';

playDoorKnock();
playChairRoll();
playMessageReceived();

Volume Categories

The system supports 5 volume categories with independent controls:

  • ui (0.7 default): UI clicks, button sounds
  • interactions (0.8 default): Item interactions, lock interactions, door knocks
  • notifications (0.6 default): Alert sounds, rejection sounds, notifications
  • effects (0.85 default): Game-specific effects like chair rolling, lockpicking
  • music (0.5 default): Background music (reserved for future use)

Setting Category Volumes

soundManager.setCategoryVolume('ui', 0.7);
soundManager.setCategoryVolume('interactions', 0.8);
soundManager.setCategoryVolume('notifications', 0.6);
soundManager.setCategoryVolume('effects', 0.85);

Integration Points

Automatic Integration

The following systems automatically include sound effects:

  1. Item Collection (js/systems/interactions.js)

    • Plays item interaction sound when collecting items
    • File path: Item pickup → playUISound('item')
  2. Lock Interactions (js/systems/unlock-system.js)

    • Plays lock interaction sound when attempting unlock
    • File path: Lock attempt → playUISound('lock')
  3. UI Panels (js/ui/panels.js)

    • Plays notification sound when showing panels
    • File path: Panel toggle/show → playUISound('notification')
  4. Lockpicking Mini-Game (js/minigames/lockpicking/lockpicking-game-phaser.js)

    • Uses dedicated lockpick sounds for each interaction
    • Plays sounds during pin manipulation, tension application, etc.

Adding Sounds to New Features

For Button Clicks

import { attachUISound } from '../systems/ui-sounds.js';

const myButton = document.getElementById('my-button');
attachUISound(myButton, 'click');

For Game Events

import { playUISound } from '../systems/ui-sounds.js';

// In your event handler
playUISound('notification');  // or 'click', 'confirm', 'reject', etc.

For Mini-Games

// In your mini-game scene
preload() {
    // Sounds are already loaded globally
}

create() {
    // Access sounds via window.soundManager
    window.soundManager.play('ui_click_1');
}

Configuration

Default Volume Levels

Edit these in SoundManager constructor in js/systems/sound-manager.js:

this.volumeSettings = {
    ui: 0.7,
    interactions: 0.8,
    notifications: 0.6,
    effects: 0.85,
    music: 0.5
};

Adding New Sounds

  1. Place MP3 file in assets/sounds/
  2. Add load call in SoundManager.preloadSounds():
    this.scene.load.audio('my_sound', 'assets/sounds/my_sound.mp3');
    
  3. Add to sound names array in initializeSounds():
    const soundNames = [
        // ... existing sounds
        'my_sound'
    ];
    
  4. Determine volume category in getVolumeForSound():
    if (soundName.includes('my_sound')) category = 'effects';
    

Best Practices

Performance

  • Sounds are cached after initial load
  • Random variants prevent sound repetition fatigue
  • Volume categories allow balanced audio mixing
  • Master volume can disable all sounds efficiently

User Experience

  • Sounds give immediate feedback to user actions
  • Different sound types (click, notification, etc.) indicate different action types
  • Random variants add perceived variety and polish
  • Category-based volume control lets players customize audio mix

Implementation

  • Always check window.soundManager exists before playing sounds
  • Use category-specific helpers (playUISound(), playGameSound()) for consistency
  • Attach DOM sounds in initialization phase, not every event handler
  • Use random sound functions (playUIClick()) instead of single sounds

Troubleshooting

Sounds Not Playing

  1. Check if sound manager is initialized: console.log(window.soundManager)
  2. Check browser console for errors
  3. Verify sound files exist in assets/sounds/
  4. Check if sounds are enabled: window.soundManager.isEnabled()
  5. Verify volume isn't muted: window.soundManager.masterVolume > 0

Sounds Too Loud/Quiet

  1. Check master volume: window.soundManager.masterVolume
  2. Check category volume: window.soundManager.volumeSettings['category_name']
  3. Adjust with: soundManager.setMasterVolume(0.7) or soundManager.setCategoryVolume('ui', 0.8)

Performance Issues

  • Limit simultaneous sounds
  • Use sound pooling (already implemented in Phaser)
  • Reduce category volumes if CPU usage is high

Future Enhancements

Potential improvements for the sound system:

  1. Background music support with fade in/out
  2. 3D positional audio for in-game sound effects
  3. Sound preferences UI panel
  4. Audio profile saves (for accessibility)
  5. NPC voice lines integration
  6. Ambient sound support
  7. Sound effect composition for mini-games