Audio
Audio in Zero is built from two components. An Audio component makes an entity emit sound from a .soundClip asset. An AudioListener component makes an entity the "ears" of the scene. Both live on…
The two halves: source and listener
You need one of each for spatial sound to be heard. The source emits; the listener hears.
-- the ears: attach a listener to whatever should hear (a camera, the player, …)
entity.find("camera").component.add("AudioListener")
-- a one-shot effect
entity.find("sfx").component.add("Audio", { clip = explosionClip })
-- looping music
entity.find("music").component.add("Audio", {
clip = themeClip, sourceType = "Music", looping = true, volume = 0.7,
})
-- spatial sound, positioned by its entity, heard relative to the listener
entity.find("campfire").component.add("Audio", {
clip = fireClip, spatial = true, looping = true,
})
The listener is explicit — you choose which entity hears. A scene with audio sources but no active AudioListener is reported at load: spatial audio has no ears until you add one. Attach the listener to whatever the player experiences the world through. When several listeners are active, the first one drives the ears.
The clip is a .soundClip asset
Audio.clip points at a .soundClip asset — a typed handle, not a path. A loose audio file (ogg/mp3/wav/flac) is promoted into a .soundClip by the importer, which encodes its playable payload. Find existing clips with asset.list("soundClip"), bring more in from the shared library, or generate them with the audio service (the generating-assets-and-content guide).
Whether a clip streams its compressed payload or decodes fully on load follows the clip's own loadType setting — "decompressOnLoad" and "streaming" apply directly, and "auto" (the default) picks by duration, so short one-shots decode up front and long tracks stream. Streaming supports spatial sound.
Common fields
Audio: clip (an AssetRef<soundClip>), sourceType ("SoundEffect" / "Music" / "Ambient"), volume, pitch, looping, spatial, maxDistance, autoplay, channel.
AudioListener: active (whether this listener drives the ears).
Because both are components, you change playback or move the ears by setting fields like any other component (the components guide), and a moving entity carries its sound — or its hearing — with it.
One-shots
For a fire-and-forget sound — an impact, a pickup, a footstep — call playOneShot on an Audio component:
entity.find("gun").component.get("Audio"):playOneShot(shotClip)
entity.find("gun").component.get("Audio"):playOneShot(shotClip, { volume = 0.6, pitch = 1.2 })
It plays the clip once through a short-lived host at the source's position (spatial if the source is spatial), then cleans itself up. Many one-shots can overlap while the source's own clip keeps playing, so one Audio component drives a whole family of SFX. It leaves the source's clip and playback state untouched.
Finding the exact fields
asset.inspect("@builtin::components.Audio") and asset.inspect("@builtin::components.AudioListener") print each component's full field list and usage; the components guide explains how component fields work in general. The model to hold: sound is a capability you attach to an entity, and so is hearing.