Builtin Library
README.md
Audio
Adds audio playback to an entity, driven by a .soundClip asset. Supports sound effects, music, and spatial/3D audio tied to entity position.
Public fields: clip (AssetRef<soundClip>), sourceType ("SoundEffect" / "Music" / "Ambient"), volume, pitch, looping, spatial, maxDistance, rolloff, doppler, autoplay, channel, pitchValue, volumeValue.
pitchValue and volumeValue name named values (values.set, the topics/values guide) the voice follows: it plays at pitch times the value and volume times the value the entity, or its nearest ancestor holding one, carries under that name, read every frame with no script writing the source. An engine note on a car follows car.values.set("rpmRatio", rpm / 1000); a tyre squeal on a wheel takes volumeValue = "wheel.skid".
A spatial source plays at full volume within one unit of the listener and reaches silence at maxDistance (default 50). Across that window its amplitude is (1 - t)^rolloff for a source t of the way through, so the default rolloff of 1 is a linear fade — half the distance, half the amplitude — a larger exponent drops away sooner, and 0 holds full volume to the edge.
A spatial source moving toward or away from the listener is heard Doppler shifted: its pitch rises while they close and falls while they part. doppler scales the shift (1, the default, is physical; 0 turns it off), and the world settings audio.doppler_scale and audio.speed_of_sound (default 343 units per second) apply to every source. The audio guide's "How a moving source shifts in pitch" states the relation.
Methods: play(), pause(), stop(), setVolume(v), setPitch(p).
entity(id).component.add("Audio", { clip = explosionClip })
entity(id).component.add("Audio", { clip = fireClip, spatial = true, looping = true })
A loose audio file (ogg/mp3/wav/flac) needs to be imported into a .soundClip asset before it can be referenced here — the importer creates the container and encodes its playable payload.
Whether the 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 clip's default) picks by the clip's duration — short one-shots decode up front, longer tracks stream. The clip decides: each source this component builds asks clipRef:streams(bytes).