Vertical vs. Horizontal
The choice of a horizontal or vertical music system is often the difference between a linear or non-linear style gameplay. Last time, we introduced the advantages of using a horizontal music system in a UDK game. A horizontal approach is best used when the composer is aware of how the music system will transition from one musical loop to the next. A particular piece of music will loop over and over again as many times as it needs, then transition to the next loop at a predetermined event; for example all enemies dead, player killed, or time running out. A horizontal system will only play one stereo music track at a time. Transitions from one piece of music to the next can happen immediately, or over time using a fade.
In contrast, a vertical music system is best utilized when the outcome or timing of any particular cue, scene, or part of the game is unknown. This is often the approach used in open world adventure games where the player can take a unique path through the storyline. A game’s soundtrack needs to change in response to the player’s action or game parameters. In open world type games the player is moving from one town or location on the map to the next, each area can have a specific piece of music attached to it. As the player enters that area the music system transitions to the correct piece of music by fading in the track that was playing in the background. While exploring the game world there can be invisible “lines in the sand” that trigger the correct piece of music for that new area of the map.
A vertical system has two main ways of introducing a new layer of music: either immediately or fading over time. The simplest system will have the music play immediately as soon as it is triggered. There is a lot use for a system that triggers immediately, mainly the element of surprise or attack. This technique can be used in horror games when needing to build the intensity and tension in a piece to scare the player. A vertical approach can be used to introduce or remove particular element of the music soundtrack when necessary, according to choices made by the player. Enemies attack, monsters jump out at you, all triggering music and sounds immediately, often without consideration of the tempo or bpm.
Vertical systems are well utilized during periods of exploration or during a battle scene, when the length of a particular piece of music needs to play is unknown. The player can explore different areas of the game world and trigger different piece of music dependant on location in the game map. Distance is also a deciding factor in an exploration audio system. How close or far the player is from an object can determine which piece of music is playing and how loud it is heard.
The truth is many modern games use a combination of both horizontal and vertical approaches. Through a combination of timed music cues, loops, stingers and transitions, a music soundtrack can be molded to fit the particular style of gameplay at any point during the experience.
Setup for Vertical System
Think of a vertical music system as being similar to a multitrack DAW session. Each track contains one or more elements of the overall mix. The tracks have individual volume controls allowing different instrumentation to be brought in and out of the mix as needed. Vertical arrangements are used to play one or more tracks of music simultaneously, typically layers of the same composition. In UDK this means we need to keep multiple soundcues running in sync together, along with control over their playback and volume.
One of the more standard approaches used in a vertical system is to have the full soundtrack split out into multiple stereo music stems, divided by similar instrumentation. Each of these stems are audio loops of the same length, utilizing the same musical key and BPM. The music system starts playing all the loops simultaneously, once the end of the file is reached the music system will loop back around to the top. Since some layers of the mix are not meant to be heard from the start, these loops play in sync with the rest of the music but their volumes are set to zero so they are muted in the mix. Once a new layer of the mix is needed the music system can immediately unmute it or fade it in over time. In Kismet, we need to be able to control multiple soundcues, triggering them to playback in sync to create the full loop. We also will need to set and fade their volumes at the correct time to create the audio mix.
It is best to keep all audio files the same length and the same number of bars. If a particular loop is going to be shorter than the others, the length of this file should still be a musical division of the overall piece. For example, if a main loop is 16 bars long the other bars should be a division of that (8,4,2,1). All cues need to loop seamlessly with no pops, clicks, or noticeable changes when the loop restarts. The music system operates as one big loop that can fade or unmute different layers to build the mix, determined by a variety of factors.
Fading two pieces of music together can introduce a number of issues with timing and sync. Anyone who has listened to a bad DJ has heard this before. Are the two pieces of music in sync? Did they start at the same time? If one started later, did it start on the next downbeat or somewhere out of sync? When should the fade start? How long will the fade be? The problems introduced by these types of question require a more intelligent music system to create a successful game soundtrack.
A smart music system like this would take into account bars, beats, and the tempo of the music. The game knows where we are in a music loop (bars & beats), and how fast we are going (tempo). It can then use this information to make intelligent decisions about how and when to transition the music. If it knows when the next bar or beat is and how long a fade should be it can properly fade any piece of music, in or out, synced to the music.
Vertical System in Kismet
The vertical music system for our example will use many different pieces of music that will crossfade in and out as the player enters new areas. TriggerVolumes are located at different points in the map to change the music system at the right time. When the game starts all PlaySound Kismet nodes are triggered to start playing at the same time. All tracks, except one, are muted leaving only the first to play at the beginning of the game. Typically vertical music systems have an ambient track that plays at all times or an intro track that plays only at the beginning.
As the player moves through out the world they enter a new location and trigger a different piece of music. That music will fade in over a predetermined amount of time. The new layer of music will remain in sync with the rest of the mix because it has been playing along with the other music tracks from the beginning. We need the functionality to play, stop and fade a music loop either immediately or in sync with the music. We will also need to consider what game events will be used to trigger the music system to play correctly.
The challenge when developing a vertical music system in Kismet is the lack of any pre-existing node that has any reference to tempo, bpm, bar or beats. By itself Kismet has no internal musical clock, it is tied to the framerate of the game. We have to build one instead. If we know bpm and the number of bars in an audio file we can determine the length of the loop. Keeping sample accurate playback of audio loops is a challenge in a toolset that isn’t built for music. The game clock is typically based off a variable framerate, instead of bars and beats. Soundcues have the internal ability to loop, but without an external clock there is no way to keep more than one in sync. If we use a timer we can trigger two or more files of the same length to loop at the same time. If we don’t want them to be heard at the same time we have find a way to fade the audio in and out.
We can imagine a custom Kismet that has the ability to play and loop a single soundcue, it understands and uses info like BPM and bar length, and has the ability to fade audio up and down. If we can trigger two or more of these nodes at the same time then we should be able to keep them in sync with an external timer. Assuming that the length of the timer equals the length of the audio files the audio files should loop in sync. If one node triggers at full volume and the others are muted we should be able to crossfade the two pieces of music with the ability to control when the fade happens and how long the fade will be.
In Kismet we will need to create a custom node that can load up any soundcue then attach it to an AudioComponent for playback. The AudioComponent can control the audio playback, looping, and volume. This Kismet node has two outputs. ‘Finished’ is fired every time the end of the file is reached, ‘Out’ fires when the Kismet node is first activated.
This Kismet node will have four inputs to control of playback of the audio. ‘Play’ starts the file playing with the volume at 100%, ‘Stop’ ends playback of the file, ‘Mute’ toggles the volume of the AudioComponent between 0% and 100%, and ‘Start Mute’ begins playback of the file with the volume set to 0%.
This Kismet node also takes in a few parameters. Bars per Measure is a float variable that is the number of bars in the musical loop, Beats per Minute (BPM) is the tempo of the music represented as a float variable, and the Bars per Fade is the number of bar to use while the audio fades in or out
The real difficulty of a music system like this is having a music system that is smart enough to keep track of tempo of the music and the number of bars in a loop. With a bit of math we can determine how long a music loop is if we have a pre-determined tempo and number of bars.
In our next article we will discuss how to actually build this custom kismet node that can track musical parameters like volume, bars, and bpm. If you have any questions contact me chris.at.engineaudio.com or post a comment below.