I am proudly in charge of the music for a lovely videogame called Passing By and in the spirit of Learning In Public I start a little series on game music production! We use Audiokinetic Wwise for all game-audio and I’ll start with something a little technical but actually crucial for interactive game music: How does randomness really work in Music Playlist Containers?
How Music Playlist Containers work
A Music Playlist Container can be wrapped around Music Segments and then played back as if it were one itself. While segments provide the means to do vertical arranging (work with simultaneously played layers of music), playlists enable horizontal arranging (work with the order different segments are played in). To this end, you can not just create a simple sequence of tracks but especially create nested Groups of tracks – and the whole playlist is also one such Group. There’s also a video by Audiokinetic covering some – but not all – of this post.
On one hand Groups can be either Continuous (Play the whole thing each time) or Step (Play one part each time, remembering the progress between plays). On the other hand they are either Sequence (Follow the order from top to bottom) or Random (Ignore the order of the tracks):
- Sequence Continuous – Just play all tracks in order
- Sequence Step – Play the next track each time
- Random Continuous – Play all tracks shuffled, each track at least once
- Random Step – Play a random track each time
- Loop Count: How often to do whatever it does. Can mean repeating a segment, playing a couple of next items in a Step-Group, or repeating a Continuous-Group. In a Standard Random Continuous Group this actually defines how often every item has to be played at minimum and may repeat more likely items much more often. To repeat infinitely enter 1 and press the down-arrow – instead of zero it will do the ultimate opposite and turn to infinity!
- Weight: Changes the probability of an item within Random-Continuous Groups. Something with weight 20 would come twice as often as something with weight 10 for example. In Shuffle Groups this actually has no effect.
- Avoid Repeat: How many other items have to play until any specific one is repeated in a Random-Group. Setting this to the number of items in the Group causes it to loop a fixed order, because any item has to wait for all others until it comes again – kind of like in twelve-tone music 🙂
- Random Type: Standard picks randomly from all items each time – notably the Continuous version goes on until every item had its turn at least once. Shuffle decides a random ordering of all items – at the start and each time after it has finished all items.
Also the Randomizer can be applied to the Loop Count, to pick the actual value from a range. To use it, just double-click the little gray (then orange) coffee bean. 🙂
To illustrate this let’s reconstruct what some example setup is actually doing!
(1) The whole playlist is simple Sequence Continuous, run once. It starts by just playing A and B.
(2) Then comes the first nested Sequence, which is played three times in total: First it plays C. Then (3) one of the interludes in ascending order. Then (4) one of the other tracks in random order, and finally (5) the track D one, two or three times. This could for example look like this:
C > Interlude1 > OtherTrack > D >
C > Interlude2 > SomeTrack > D > D > D >
C > Interlude3 > YetAnotherTrack > D
(6) Finally it picks one of four tracks randomly forever, with one track much less likely. Because of Avoid Repeat = 2 it will probably loop the first three tracks in the same order for a while and then play the very unlikely track and slide into a new ordering of the first three afterwards.
Special track occurring exactly once
In the game Passing By, the player travels between floating islands with an air balloon. I create Music Playlist Containers for “Flight” and “Island” states separately and each of them consists of several regular tracks and a special, distinctive melody track. I want the special track to occur exactly once on each island, as to not strain the players ears with an overly repeated melody. Also the special track should not occur right at the beginning.
With the Loop Count parameter of the first group I can specify how many tracks should play at least before the special track, and with the Randomizer I can use the Max Offset to specify how many tracks should play at most. If the tracks are roughly the same length (I mostly use 8 bar loops), this translates directly to a time duration until the special track can occur the first time, as a kind of “warm up” for the new environment the player is in.
I can now set different Weights for the individual tracks – here I have two basic tracks with weights 50 and 40 and a slightly more varied one. I would now like to force the varied one to only play once in a row while allowing repetition for the others. This can be achieved by setting the Avoid Repeat to 1 and putting the Randomizer on the Loop Counts of the two basic ones to allow them a certain amount of repetition.
Another approach would be to duplicate all basic tracks, allowing Wwise to jump between the same track and therefore repeating it. However this would hide the true number of distinct tracks and clutter the playlist.
Using this setup on the first group however now raises a small problem: A looped item still just counts as one “step”, just a much longer one, therefore the maximum length until the first group is finished can potentially be much longer. Therefore I only use this setup in the second group which has no (soft) time restriction, and compensate in the first group with a much lower Weight for the varied segment.
Optional intro track
While I have not found a way to explicitly have an item play “zero or one times” (the randomizer on Loop Count never goes below one), there is a way to make an item a optional “intro” to another one, as also shown in the official video.
This again relies on copying something, in this case the “Track that deserves an intro”, to have it once alone and once in a sequence with the intro and both of this in a Step-Group (Random or Sequence). That way you effectively have an optional track, with specifyable probability – but only if you copy (and therefore know) what comes directly afterwards.
Different Melody each time
The melody tracks for Passing By should not not only appear just once per island – I also prepared several melody and want a different one to play for each new island but also not re-create the accompaniment for each melody. This can be done very easily from within the Music Segment!
For this purpose I add each melody as a sub-track of the Melody Track, which is set to Sequence Step. This will make Wwise play the first sub-track on the first occurrence, the second sub-track the next time, and so on. This also works, if the playback leaves the containing Playlist Container or Switch Container.
Unfortunately it seems, that randomly choosing the order of the sub-tracks is not possible that easily, as the Random Step group seems to not use a shuffled ordering as in the Playlist Container, but rather picks freely from all tracks each time, risking repetitions. A workaround would be to create a new Segment for each melody, copy the accompaniment and put them in a Random Step group within a Playlist Container, which will also remember what it already played even if the playback leaves the container.
- While a Random Group with Shuffle seems to implicitly avoid repetitions, it may repeat the same item if the whole group is looped and it is placed at the end of one ordering and at the beginning of the next, e.g. “a > c > b” and then “b > a > c”. So setting Avoid Repeat to 1 or higher actually does have an effect here.
Note: setting it to at least the number of items minus one actually forces it to repeat the first order all the time, behaving just as Standard mode with the same Avoid Repeat setting.
This article is actually a work in progress as I continue to work on Passing By. I want to update it with more scenarios and insights as I move along.
If you have any remarks, or ways to do certain things better, I’d love to read from you in the comments!