Sound API

The Sound API lets Lua scripts load and play audio files with real-time volume and stereo panning control.

Sound files are loaded from relative paths resolved against your script directory (same as the File System API).

Supported formats: WAV (PCM 8/16-bit), MP3, AAC, WMA, FLAC — anything Windows Media Foundation can decode.

All audio is resampled to 44100 Hz stereo at load time. Up to 64 sounds can play simultaneously.


Concepts

There are two handle types, both represented as integers:

  • Sound handle — a loaded audio resource returned by load_sound. Can be played multiple times simultaneously. Must be freed with free_sound when no longer needed.

  • Instance handle — a single playing occurrence returned by play_sound. Used to stop, query, or adjust an active playback.

Both return 0 on failure. All functions are safe to call with 0 handles (they become no-ops).


Loading & Freeing

load_sound(path) -> handle

Loads a sound file from a relative path.

  • path (string) — Relative path to the audio file (e.g. "sounds/hit.wav", "alert.mp3").

Returns a sound handle (integer), or 0 if the file doesn't exist or decoding fails.


free_sound(handle)

Frees a previously loaded sound resource. Any active instances using this sound are stopped automatically.


Playback

play_sound(sound [, volume [, pan [, loop]]]) -> instance

Plays a loaded sound and returns an instance handle.

  • sound (integer) — Sound handle from load_sound.

  • volume (number) — 0.0 (silent) to 1.0 (full). Default 1.0. Clamped.

  • pan (number) — -1.0 (full left) to +1.0 (full right). Default 0.0 (center). Clamped.

  • loop (boolean) — If true, the sound repeats until explicitly stopped. Default false.

Returns an instance handle (integer), or 0 if the sound handle is invalid or all 64 instance slots are in use.


stop_sound(instance)

Stops a playing instance immediately.


stop_all_sounds()

Stops every currently playing sound instance.


is_sound_playing(instance) -> bool

Returns true if the instance is still actively playing. Returns false if it finished, was stopped, or the handle is invalid.


Live Adjustment

These functions modify a playing instance in real time. Changes take effect on the next mixer tick (~20ms).

set_sound_volume(instance, volume)

Changes volume of a playing instance. 0.0 to 1.0, clamped.


set_sound_pan(instance, pan)

Changes stereo panning of a playing instance. -1.0 (left) to +1.0 (right), clamped.


Examples

Play a one-shot sound effect


Looping background music


Directional sound with panning


Fade out over time


Multiple simultaneous sounds


Notes

  • Sound data is fully decoded to PCM at load time. Loading is the expensive operation — play_sound is cheap.

  • Instance handles point into a fixed pool of 64 slots. If all slots are in use, play_sound returns 0.

  • Calling free_sound automatically stops all instances that reference that sound.

  • Sounds are automatically freed when your script is unloaded (leaked handles are cleaned up). You should still free sounds explicitly when possible.

  • The path parameter follows the same validation rules as the File System API: relative paths only, no .. segments, no : characters.

Last updated