FMOD Studio provides a Scripting API that allows us to control and edit the application by writing JavaScript code. This is extremely useful when automating tasks or to extend functionalities of the editor. It is possible to create scripts to bulk rename markers, parse spreadsheets to create events, create ScriptableObjects .cs files for Unity for example.
There a three ways to use the Scripting API:
- Directly executing commands in the console interface.
- Writing and executing .js scripts.
- Sending commands via TCP/IP.
Let’s have a brief look at each method.
Using the console to execute commands
We can input commands directly into the console. You can open the console by pressing CTRL+0 or clicking on the menu item Window->Console:
Creating and executing a script
To execute a script in FMOD Studio you need to create a Scripts folder in the root directory of your FMOD Project. Alternatively, you can use the scripts folder already present in the installation directory of FMOD Studio. There is also a system-wide Scripts folder placed under %localappdata%/FMOD Studio/Scripts
on Windows and ~/Library/Application Support/FMOD Studio/Scripts
on macOS. A minimal JavaScript script example might look like this:
studio.menu.addMenuItem({
name: "Scripts\\Hello World",
execute: function () {
console.log("Hello World");
}
});
Here we are adding a new menu item to the Scripts menu bar by calling studio.menu.addMenuItem
. After reloading your scripts by clicking on Scripts->Reload you’ll find the new menu entry in the scripts menu bar. By clicking on the script the code inside the execute function will be executed. In this example we are printing hello world to the console.
Sending commands via TCP/IP
When opening the console you can see the IP and port you can connect to:
You can test the connection by using a software like Packet Sender to send commands to FMOD Studio:
If you are working on an external tool, it should be easy to interface with FMOD Studio. Managing and editing a FMOD project inside your game engine should also be possible with a few scripts.
Command list
Here you can find a list of commands I personally find useful. For a more complete overview of the API, consult the Scripting API documentation page. You can get the properties of any object in FMOD Studio project by calling dump()
on that object.
Event commands
Getting all events
var events = studio.project.model.Event.findInstances();
findInstances() will return an array containing all event ManagedObjects
.
Getting the current selected event in the event browser
var event = studio.window.browserCurrent();
Getting an event
var event = studio.project.lookup("event:/testFolder/testEvent");
Creating an event
var event = studio.project.create("Event");
Setting the name of the event
event.name = "My Event Name";
Creating a folder
var folder = studio.project.create('EventFolder');
folder.name = "Hello World";
Assigning a folder to an event
event.folder = folder;
Adding a group track to the event
var track = event.addGroupTrack();
Adding instruments to a group track
track.addSound(parameter, soundType, start, length)
parameter is the parameter we are adding the instrument to. If you want to add an instrument to the timeline sheet, use the timeline
property of a ManagedObject:Event. start and length is the respective start time and length in seconds.
To add a Single Instrument to the track on the timeline we would write:
var singleInstrument = track.addSound(event.timeline, 'SingleSound', 0, 10);
The following instruments are available:
SingleSound
MultiSound
ProgrammerSound
SoundScatterer
Importing an audio asset into the FMOD project
var asset = studio.project.importAudioFile(path);
path is the file path. It will return an AudioFile ManagedObject. It will return null
if it can’t find the file.
Assigning an audio asset to a Single Instrument
singleSound.audioFile = asset;
Assigning Single Instruments to a Multi Instrument
First, create a new multi instrument:
var multiSound = track.addSound(event.timeline, 'MultiSound', 0, 10);
Then set the multi instrument to the owner of the single instrument :
singleSound.owner = multiSound;
The same principle applies to a scatterer instrument.
Adding effects to the master track of an event
var effect = event.masterTrack.mixerGroup.effectChain.addEffect('SpatialiserEffect');
The following effects are available:
ThreeEQEffect
GainEffect
ChannelMixEffect
ChorusEffect
CompressorEffect
ConvolutionReverbEffect
DistortionEffect
DelayEffect
FlangerEffect
LimiterEffect
MultibandEqEffect
PitchShifterEffect
SFXReverbEffect
TransceiverEffect
TremoloEffect
HighpassEffect
HighpassSimpleEffect
LowpassEffect
LowpassSimpleEffect
ParamEqEffect
SpatialiserEffect
ObjectSpatialiserEffect
LoudnessMeter
Getting the currently selected item in the editor window
var item = studio.window.editorSelection();
This can be a marker, an instrument and so on.
Setting the max instances value of an event
event.automatableProperties.maxVoices = 3; // number
Parameter commands
Getting all the parameters of an event
var parameters = event.getParameterPresets();
Adding a new parameter to an event
var param = event.addGameParameter({
name: "Test",
type: studio.project.parameterType.User,
min: -1,
max: 20
});
studio.project.parameterType corresponds to the parameter types available. These are:
User
Distance
Direction
Elevation
EventConeAngle
EventOrientation
UserEnumeration
Adding a labeled parameter to an event
First, create a parameter with the UserEnumeration parameterType:
var param = event.addGameParameter({
name: "Test",
type: studio.project.parameterType.UserEnumeration,
});
Create an array containing your parameter values and assign the array to the enumerationLabels of the parameter:
var paramArr = ["First Label", "Second Label", "Third Label"];
param.preset.enumerationLabels = paramArr;
Setting the initial value of a parameter
param.preset.initialValue = 1 // number
Mixer commands
Getting all mixer groups
var mixerGroups = studio.project.model.MixerGroup.findInstances();
findInstances() will return an array containing all mixer groups.
Creating a new mixer group
var mixerGroup = studio.project.create("MixerGroup");
mixerGroup.name = "New Group";
Setting the volume of a mixer group
mixerGroup.volume = -20; // number from -80 to 10
Deleting a mixer group
studio.project.deleteObject(mixerGroup);
Banks Commands
Creating a new bank
var bank = studio.project.create("Bank");
bank.name = "New Bank";
Assigning events to banks
event.relationships.banks.add(bank);
Project Commands
Getting the path to the project’s .fspro file
var projectPath = studio.project.filePath;
Saving a project
studio.project.save();
Building the project
studio.project.build();
File Commands
Reading a file
var file = studio.system.getFile(filePath);
file.open(studio.system.openMode.ReadOnly); // returns true if succeeded
var fileSize = file.size();
var text = file.readText(fileSize);
Writing to a file
var file = studio.system.getFile(filePath);
file.open(studio.system.openMode.WriteOnly); // returns true if succeeded
file.writeText("Hello World"); // Returns the num. of bytes that were written or -1 if an error occurred.
file.close();