Base — ships in GS_Audio.
An audio event is a named sound the game can fire. Events live in .aev event libraries, which are loaded onto the Audio Manager; firing one is a matter of naming it.
The important structural fact: an event declares only what plays. Everything else — pooling, concurrency limits, distance falloff, 3D tracking, spatialization, re-fire suppression — is shared machinery that every event type inherits. That is what makes adding a new kind of sound source cheap.
For usage guides and setup examples, see The Basics: GS_Audio.
Contents
- Event Libraries
- Event Types
- Shared Configuration
- Firing Events
- Instancing and Pooling
- Spatialization
- Writing a New Event Type
- See Also
Event Libraries
AudioEventLibrary
A loadable collection of events, authored in the Asset Editor.
| Field | Value |
|---|---|
| Extension | .aev |
| TypeId | {04218A1E-4399-4A7F-9649-ED468B5EF76B} |
| Extends | AZ::Data::AssetData |
Libraries are assigned to the Audio Manager and can also be added or removed at runtime:
| Method | Parameters | Description |
|---|---|---|
AddAudioLibrary | AZ::Data::Asset<AudioEventLibrary> | Loads a library and registers its events by name. |
RemoveAudioLibrary | const AZStd::string& name | Unregisters a library’s events. |
Both are on AudioManagerRequestBus.
Event Types
GS_AudioEvent is an abstract base, and a library holds AZStd::vector<GS_AudioEvent*>. When you add an event in the Asset Editor, the type dropdown offers every registered subtype.
This is the framework’s standard polymorphic array authoring shape: a raw-pointer vector of a reflected abstract base, where the serializer supplies the type picker and the owning container owns its elements.
| Type | Source of sound | Authored fields |
|---|---|---|
| GS_AudioEvent_Pool | Sound file assets | Sound Pool — a pool of MiniAudio::SoundAsset. One is picked at random per fire. A single file is simply a pool of one. |
| GS_AudioEvent_Noise | Procedural noise | Noise Type (White / Pink / Brownish / Blueish) and Duration Seconds. Setting the event to loop overrides duration and runs continuously. |
| GS_AudioEvent_Sfxr | Procedural chiptone | Profiles — a pool of .sfxrprofile assets, randomized per fire. The profile’s envelope defines the length. |
The pooling model is the reason to prefer pools over single assets. Five mutated explosion profiles in one Sfxr event, or five recorded footstep variants in one Pool event, means the sound never repeats identically — with no logic on the calling side.
Shared Configuration
Every event type carries these, regardless of what produces its sound.
| Field | Default | Description |
|---|---|---|
| Event Name | The name PlayEvent* resolves. | |
| Mixing Channel | Where this event routes — a volume channel or a named mix effect chain. Both live in the same namespace. | |
| Base Volume | 100 | Event volume before channel gain. |
| Distance Min/Max | (1, 20) | Metres. Full volume within min, attenuating out to max. |
| Outer Volume | 0 | Level beyond the max distance. |
| Is 2D | false | Pure stereo, no spatial consideration. |
| Loop | false | Repeat until stopped. |
| Concurrent Event Limit | 5 | Maximum simultaneous voices for this event. |
| Instance Pad Size | 3 | Spare voices kept in the pool. |
| Event Repeat Hold | 0.05 | Seconds of re-fire suppression, so a rapid trigger cannot machine-gun the sound. |
| Pitch Modulation | zero | Per-fire pitch jitter. The Pitch mix effect gives finer control over the same idea. |
Minimum distance must stay above zero
The inverse distance model collapses to silence at a minimum distance of0. The framework clamps it, but an event authored with min distance 0 is not expressing what its author expects — set a real minimum.Firing Events
All three are on AudioManagerRequestBus, and all three resolve the event by name across every loaded library.
| Method | Parameters | Description |
|---|---|---|
PlayEvent2D | const AZStd::string& eventName | Fires with no spatialization. |
PlayEventAtLocation | const AZStd::string& eventName, const AZ::Vector3& position | Fires at a fixed world position. |
PlayEventOnEntity | const AZStd::string& eventName, AZ::EntityId entity | Fires on an entity and tracks it — the voice follows the entity as it moves. |
Instancing and Pooling
Each event owns a flat pool of voices, and the model is identical across every event type.
- A fire takes an idle voice from the pool, or produces one if none is free.
- Active, paused and tracking sets are maintained per event. The tracking set maps a voice to the entity it follows for 3D updates.
- The pool is trimmed on an interval — by default every 10 seconds — so a burst of sound does not permanently inflate memory.
- The concurrency limit is enforced per event, so one over-eager emitter cannot flood the mixer.
Routing survives late changes. When a mix effect registers after an event has already preloaded, the manager re-points every pooled and future instance at the new target. In practice this means you can add a MixEffectComponent at runtime and voices that were already pooled will follow it — you are not required to have the routing in place before sounds exist.
Spatialization
Resolved once at preload; the project’s spatialization mode does not change at runtime.
When binaural is active, a 3D voice routes through its own Steam Audio binaural node instead of miniaudio’s spatializer, and the event pushes the listener transform as it ticks. The shared Steam Audio context and HRTF are borrowed from the Audio Manager rather than created per event.
See Spatialization for the behaviour, and the Audio Signal Model for why this is a property of the source rather than an effect.
Writing a New Event Type
Subclass GS_AudioEvent and implement a small set of virtuals. Everything in Shared Configuration, Instancing and Pooling and Spatialization is inherited.
| Hook | Required | Purpose |
|---|---|---|
CreateInstance(engine, targetNode) | Yes | Produce one fresh playable voice attached to the target node. |
IsSourceReady() | Yes | Whether the source can currently produce instances. |
HasContent() | Yes | Whether the event has authored content. An event with none is a silent no-op. |
AcquireAssets() | No | Re-acquire referenced assets with PreLoad behaviour. |
QueueLoad() | No | Kick off asynchronous asset loads. |
PreloadSource(engine) | No | Register or prepare source data against the engine. |
UnloadSource() | No | Free source data. |
The four optional hooks exist for asset-backed sources. A generator — noise, sfxr, or anything you synthesise — leaves them as no-ops and is simply ready once the engine exists. The asset machinery is optional, not assumed.
Reflect your subclass and it appears in the event type dropdown automatically. There is no registry to add it to.
See Also
For related systems:
- Audio Manager — loads libraries and owns the listener
- SFXR Profiles — what the Sfxr event type consumes
- Mixing & Effects — where an event’s mixing channel routes to
- Audio Signal Model — how a fired event reaches the speakers
For conceptual overviews and usage guides:
Get GS_Audio
GS_Audio — Explore this gem on the product page and add it to your project.