arcade2d
Class

AudioSource

audio/audio-source.ts:71

Plays short, one-shot sound effects from a WorldObject.

Attach an AudioSource to any object that needs to emit SFX — a player who fires bullets, a door that creaks, a wall that takes damage. Each call to AudioSource.play spawns a fresh, fire-and-forget AudioInstance routed through the AudioEngine's SFX bus, so several voices from the same source can overlap freely (the burst of an automatic weapon, two shots in quick succession).

What "source" means

AudioSource is the host-component analogue of the renderer's Sprite: a thin behavioural component bound to a WorldObject that exposes a tidy play() / stop() surface and hides the audio-graph bookkeeping. The component holds:

  • A default asset — the clip most calls play, often the only one.
  • Default volume and pan — applied to each voice unless the call site overrides them in AudioSourcePlayOptions.
  • The set of voices it has spawned but not yet finished, so it can AudioSource.stop them in bulk or clean them up when the host WorldObject is destroyed.

Spawn vs play

Unlike Music, voices are spawned per-play, not held by the component. AudioSource.play returns the spawned AudioInstance for the rare caller that wants to fade or stop one voice specifically; most callers ignore the return value entirely.

Stereo positioning

AudioSource does not auto-position based on the host's world position — the engine's panning is a manual [-1, 1] knob, not a positional PannerNode model. If you want a sound to follow the host, set AudioSource.pan from your own controller (e.g. interpolate from host.position.x against the camera). A positional/PannerNode-based variant may land later.

Example

const player = world.createObject();
const shoot = game.assets.getAs('gunshot', AudioAsset);

player.addComponentFromFactory(
  'audio',
  (host) => new AudioSource(host, shoot, { volume: 0.6 }),
);

// Later, in the input handler:
player.getComponent<AudioSource>('audio').play();

Constructors

#
constructor(host: WorldObject, asset: null | AudioAsset, options: AudioSourceOptions): AudioSource

Parameters

Properties

#
enabled: boolean

Per-component gate on the three update hooks (onPreUpdate, onUpdate, onPostUpdate). When explicitly false, the engine skips all three for this component during the host's tick — useful for temporarily pausing behaviour (e.g. a freeze powerup) without removing the component and losing its internal state.

Does not gate onAdded or onDestroy; those always fire so a host can never end up with a half-attached component.

readonly #
host: WorldObject

The host this component is attached to. Stored read-only; subclasses access it as this.host directly, or through the tier-appropriate aliases (this.world, this.game) on the per-tier abstract bases.

Accessors

readonly #
activeVoiceCount: number

The number of voices this source currently has running. Useful for tests and for caps ("don't spawn more than four concurrent footsteps").

readonly #
asset: null | AudioAsset

The default AudioAsset this source plays, or null when the source was constructed without one.

readonly #
game: Game

The Game the host's world belongs to. Always non-null — the world's game field is a mandatory construction argument, not an option.

#
pan: number

Default stereo pan from -1 (left) to 1 (right) applied to each new voice. Setting this also re-targets currently-playing voices.

#
volume: number

Default volume from 0 to 1 applied to each new voice. Setting this also re-targets any currently-playing voices spawned by this source — a single source pretends to be one continuous emitter even when it is actually a bag of one-shots.

readonly #
world: World

The World the host WorldObject lives in. Shorthand for this.host.world.

Methods

#
onAdded(_deps: Record): void

Lifecycle hook that is called when the component is added to the host object. Should not be called directly.

Parameters

  • _deps Record

Returns

void
#
onDestroy(): void

Stops every active voice and releases the source's audio graph resources when the host WorldObject is destroyed.

Returns

void
#
onUpdate(_update: WorldUpdate, _deps: Record): void

Lifecycle hook for the main update phase. Called once per world tick, after every component's onPreUpdate and before any onPostUpdate.

Parameters

Returns

void
#
play(options: AudioSourcePlayOptions): AudioInstance

Spawns a fresh playback voice and starts it. Each call produces an independent AudioInstance, so overlapping plays (rapid fire, footstep cadence, a triggered burst) layer naturally instead of cutting each other off.

The voice is registered internally so AudioSource.stop and onDestroy can shut it down in bulk, and unregistered automatically when the underlying source ends.

Parameters

Returns

AudioInstance

The spawned AudioInstance. Most callers ignore the return; reach for it when you want to fade or stop a specific voice.

Throws

EngineError with code ErrorCode.AUDIO_NO_SOURCE when no asset is supplied and the source has no default asset to fall back on.

#
setAsset(asset: null | AudioAsset): void

Swap the default AudioAsset. Does not affect voices already playing — they keep playing the asset they were started with.

Parameters

Returns

void
#
stop(): void

Stops every voice this source is currently playing and tears each one down. Idempotent — calling on a source with no active voices is a no-op.

Returns

void
ESC