arcade2d
Class

Music

audio/music.ts:58

Plays a single, long-lived audio track at the world tier — the background music for a level, menu, or boss fight.

Music is a world-scoped component (one playing track per world is the canonical model) that owns exactly one AudioInstance routed through the AudioEngine's music bus. The component proxies the standard playback surface — Music.play, Music.pause, Music.stop, Music.restart, volume, pan, loop — directly to that instance, so game code talks to a single component without caring that an AudioInstance is doing the work underneath.

When to reach for it vs. AudioSource

Use Music for one long-running track per world. Use AudioSource for short one-shot SFX attached to world objects. The difference is the lifecycle:

  • A Music instance is created once and reused — pause and play resume from the same position, stop rewinds.
  • An AudioSource spawns a fresh voice per play() so several copies of the same SFX can overlap.

Autoplay and the user-gesture rule

Browsers suspend a freshly-created AudioContext until a user gesture unlocks it. Setting autoplay: true on a Music component that is attached before any user input will call play() immediately, but the underlying context may still be suspended — audio starts inaudibly and becomes audible the moment the player clicks, taps, or presses a key. Use AudioEngine.resume from a click handler if you want deterministic start-on-gesture.

Example

const theme = game.assets.getAs('theme', AudioAsset);

const world = game.createWorld({
  components: (w) => ({
    music: () => new Music(w, theme, { volume: 0.5, autoplay: true }),
  }),
});

// Later, in a pause handler:
world.getComponent<Music>('music').pause();

Constructors

#
constructor(host: World, asset: AudioAsset, options: MusicOptions): Music

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: World

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 #
duration: number

Track duration in seconds.

readonly #
game: Game

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

readonly #
instance: AudioInstance

Direct access to the underlying AudioInstance. Use this for advanced playback control (subscribing to AudioInstance.onEnded for a non-looping track, hooking into the buffer for visualisations, etc.). The proxy methods on this class cover the common operations.

#
loop: boolean

Whether the track loops at its end. Defaults to true on construction.

#
pan: number

Stereo pan from -1 (left) to 1 (right).

readonly #
paused: boolean

Whether the track is currently paused. The next Music.play resumes from the same position.

readonly #
playing: boolean

Whether the track is currently playing.

readonly #
stopped: boolean

Whether the track is currently stopped (rewound). The next Music.play starts from the beginning.

#
volume: number

Volume from 0 to 1. Multiplied with the engine's music-bus and master gains at playback time.

readonly #
world: World

The World this component is attached to — identical to AbstractComponent.host at this tier, exposed under the world name so subclass code reads the same on every tier.

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

Tears down the underlying AudioInstance when the world 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
#
pause(): void

Pauses playback in place. The next Music.play resumes from here. Idempotent.

Returns

void
#
play(): void

Starts playback from the current resume position — zero on a fresh component, the pause offset after Music.pause. Calling on an already-playing instance is a no-op.

Returns

void
#
restart(): void

Stops the track if it is running, rewinds to the start, then plays. Equivalent to Music.stop followed by Music.play.

Returns

void
#
stop(): void

Stops playback and rewinds to the start. The next Music.play starts from the beginning of the track.

Returns

void
ESC