Creating Your Own Sound Scripts!

Posted by on Mar 19, 2012

If you don’t know what a sound script is, well you’re in for something rather special! Although you can play sound files directly by targeting the raw file, a sound script will allow you to control the sound in different ways. You can use a sound script in custom: maps, mods, and games. While you might not want to make a sound script if you’re just adding music to a single custom level, you will want to make them if you’re using custom sound effects, or many different sounds.

Some of the perks of using sound scripts are:

  • Choosing a shorter, more organized name for the sound.
  • Ability to modify the sound without creating more sound files that would otherwise waste space.
  • Pitch and volume alteration.
  • Choosing a random sound file from an array.
  • Subtitles (We won’t cover this, and custom subtitles are only for mods).
  • Channels that handle the sound differently based on the use.
  • DSP modification, and sound characters.
Some of the problems of using a sound script are:
  • None, there is no reason NOT to use them.

The Manifest, and Script File

So now that you have a basic understanding of what a sound script actually does, how about we learn more about the creation process.  sound scripts are stored in:
GameGamefolderscriptsgame_sounds_SCRIPT.txt
Once you have a sound script you’ll have to add it to the manifest. The manifest tells that game what sound scripts to load into memory. The manifest looks like this:
game_sounds_manifest
{
	 "preload_file"  	"scripts/game_sounds_physics.txt"
	 "preload_file"  	"scripts/game_sounds_weapons.txt"
	 "preload_file"		"scripts/game_sounds_ambient_generic.txt"
	 "preload_file"		"scripts/game_sounds_world.txt"
	 "preload_file"		"scripts/level_sounds_general.txt"
}

As you can see it’s a rather simple file, all you do is copy an existing line and change the file that it points too. Now lets look at what a sound script entry looks like, I’ll be sure to break it down into it’s simplest form.

"Sound.Name_Entry"
{
	"Command"		"Setting"
}

This is what a completed sound script entry looks like:

"Tube.explode_1" //Name of the sound entry
{
"channel" "CHAN_STATIC" //Channel that the sound functions on. If it is not defined it will use the default channel.
"volume" "1" //Volume of the sound to be player, this is a value 0-1 and can be a decimal. If it is not defined it will be "1"
"pitch" "100" //Pitch of the sound, can be 0-255, 100 if default. If it is not defined it will use the default.
"soundlevel" "SNDLVL_90db" //Sound level, this is used for sound attenuation. It is basically how fast, and how far it falls off.
"wave" "level/explode_1.wav" //Sound to be played, must be a WAV.
}

Pretty simple so far right? Good! Now lets make one from scratch! I’ll name my file game_sounds_tutorial.txt. Once you’ve made the script make sure to place it in the proper location: GameGamefolderscripts Then append the newly created script file into the manifest.

Now time to create a sound entry in our new file. There are a few things that you need to keep in mind when you name your sound. First the restrictions, there can only be one “.” in the sound name. So if the sound it not working make sure you’ve only used one. When you name the entry try to keep is simple, I follow this setup: “Type.Description_Number“. So for this I’ll be naming my sound: “Explosion.LargeMetal_01“.

Now we need to add some controllers and settings. Now let me warn you here, and make sure you know this: If you DON’T  enclose every command and parameter in quotes. ” <– Those things! Make sure to use them!

Playing the Sound File

First you’ll want to choose what sound file you are going to play in this entry, there are two ways that you can play sounds in a sound script.

  1. Wave – A single wave that will be played when called.
  2. Rndwave – An array of sounds that are randomly chosen from when called.

The WAVE command

The wave command is pretty straight forward, just add the command “wave” followed by the path to the sound. Make sure that your WAV files are placed inside of a folder inside of the “Sounds” folder, if they are not, they will not play. This is what is looks like:

"Explosion.LargeMetal_01"
{
	"wave"		"tutorial/soundscripts/explosion.wav"
}

Rndwave command

The rndwave command acts like the normal wave command but it requires you to make a list of sounds to be played. When the sound is called, it picks one of these sounds at random. It is good for things like: water drips, foot steps, explosions, and anything that have many things that sound the same but are a little different. This is what it looks like:

