Dynamic Music Tutorial for Half-Life 2: Episode TwoThis is the first time I write a tutorial, so please excuse any mistakes I might do. In this tutorial I will show you how I implemented dynamic music in my Half-Life 2: Episode Two maps, but this technique can be used in any Source game, although not neccessary for something like Left4Dead 2 (but Black Mesa, to name a modern singleplayer Source game).
Maybe there are better ways to do this, if you know one, please tell me. Also I won't be going into soundscripts which apparently give you a little more control of a few things, but I didn't go into those far enough yet to be able to talk about them. There are two ways how I personally implement dynamic music in my maps, and I will go in-depth into each of those, but there are easily more ways to have dynamic music.
What you needIf you created a song yourself, you obviously have way more control about each part, I will focus on choosing existing Half-Life music. To be able to create dynamic music from existing songs, you will need some (very) basic Audacity skills (or any other sound-editor).
1. Choose a song you like and that fits
2. Identify sections that can be split into individual parts
3. Loop the part that is responsible for combat: Either loop the audio itself in audacity (which will create a large file), or make the sound loopable in-engine, which I won't explain here though. Having a large file isn't a problem though, just make sure it is a .mp3 file, cause otherwise you will have huge file sizes.
Creating each segmentHere is an example video, where I show you how I create each segment of the dynamic music. In this example I use the song "Sector Sweep" from Episode Two, but you can do with almost all combat music from Half-Life 2.
Technique 1: Action BubbleI use this technique for encounters where the player enters a combat space, but the fighting hasn't started yet. You play cautious music that is supposed to build tension, when the actual fight begins, you play the combat music, and when the fight ends you play the cooldown music. The combat music should be looped or be loopable in-engine.
1. Set up three logic_relays and name them accordingly. I name them [name of encounter]_caution, [name of encounter]_alert and [name of encounter]_cooldown.
2. Create an ambient_generic for each track and make sure the flags are as follows: "Start Silent" checked, "is NOT Looped" unchecked, "Play Everywhere" checked. You want "is NOT Looped unchecked, because otherwise you don't have control over the ambient_generic, it's just how Source works.
3. In the "caution" relay, you start the caution track. You trigger this relay when the player enters the combat space.
4. In the "alert" relay, you start the alert track and stop the caution track 0.1 seconds after that. You stop it 0.1 seconds after it, cause otherwise the player will notice a short gap between each track. You trigger this relay when the fighting begins (player starts shooting, enemies start entering the space)
5. In the "cooldown" relay, you start the cooldown track and stop the alert track 0.1 seconds after that. You trigger this relay when all enemies are dead or the fight is over in some other way (player escaped).
This is a very simple way to implement dynamic music and the one I recommend starting with. Here is an example:
Technique 2: Continuous BattleI use this technique when the player is in a battle where there is down-time, which means there are situations where the player can leave the combat space in some way and gets room to breathe, only to get back into the fight a little later. For this technique you will need a "relaxed" version of your song, a "tension" version and a "cooldown" version. The "relaxed" and "tension" versions should be looped or loopable in-engine.
1. Create an ambient_generic for each track and make sure the flags are as follows: "Start Silent" checked, "is NOT Looped" unchecked, "Play Everywhere" checked. You want "is NOT Looped unchecked, because otherwise you don't have control over the ambient_generic, it's just how Source works.
I name these like this: [name of encounter]_relax, [name of encounter]_tension, [name of encounter]_cooldown
In the map I implemented this I used trigger brushes to stop and play each track. The player triggers these when going to certain areas of the combat-space and when he comes out again. You could this any way you like though, depending on the encounter.
2. Set the Volume of the relaxed ambient_generic to 1. (Ideally we would set it to 0, but that pauses the sound, instead of playing it silently)
3. Player enters combat-space: Start the relaxed and the tension track simultanously. We do this so we guarantuee that both tracks are always aligned.
4. Player enters "safe" area or places enemies can't reach (see example video): Set Volume of the tension track to 1 and the relaxed track to 10.
5. Player exits "safe" area: Set Volume of the relaxed track to 1 and the tension track to 10.
6. Player defeats all enemies or fight is over in some other way: Start the cooldown track and stop the tension and the relaxed track 0.1 seconds after that. You stop it 0.1 seconds after it, cause otherwise the player will notice a short gap between each track.
Here is an example:
Example TracksHere are a few example packages of songs I made, you can use them freely (they technically still are Valve property). Listen to the original songs and understand at which sections I split the songs and looped them.
ExtrasThere are a few things you must know about ambient_generic, my favorite pain in the ass of Source.
- ambient_generic doesn't pause when you pause the game
- when you load a save file, the sound doesn't replay
- when you have a sound with "is NOT Looped" UNCHECKED, then the sound will restart when you load a save. This doesn't have to be a problem though. If you follow my technique you ensure this way that there is always music, even though you are not using soundscripts
- if you don't want that, you can use the Input "Volume" with "0" as the parameter to stop the sound. You can't stop sounds with "StopSound" if the flag "is NOT Looped" is checked.
- if "Start Silent" is unchecked you loose all control over the ambient_generic
- If you start "relaxed" and "tension" simultaneously, but you want "relaxed" to be there first instead of "tension" (like in the example), I recommed fading in "tension", cause otherwise the loudness of the combat version will be too obvious. This problem only exists because we can't set Volume to 0 to make sounds play silently.
- Don't forget to add *# before the filepath. So in the ambient_generic where you set the sound, just put these two characters before the path. Example:
by putting the * there, the engine knows that it should stream the file, instead of loading it completely before playing it. For bigger files that is neccessary, cause otherwise you will have a small lag.
By putting the # there, the engine knows that it's music, and the music volume slider in the options menu will affect the volume of the sounds.