Torque 3D 1.1 Alpha SFX Workflows
by Rene Damm · in Torque 3D Professional · 12/01/2009 (12:26 am) · 75 replies
In this thread, I will progressively add some quick instructions on how to use several of the new SFX features in 1.1 Alpha.
For suggestions/requests/criticism/thoughts/whatever, feel free to comment.
For suggestions/requests/criticism/thoughts/whatever, feel free to comment.
About the author
#2
There's a range of predefined SFXStates that help you do that (though you probably would want to modify the set of moods for your game). Other than that, you only need to set up your playlists accordingly:
When a mood is activated, it will automatically deactivate all other moods and all playlists that are currently playing and that have slots directly or indirectly coupled to moods will move on to play slots with compatible moods.
Currently, setting up SFXStates still requires some (light) scripting. There will probably be an editor for this later on.
12/01/2009 (12:31 am)
How do I make my background music react to the mood of the gameplay situation?
There's a range of predefined SFXStates that help you do that (though you probably would want to modify the set of moods for your game). Other than that, you only need to set up your playlists accordingly:
- Define an SFXState for each mood that you want your game to have. core/scripts/client/audioStates.cs already contains a number of moods: AudioMoodAggressive, AudioMoodTense, AudioMoodVictory, AudioMoodCalm. To create a new mood "Berserk", for example, add the following:
- Create an SFXProfile for each of your background music tracks. Assign them appropriate non-3D SFXDescriptions. Usually, streaming ("isStreaming") makes sense for background audio as does looping ("isLooping"). Also, using a little fade-in and fade-out on the tracks usually gives nicer transitions. AudioMusicLoop2D is a good description to start with since it has both streaming and looping enabled and plays in the music audio group.
- Create a playlist with your background music. Give the playlist a description that has looping enabled.
- Assign each music track to a separate slot. For each slot, do the following
- Set "replay" to "KeepPlaying" to make the list pick up a source that may already be playing on a given slot.
- Set "transitionOut" to "Wait" to make the list wait for each track to finish playing.
- Set "state" to the respective AudioMood for each music track.
- Set "stateMode" to "PauseWhenDeactivated" to make the list pause playback of a track when its mood is deactivated.
- Create an SFXAmbience and set its "soundTrack" property to the playlist just created.
- Set the "soundAmbience" property of the LevelInfo object to the SFXAmbience just created. This will cause the playlist to automatically start playing when the level is loaded.
- In your client-side game scripts, activate the moods depending on your game state. This can, for example, be triggered from the server with a clientCmd:
singleton SFXState( AudioMoodBerserk )
{
parentGroup = AudioMood; // This groups all the mood states.
className = "AudioStateExclusive"; // This makes each mood deactivate other moods when it is activated.
};function clientCmdGoBerserk()
{
AudioMoodBerserk.activate();
}When a mood is activated, it will automatically deactivate all other moods and all playlists that are currently playing and that have slots directly or indirectly coupled to moods will move on to play slots with compatible moods.
Currently, setting up SFXStates still requires some (light) scripting. There will probably be an editor for this later on.
#3
What you need to do is set up a playlist that plays only a single sound randomly chosen from the list of available sounds. So, here we go:
Be aware that this creates two SFXSources (one for the playlist and one for the actual sound) per shot and is thus not ideal for rapid-fire weapons. To create audio for weapons like chainguns, FMOD Designer is a very suitable tool.
12/01/2009 (12:46 am)
How do I select a random gunshot sound to play out of a list of sounds?
What you need to do is set up a playlist that plays only a single sound randomly chosen from the list of available sounds. So, here we go:
- Create a separate SFXProfile for each of the sounds in the Datablock Editor. For something like gunshot sounds, "preload" should generally be set to true and the associated SFXDescription should generally be for a non-streaming 3D sound with a slow falloff since gunshots are heard from rather far away (though for optimization it can be advantageous to use quicker falloffs). Be aware that 3D sounds need to be mono.
- Create a SFXPlayList in the Datablock Editor and assign each of the SFXProfiles to a separate slot in the list.
- Set the "numSlotsToPlay" property on the playlist to 1 to make the playlist stop after playing a single sound.
- Set the "random" property to either "StrictRandom" or "OrderedRandom" (both are suitable in this situation) to make the playlist randomly choose a single sound from all the slots that have a track assigned.
- Assign an SFXDescription to the playlist. Since in this case you wouldn't want the playlist itself to have much of an influence on the playback of the sounds in the list, use a generic description like AudioSim (AudioEffects). Be aware that if you use a 3D sound description for the playlist, additional distance attenuation will be stacked on top of the distance attenuation that the 3D sounds in the list already have.
- Open the ShapeBaseImageData datablock for the weapon in the editor and set the "stateSound" for the "fire" state to the playlist just created.
Be aware that this creates two SFXSources (one for the playlist and one for the actual sound) per shot and is thus not ideal for rapid-fire weapons. To create audio for weapons like chainguns, FMOD Designer is a very suitable tool.
#4
12/01/2009 (2:51 am)
Stickied this post until official docs are added. Great content Rene! =)
#5
Holy sheepsh@t that's awesome!
12/01/2009 (7:15 am)
Quote:
How do I make my background music react to the mood of the gameplay situation?
Holy sheepsh@t that's awesome!
#6
12/03/2009 (1:20 pm)
Great Rene ! :-)
#8
Example: you have a track with wind noises and other sounds of nature and want to randomly play some bird sounds on top of it.
This requires understanding a key difference between playlists in Torque and playlists in music players. A music player will play each track in the list in entirety and then move on to the next list item. Torque's sound system, however, undergoes a more complex procedure for each list item. Each slot in the list will go through 5 discrete stages in succession:
12/04/2009 (11:27 am)
How do I mix some one-shot sounds on top of my ambient audio track? - Part I
Example: you have a track with wind noises and other sounds of nature and want to randomly play some bird sounds on top of it.
This requires understanding a key difference between playlists in Torque and playlists in music players. A music player will play each track in the list in entirety and then move on to the next list item. Torque's sound system, however, undergoes a more complex procedure for each list item. Each slot in the list will go through 5 discrete stages in succession:
- delayIn: Waits a set amount of time before processing the slot. This is 0 by default and is determined by the "delayTimeIn" (seconds to wait) and "delayTimeInVariance" (bounds on randomization) properties.
- transitionIn: Decides what to do before playing the slot. Defaults to "None" which makes this stage a no-operation. Alternatively, the slot can be configured to wait for playback of other slots to finish ("Wait" and "WaitAll") or to stop playback of other slots ("Stop" and "StopAll"). Note that "Wait" and "Stop" always refer to the source that was last started by the list.
- play: Finally, the track attached to the slot is played. However, this will only start playback of the track and then immediately move on to the next stage. It will not wait for the track to finish playing. Note also that depending on the "replay" setting for the slot, this stage may pick up a source that is already playing on the slot rather than starting a new one.
- delayOut: Waits a set amount of time before transitioning out of the slot. This works the same as delayIn and is set to 0 by default (i.e. no delay).
- transitionOut: Decides what to do after playing the slot. This works like transitionIn.
Several slot properties (fade times, min/max distance, and volume/pitch scale) are used in this stage.
#9
So, after this detour, let's see how this works in practice:
In this example, I have assumed that it is fine to have more than one of the one-shot sounds playing at a given time. If this is not what you want, the easiest solution is to set all one-shot sound slots to "Wait" on "transitionOut".
//Edit: corrected use of "IgnorePlaying" that must be "KeepPlaying"
//Edit: Removed bogus tip about moving sounds to separate playlist
12/04/2009 (11:28 am)
How do I mix some one-shot sounds on top of my ambient audio track? - Part II
So, after this detour, let's see how this works in practice:
- In the Datablock Editor, create an SFXProfile for the ambient audio track as well as for each of the one-shot sounds. Of course, each of the sounds can just as well be a playlist or FMOD event.
- Also create a new SFXPlayList and assign a looping SFXDescription to it.
- Set "random" to either "StrictRandom" or "OrderedRandom". The difference between the two is that "StrictRandom" just randomly picks a slot to play even if this slot has already played within the current loop. "OrderedRandom", on the other hand, randomizes only the order in which slots are played and will thus never play the same slot twice in a single loop. In our case here, this doesn't matter too much.
- Set the first slot in the list to the ambient audio track that should continuously run (make sure to create this as a looped track). Set "replay" on this slot to "KeepPlaying". This is important.
- Assign each of the one-shot sounds to a separate slot in the list. If you have more of these sounds than fit into the remaining slots, use one or more secondary playlists and attach them to the primary playlist.
- Assign the playlist to an SFXEmitter or to an SFXAmbience.
As the playlist will loop over the slots in the list, it will come across the slot with the ambient audio track again and again. However, we do not want the list to start another sound or affect the current playback of the ambient track in any way so by setting "replay" to "KeepPlaying", the "play" stage of the list will effectively become a NOP.
For each of these sounds, set "transitionIn" and "transitionOut" to "None". Also, set "replay" on each slot to "StartNew" if it is okay for multiple instances of a the same one-shot sound to play simultaneously.
The key to getting the sounds to trigger at random times now is the "delayTimeIn" and "delayTimeInVariance" properties on each slot. These allow to make the list wait a random amount of time before actually starting to play a given sound.
Set "delayTimeIn" on each of the one-shot sounds to a reasonable base value. This could be the same or a different value for each sound. Let's say we set all of them to 60 seconds.
The "xyzVariance" fields all work the same way. They take the value of their "xyz" base field ("delayTimeIn" in this case) and specify the bounds on the randomization applied to the field. The default of "0 0" means that no randomization takes places. If, however, we were to set "delayTimeInVariance" to "-30 20" with "delayTimeIn" being set to "60", the effective delay time will be a random number of seconds between 30 and 80.