"Explosion.LargeMetal_01"
{
	"rndwave"
		{
			"wave"	"tutorial/soundscripts/explosion_01.wav"
			"wave"	"tutorial/soundscripts/explosion_02.wav"
			"wave"	"tutorial/soundscripts/explosion_03.wav"
			"wave"	"tutorial/soundscripts/explosion_04.wav"
		{
}

Volume

The volume is the volume level that the sound will be played at. This is a number value of 0-1 and can be a decimal. You can also use a value of “VOL_NORM” to use the mod/game’s default volume, which is probably “1”. Comma notation is also supported by the volume command. An example of the volume command looks like this:

"Explosion.LargeMetal_01"
{
	"volume"	"0.8"
	"wave"		"tutorial/soundscripts/explosion.wav"
}

Comma Notation

Now you might be wondering what “Comma notation” is. Basically some commands support the ability to have some randomness added to them. This is done with comma notation. Now keep in mind that not all commands support comma notation, and I’ll list all of the ones that I know support it. To use comma notation you simple just do “ValueA,ValueB” but is must follow: ValueA

"Explosion.LargeMetal_01"
{
	"volume"	"0.4,0.8"
	"wave"		"tutorial/soundscripts/explosion.wav"
}

So with that when the sound is called it will randomly choose a value between 0.4 and 0.8. This allows you to reuse sounds without it looking super obvious.

Pitch

You’re able to change the pitch from the script, instead of making multiple sound files. It must be a value between 0-255 and cannot be a decimal, you can also use “PITCH_NORM” to use the mod/game’s default volume, which is probably “100”. Comma notation is also supported by the Pitch command. An example of the pitch command looks like this:

"Explosion.LargeMetal_01"
{
	"pitch"		"130"
	"volume"	"0.8"
	"wave"		"tutorial/soundscripts/explosion.wav"
}

Channel

Channels are used to categorise sounds in a way that NPCs, and game logic in general, can understand. In most of my experiences you don’t need to do anything fancy here, just define the default one and you’ll be fine. If there is a channel for something that you’re making a sound for then use it. For instance use CHAN_VOICE if the sound is used for a voice, and use CHAN_WEAPON if the sound is for a weapon. An example of the channel command looks like this:

"Explosion.LargeMetal_01"
{
	"pitch"		"130"
	"volume"	"0.8"
	"channel"	"CHAN_STATIC"
	"wave"		"tutorial/soundscripts/explosion.wav"
}

Here is a list of all channels that are available for use. (I’ve copied this list from the VDC.)

  • CHAN_AUTO
    • Default, generic channel.
  • CHAN_WEAPON
    • Player and NPC weaponsfire.
  • CHAN_VOICE
    • Voice over dialogue.
  • CHAN_ITEM
    • Generic physics impact sounds, health/suit chargers, ‘use’ sounds.
  • CHAN_BODY
    • Clothing, ragdoll impacts, footsteps, knocking/pounding/punching etc.
  • CHAN_STREAM
    • Sounds that can be delayed by an async load, i.e. aren’t responses to particular events. Confirm: This won’t make the sound actually stream; use the * prefix for that.
  • CHAN_REPLACE
    • Used when playing sounds through console commands.
  • CHAN_STATIC
    • A constant/background sound that doesn’t require any reaction.
  • CHAN_VOICE_BASE
    • Network voice data (online voice communications)
  • CHAN_USER_BASE+<number> (You typically won’t use these, at least I’ve never found a use for them.)
    • Custom channels can be defined here.

Still with me? I knew you could do it!

SoundLevel

The sound’s attenuation; how fast it drops away. You’ll use this if the sound is used for an environmental sound like: explosions, engines, and fires. You’ll want to use “SNDLVL_NONE” if the sound is global sound. Note that the engine starts to run into some problems when you use a sound level under 60db. An example of the soundlevel command looks like this:

"Explosion.LargeMetal_01"
{
	"pitch"			"130"
	"volume"		"0.8"
	"channel"		"CHAN_STATIC"
	"soundlevel"	"SNDLVL_85dB"
	"wave"			"tutorial/soundscripts/explosion.wav"
}

This is a table of all settings for the soundlevel command. (I’ve copied this list from the VDC.)

[table id=22 /]

Sound Characters

Sound characters modify how the sound file is handled. Be it how it gets loaded or encoded, it gets modified. How it works is you add a special character to the beginning of a wave command. When the engine calls that sound it scans the first two characters for one of these, if it finds it, it gets applied to the sound. so you’re allowed to have up to two on any sound that is being played. An example of how Sound Characters look:

"Explosion.LargeMetal_01"
{
	"pitch"			"130"
	"volume"		"0.8"
	"channel"		"CHAN_STATIC"
	"soundlevel"	"SNDLVL_85dB"
	"wave"			"*tutorial/soundscripts/explosion.wav"
}

And one with two on it:

"Explosion.LargeMetal_01"
{
	"pitch"			"130"
	"volume"		"0.8"
	"channel"		"CHAN_STATIC"
	"soundlevel"	"SNDLVL_85dB"
	"wave"			"@#tutorial/soundscripts/explosion.wav"
}

Here are all of the Sound Characters and what they do. (Once again, I’ve copied this from the VCD)

  • * – CHAR_STREAM
    • Streams from the disc, get flushed soon after. Use for one-off dialogue files or music.
  • # – CHAR_DRYMIX
    • Bypasses DSP and affected by the user’s music volume setting.
  • @ – CHAR_OMNI
    • Non-directional; audible everywhere. “Default mono or stereo”, whatever that means.
  • > – CHAR_DOPPLER
    • Doppler encoded stereo: left for heading towards the listenr and right for heading away.
  • < – CHAR_DIRECTIONAL
    • Stereo with direction: left channel for front facing, right channel for rear facing. Mixed based on listener’s direction.
  • ^ – CHAR_DISTVARIANT
    • Distance-variant stereo. Left channel is close, right channel is far. Transition distance is hard-coded; see below.
  • ) – CHAR_SPATIALSTEREO
    • Spatializes both channels, allowing them to be placed at specific locations within the world; see below.
      • Note: Sometimes “(” must be used instead; see below.
  • } – CHAR_FAST_PITCH
    • Forces low quality, non-interpolated pitch shift.
  • $ – CHAR_CRITICAL
    • Memory resident; cache locked.
  • ! – CHAR_SENTENCE
    • An NPC sentence.
  • ? – CHAR_USERVOX
    • Voice chat data. You shouldn’t ever need to use this.

Spatial Stereo

Adding “)” in front of a stereo sound name in the soundscript such as “)weapons/m4a1/m4_shoot.wav” tells the sound engine that it is a spatialized sound; this allows the sound to emit from a specific location within the world. When not used, stereo sounds play in a fixed 2-channel orientation and cannot be panned to simulate a location. Single-channel files do not require “)” before the filename and will be spatialized automatically.

Distance Variance in Source

Adding ^ in front of a sound name, such as “^weapons/explode3.wav” tells the sound engine that it is a distance based sound. The left channel of the .wav is the ‘near’ sound that will play when the sound originates close to you, and the right channel is the ‘far’ sound that will play when the sound originates far from you. If the ^ mark is not used in the soundscript the sound is treated as stereo with no directionality or distance. This is a different feature than the sndlvl entry to control attenuation. This distant variant feature allows you to play two different sounds (but using only one file) and cross-fading between the two depending on how far away the sound originates.
Currently the fade distances are hardcoded to begin at 20 feet (240 world units) and end at 110 feet (1320 world units) and cannot be changed in a mod.

There is also a new thing called “Operator Stacks” But those are currently only support by Portal 2, Dota 2, Counter-Strike Global Offensive, and newer. You most likely won’t need to use them, but if you want to learn more on them here is the VDC article on them. Operator Stacks On Valve Developer Community

I hope that you enjoyed this quick little tutorial on Sound Scripts. If you have any questions be sure to ask!

~Happy Mapping!