Audio Files for Audiophiles

Hi, I’m Adam and I’m a new member of the Advent team. I’m a self-taught programmer, who’s been messing around with game dev for many years. I’ve been a part of some solid hobbyist projects (and many that didn’t go very far, though they all were valuable learning experiences), but nothing as promising as Advent of the Reaper, and I’m excited to be here!

After acclimating to the project, my first major task was to build out a sound system to handle the game’s needs. This was exciting, because it gave me a chance to tackle a problem area I’ve never spent much time on. Also, the soundtrack to the game is truly remarkable, and giving it the justice it deserved was gratifying.

Unity’s Sound System

There’s a lot of noise around Unity’s sound system and its limitations. Most sound designers I’ve worked with prefer to have FMOD or WWISE integrations to interface with as they make their magic. On the other hand, I’ve never seen anyone articulate anything specifically wrong with Unity’s system, and our needs are straightforward. As a 2D tactical game, we don’t need to worry about positional or distance effects, doppler shift, or other such things. We need to play one-shot sound effects, looping musical tracks, and handle transitions between those tracks (fades, crossfades, and ducks).   

Can anyone hear me?

Unity’s sound system at its most basic involves one or more sound emitters (Audio Sources) along with one or more listeners (Audio Listeners). Again, we don’t need positional audio, so one listener on a camera works, and we don’t care where the Audio Source(s) are, which means they can be centralized as a system that can exist in all levels. So, I placed several of them (more on this later) as children on an ‘Audio System’ object which is part of the Main scene and always loaded in the game.

One Audio Mixer to Rule Them All

Although I hadn’t done much thinking about audio systems before, Lucas had already put some thought into things and realized that an Audio Mixer would help achieve our goals. In addition to allowing for some neat effects, it had a big advantage in that it allowed control of sound by channels (or groups, in Unity-speak). This simplified controlling sound levels, since each Audio Source could be assigned to a specific group, and then no matter how many such sources exist in the project, each group can be controlled easily. It also greatly simplifies controlling global volume (the Main group) and individual channels (the SFX and Music groups). The system I was building wasn’t too complicated, so this was only a small bonus, but in projects with different audio needs, it could be a lifesaver. It did also provide one big piece to the audio puzzle — the ability to “duck” groups behind each other, which is when one channel’s volume lowers when another’s is increased. This handy feature is useful for the game’s flourishes, which is something I’ll discuss below.

Unity Audio Mixer

Implementing Different Audio Scenarios

One-shot Sounds (Play it once, Sam, for old times’ sake)

The simplest case to handle is the short clips that are ‘fire and forget.’ All the little bleeps and bloops used for cursor movement, button presses, and the like. A single Audio Source can handle dozens of one shots overlaid on each other simultaneously, so I only used one for this. There is a limitation to this though — if too many sounds are fired at the same time, Unity will stop playing some sounds, presumably to conserve CPU resources or memory. This was an issue for the cursor bleeps, since with a mouse the player can trigger the firing of many sounds in a short period of time.

Audio is lost when too many sounds fire simultaneously

There are a few ways to fix this. The first is to make sure that sound clips only last as long as they need to. The original sound clips had a tail of no sound, lasting over 1 second in length, even though the actual ‘bloop’ is only about 0.2s long. Nothing would play during these tails, but the clip is still considered fired until the end of them.

Original sound clip

Trimmed sound clip

Default Max Real Voices

Trimming this helped, but it was still possible to fire cursor bloops fast enough to overwhelm the system. It is possible to increase how many clips can play concurrently (Max Real Voices), through Unity, but increasing this too much can cause excess resource consumption. Besides that, the default of 32 concurrent clips (‘Max Real Voices’) seems plenty. If the player is moving the cursor fast enough to fire that many clips, there won’t be any way to properly associate which movement fired which sound anyway. So, a simple solution that keeps resource usage down is to limit how fast the bloops can fire, which requires a simple check to see when the last one was fired. The delay is quite low, so any reasonable movement of the mouse should feel right.

Code limiting bloop speed

This fixed the issue completely, and doesn’t make moving the cursor feel any less solid than it should.

Fixed!

With the one-shot sounds handled, the next task was to take a look at how the music of the game was meant to work. The simplest case was a song meant to fade in over time. This was straightforward — just send the music clip to the Audio System and ask it to fade into some volume over some amount of time. The Audio System then picks one of the music Audio Sources, and emits to it, increasing volume over time until it reaches the target.

Crossfades

The next case was when one track was meant to crossfade to another. This is similar to the first case, in that the new track is provided, as well as the target volume and time for the fade. But in this case, the Audio System knows to send the track to the idle music Audio Source, increasing its volume over time, while at the same time fading the old track out.

Crossfading

Amp-up Crossfades

The third case was when two tracks were meant to stay synchronized, with periodic crossfading between them. This is the case for the main level theme, and the combat version of that theme, or the main BGM themes. Synchronization is vital, since the two tracks are very similar, with the combat version being a bit more exciting. Here, both tracks are sent to the Audio System at the same time, and whenever needed, a call to request crossfading between the active and muted music Audio Source can be made. 

This is jarring, and the player will quickly notice the music isn’t in sync.

Much better.

Looping Clips

The fourth case was when a new track was meant to be played without disrupting the synced BGM tracks. Things like playing a clip for a boss or tutorial. These clips need to loop, since the length of time they are playing isn’t known, and the fading between the temporary channel and the two other music channels is handled in code.

Looping clip for a boss

Ducking Clips

The last case is a special one. Here, a music clip is meant to be crossfaded in, while the current music is crossfaded out. In this case though, the incoming clip is a one-shot, i.e. a non-looping track, and once it is finished firing, the original track should fade back in. An example of this is the player and enemy turn flourishes that play to mark the beginning of a turn.

While it is possible for this to be handled in code, it would be complicated, and Unity provides something that works easily.

What we need is a channel that fires once (so, an Audio Source with looping turned off), but that automatically will take priority and lower the volume of other Audio Sources while it is playing. When such a clip is fired, the BGM clips keep playing but the volume adjusts automatically while the one-shot clip is playing, and again once it is done.

One-shot flourish

OK, that should give you a peek behind the curtain of AotR’s sound system. Hopefully, you enjoyed it!

A Note from Lucas

Lucas here. We’re super happy to have met Adam and I’m extremely impressed with how quickly he’s gotten up to speed with the codebase. This overhaul of our audio systems was desperately needed — I wrote some hacky code in a weekend prior to submitting AoTR to a competitive conference and always meant to rewrite it the “right” way (I wouldn’t know where to start)! Having a mixer that allows these crossfades, “ducking,” and more will be critical as we look to add tutorial screens, more levels, and more battle features, and Adam’s been helping me understand the new functionality. Onward!


Bonus Loot

As an extra bonus for this month, please enjoy this new gameplay footage video showing off many of the improvements we've been working on, including the new audio implementation!


SIGN UP FOR OUR NEWSLETTER

Go behind the scenes of our game development, get sneak peeks at art, and find us at events

Previous
Previous

Meet the Writer: Dan

Next
Next

Chapter Clear: Midwest Gaming Classic 2024!