In this example, I have assumed that it is fine to have more than one of the one-shot sounds playing at a given time. If this is not what you want, the easiest solution is to set all one-shot sound slots to "Wait" on "transitionOut".
//Edit: corrected use of "IgnorePlaying" that must be "KeepPlaying"
//Edit: Removed bogus tip about moving sounds to separate playlist
#10
Two things are needed for this: an SFXState that indicates the "under water" condition and a playlist on the weapon's firing (or other) state.
A number of predefined audio location states are already defined in core/scripts/client/audioStates.cs: AudioLocationInside, AudioLocationOutside, and AudioLocationUnderwater. We'll use AudioLocationUnderwater in this example. If you need more location states in your game, you can simply extend this set, like, for example, to differentiate audio for dungeons:
The easiest way to use AudioLocation states is to bind them to SFXAmbiences and let the listener tracking system automatically activate and deactivate them according to where the listener currently is.
There is one thing we need to look out for, though: since playlists will assume that a slot without a state assigned to it is completely agnostic to SFXStates and will play regardless of what states are active, we need a way to identify the "not in water" state. This can be done two ways:
A little explanation on state activation and disabling: Each state maintains one counter for activation and one counter for disabling. If a state is disabled, it will not activate even if its activation count is non-zero. If it is active when being disabled, it will go into inactive state. This way, disabling a state always takes precedence over activating a state.
In this example, we'll use the first approach.
So, finally, let's get to work:
As already mentioned before, this creates two SFXSources (playlist+sound) per shot and is thus not ideal for rapid-fire weapons.
12/05/2009 (9:43 pm)
How do I make my weapon have a different gunshot sound under water?
Two things are needed for this: an SFXState that indicates the "under water" condition and a playlist on the weapon's firing (or other) state.
A number of predefined audio location states are already defined in core/scripts/client/audioStates.cs: AudioLocationInside, AudioLocationOutside, and AudioLocationUnderwater. We'll use AudioLocationUnderwater in this example. If you need more location states in your game, you can simply extend this set, like, for example, to differentiate audio for dungeons:
singleton SFXState( AudioLocationDungeon )
{
parentGroup = AudioLocation; // This groups all the location states.
className = "AudioStateExclusive"; // This makes each location deactivate other locations when activated.
};The easiest way to use AudioLocation states is to bind them to SFXAmbiences and let the listener tracking system automatically activate and deactivate them according to where the listener currently is.
There is one thing we need to look out for, though: since playlists will assume that a slot without a state assigned to it is completely agnostic to SFXStates and will play regardless of what states are active, we need a way to identify the "not in water" state. This can be done two ways:
- We can make sure that one AudioLocation state is always active, e.g. by assigning AudioLocationOutside to the global SFXAmbience on the LevelInfo object. This way, AudioLocationOutside sort of becomes the default audio location which is then overridden by local settings as the listeners roams around the level.
- We can create a separate AudioLocationNotUnderwater state which we immediately activate and then add to the "excludedStates" list of AudioLocationUnderwater. This way, whenever AudioLocationUnderwater is activated, it will disable AudioLocationNotUnderwater.
A little explanation on state activation and disabling: Each state maintains one counter for activation and one counter for disabling. If a state is disabled, it will not activate even if its activation count is non-zero. If it is active when being disabled, it will go into inactive state. This way, disabling a state always takes precedence over activating a state.
In this example, we'll use the first approach.
So, finally, let's get to work:
- Create one SFXProfile for the normal gunshot sound and one for the underwater gunshot sound.
- Create a new playlist and give it a neutral SFXDescription that plays in the effects sound group ("AudioSim"/"AudioEffects" is a good candidate.)
- Set the "track" property on the first slot to the SFXProfile of the normal gunshot sound and the "track" property of the second slot to the SFXProfile for the underwater gunshot sound (well, the order doesn't matter in fact.)
- Set the "state" property of the first slot to "AudioLocationOutside".
- Set the "state" property of the second slot to "AudioLocationUnderwater".
- Also set the "stateMode" property on both slots to "IgnoreWhenDeactivated" as otherwise a gunshot sound will get cut short when the player exits the location it was fired in.
- Switch to the ShapeBaseImageData instance for your weapon and set the "stateSound" property for the "fire" state to the playlist just created.
- Create a new SFXAmbience, set one of its "states" to "AudioLocationOutside" and assign it to the "soundAmbience" property of the LevelInfo object in your levels.
- Create a new SFXAmbience, set one of its "states" to "AudioLocationUnderwater" and assign this ambience to the "soundAmbience" property of all WaterObjects (WaterBlocks, WaterPlanes, Rivers) in your levels.
As already mentioned before, this creates two SFXSources (playlist+sound) per shot and is thus not ideal for rapid-fire weapons.
#11
I think it should be noted that the DLLs in the FMOD Download here on GG (or TP now..) are a bit old (v4.22). I got the updated package off the FMOD website (v4.28). I had to run a Debug Mode from VS 2008 to catch that. Just an FYI.
01/12/2010 (11:55 pm)
Awesome!I think it should be noted that the DLLs in the FMOD Download here on GG (or TP now..) are a bit old (v4.22). I got the updated package off the FMOD website (v4.28). I had to run a Debug Mode from VS 2008 to catch that. Just an FYI.
#12
Yep, they don't work with T3D anymore (they are really age old) and indeed, there should be a note about this somewhere. One will get an error message about this in the console.log, though (both in debug and release builds).
Basically, one should always download the latest FMOD SDK from fmod.org and work with that.
01/13/2010 (3:18 am)
Yep, they don't work with T3D anymore (they are really age old) and indeed, there should be a note about this somewhere. One will get an error message about this in the console.log, though (both in debug and release builds).
Basically, one should always download the latest FMOD SDK from fmod.org and work with that.
#13

Has anyone else run into this error or knows why this is happening? I've tried changing the name and moving the files into the same structure as the tutorial with no luck
02/19/2010 (5:03 pm)
So I followed the tutorial at the top and everything seems to be implemented fine except I'm getting an object name error when I try to add the designer.
Has anyone else run into this error or knows why this is happening? I've tried changing the name and moving the files into the same structure as the tutorial with no luck
#14
I vaguely remember there was a bug in the alpha with the object name validation. Is this happening with the beta?
Otherwise, the FMODProject instance can also be added through the Datablock Editor or manually in script. The dialog there is just a convenience (turned inconvenience in this case).
Anyways, I'll check and make sure this is working.
02/19/2010 (5:09 pm)
I vaguely remember there was a bug in the alpha with the object name validation. Is this happening with the beta?
Otherwise, the FMODProject instance can also be added through the Datablock Editor or manually in script. The dialog there is just a convenience (turned inconvenience in this case).
Anyways, I'll check and make sure this is working.
#15
his post is here http://www.torquepowered.com/community/forums/viewthread/106987
02/19/2010 (5:14 pm)
My buddy merged the FMOD stuff from the T3D alpha 1.1his post is here http://www.torquepowered.com/community/forums/viewthread/106987
#16
There's a (dumb) bug in isValidObjectName where is says '0' instead of 'i' in one place. Replace the function with:
However, you error is caused by something else as 'FMODExample' should be accepted even with the bug.
Replace AddFMODProjectDlg.ed.cs in your project with the one from beta.
02/19/2010 (5:22 pm)
There's a (dumb) bug in isValidObjectName where is says '0' instead of 'i' in one place. Replace the function with:
bool isValidObjectName( const char* name )
{
if( !name || !name[ 0 ] )
return true; // Anonymous object.
if( !dIsalpha( name[ 0 ] ) && name[ 0 ] != '_' )
return false;
for( U32 i = 1; name[ i ]; ++ i )
if( !dIsalnum( name[ i ] ) && name[ i ] != '_' )
return false;
return true;
}However, you error is caused by something else as 'FMODExample' should be accepted even with the bug.
Replace AddFMODProjectDlg.ed.cs in your project with the one from beta.
#17
The dll is in place and our previous AddFMODProjectDlg.ed.cs file didn't have the check for that error
02/19/2010 (6:35 pm)
so I replaced the AddFMODProjectDlg.ed.cs from beta and I'm getting a missing fmod_event.dll errorThe dll is in place and our previous AddFMODProjectDlg.ed.cs file didn't have the check for that error
#18
You need to switch the sound system to FMOD like the dialog says. Put the DLLs in the game folder, restart, select FMOD as the sound provider in the options dialog.
02/19/2010 (6:41 pm)
You need to switch the sound system to FMOD like the dialog says. Put the DLLs in the game folder, restart, select FMOD as the sound provider in the options dialog.
#19

I have the DLLs in the game folder
02/19/2010 (6:50 pm)
I already did that, the error its giving me isn't the error that I didn't select FMOD as the sound provider. Its this one...
I have the DLLs in the game folder
#20
The FMOD Event DLL failed to load. I recommend merging all SFX changes from 1.1 Beta. There have been some vital fixes.
02/19/2010 (6:57 pm)
The FMOD Event DLL failed to load. I recommend merging all SFX changes from 1.1 Beta. There have been some vital fixes.
Associate Rene Damm
How do I add my FMOD Designer project to Torque?
For this, you need to build the project in Designer first and then add the compiled project to Torque:
Make sure you have the FMOD DLLs in your game folder alongside the game executable and FMOD selected as your SFX provider in the game options dialog. If this is not the case, error messages will tell you so.
Note that if you modify the project in Designer, you can simply rebuild the project and overwrite the compiled files. Torque will then re-import the project automatically on the next start. Except for removed or renamed events, all links to events remain valid.
Note also that the SFXFMODProject datablock is added to scripts/client/audioData.cs. Unfortunately, in the alpha release, only the Full template executes that file on startup if it exists. To modify your game to load this file on startup, add the following to the initClient() function in scripts/client/init.cs:
if( isFile( "./audioData.cs" ) ) exec( "./audioData.cs" );audioData.cs also contains custom SFXParameters created in the editor.