Skip to main content

Sounds Guide

This guide explains how to work with sounds in RPG-JS, including static sound configuration, playing sounds from the server, and dynamic sound resolution.

Overview

Sounds are audio files that can be played during gameplay to provide audio feedback for actions, events, and ambient effects. RPG-JS supports both pre-loaded static sounds and dynamic sound creation through a resolver system.

Static Sounds

Basic Configuration

Add sounds to your client module configuration:

Sound Object Structure

A sound object can have the following properties:
If a sound object has a play() method, it will be used directly. Otherwise, the engine will create an Audio element from the src property.

Playing Sounds from Server

Using player.playSound()

You can play sounds from the server side using the playSound() method on a player instance. This method plays the sound only for the specific player, making it ideal for personal feedback sounds.

Using player.stopAllSounds()

Stop all currently playing sounds for this specific player. This is useful when changing maps or resetting the audio state for a player.

Using map.playSound()

To play a sound for all players on the map, use the playSound() method on the map instance. This is ideal for environmental sounds, battle music, or map-wide events.

Using map.stopSound()

Stop a specific sound for all players on the map.

Examples

Play Sound for Current Player Only

Play Sound for All Players on Map

Stopping Sounds

You can stop sounds using stopSound() on either the player or map:

Stop All Sounds

You can also stop all currently playing sounds at once:
This is particularly useful when changing maps to prevent sound overlap. See the Map Sounds Configuration section below for automatic sound stopping when joining maps.

Map Sounds Configuration

Maps can automatically play sounds when a player joins. These sounds are configured using the sounds property in the map configuration.

Basic Map Sounds

The simplest way to configure map sounds is using a plain object with provideServerModules:

Stop All Sounds Before Joining

By default, sounds from the previous map continue playing when a player changes maps. If you want to stop all sounds before playing the new map’s sounds, use the stopAllSoundsBeforeJoin option:
When to use stopAllSoundsBeforeJoin: true:
  • Battle maps (to cut off peaceful background music)
  • Important cutscenes or story moments
  • Areas where you want a clean audio transition
  • Maps with their own distinct audio atmosphere
When to keep it false (default):
  • Smooth transitions between similar areas
  • Continuous ambient sounds that should carry over
  • When you want sounds to layer naturally

Complete Map Sound Example

Using defineModule (Alternative)

You can also use defineModule to define your server configuration separately:

Alternative: Using @MapData or @RpgModule (Legacy)

For backward compatibility, you can still use decorators, though plain objects are now the recommended approach:
Or with @RpgModule:
Note: Using plain objects with provideServerModules or defineModule is the recommended approach. Decorators are still supported for backward compatibility but not required.

Use Cases

Using map.playSound() (for all players):
  • Environmental sounds (explosions, doors opening)
  • Battle sounds (combat start, victory fanfare)
  • Map-wide events (boss spawn, treasure chest opening)
  • Ambient effects that should be synchronized
  • Background music that everyone should hear
Using player.playSound() (for current player only):
  • UI feedback sounds (menu navigation, button clicks)
  • Personal notifications (level up, achievement unlocked)
  • Item pickup sounds (only the player who picked it up hears it)
  • Private messages or alerts
  • Personal background music

Complete Example

Dynamic Sound Resolver

The sound resolver allows you to create sounds on-the-fly when they are requested but not found in the cache. This is useful for:
  • Loading sounds from external APIs
  • Generating sounds programmatically
  • Creating sounds based on runtime data
  • Lazy loading sounds to reduce initial load time

Configuration

Add a soundResolver function to your client module:

Asynchronous Resolver

The resolver can also be asynchronous, useful for loading sounds from APIs or files:

Programmatic Generation

You can also generate sounds programmatically:

How It Works

  1. When a sound is requested (e.g., via player.playSound()), the engine first checks the cache
  2. If the sound is not found and a resolver is configured, the resolver is called with the sound ID
  3. The resolved sound is automatically cached for future use
  4. If the resolver returns undefined or null, the sound is not found and a warning is logged

Resolver Function Signature

Parameters:
  • id: string - The sound ID that was requested
Returns:
  • SoundDefinition - A sound configuration object (synchronous)
  • Promise<SoundDefinition> - A Promise that resolves to a sound (asynchronous)
  • undefined | null - Indicates the sound cannot be created

Programmatic API

You can also set a resolver programmatically using the engine:

Example: Loading from CDN

Example: Fallback Chain

Combining Static and Dynamic

You can use both static sounds and a resolver together. Static sounds are loaded first, and the resolver is only called for sounds not found in the static list:

Client-Side Sound API

You can also play sounds directly from the client side using the engine:

Best Practices

1. Sound File Formats

  • Use compressed formats (MP3, OGG) for better performance
  • Provide multiple formats for browser compatibility:

2. Error Handling

Always handle errors gracefully in async resolvers:

3. Performance

  • Use static sounds for frequently played sounds (UI feedback, common actions)
  • Use resolvers for sounds that are rarely used or loaded on-demand
  • Pre-load critical sounds in the static sounds array

4. ID Patterns

Use consistent ID patterns to make resolver logic easier:

5. Volume Management

Consider implementing volume controls:

6. Memory Management

Resolved sounds are automatically cached. If you need to invalidate the cache:

Common Use Cases

Dialog Box Sounds

Footstep Sounds

Weapon Sounds

See Also