A sound bank is a named sound. Content never references an audio file directly — it
references a bank id, and the bank decides what actually plays.
Banks live in World/sound-banks.xml and are edited in Hydra's
Sound Bank editor. They are id‑keyed and merged across active modules
like every other resource, so a module can add banks or replace existing ones. See
Modules.
The simplest bank
<sound-bank id="ShieldsUp" category="system" instances="2">
<description>Shields raised</description>
<alias>sounds/shields-up.mp3</alias>
<layer source="sounds/shields-up.mp3" volume="1" />
</sound-bank>
That is what a component means when it says
activated="ShieldsUp".
Referencing a bank
Banks are referenced by id from component sound slots, model audio cues, effect banks and
mission actions, and an FTL drive's Spool-Sound names one too.
category groups them in the editor; it does not route the mix.
instances caps how many copies can sound at once: left out, it is 2, and 0
means no cap. When the cap is reached, the oldest copy fades out to make room. A bank's
own volume scales every layer in it.
instances is a real design decision, not a technical limit.
An ambient hum wants 1 — a second copy is just louder. An explosion wants around 10,
because in a real fight several land together and a cap of 1 makes a battle sound thin. Laser
fire sits in between. Getting these wrong is the most common reason a mix sounds wrong when
every individual sound is fine.
Aliases, and why they exist
A bank can declare aliases, and an alias can be a bare file path:
<sound-bank id="LaserFire" category="weapon" instances="6">
<alias>sounds/laser-fire.mp3</alias>
<alias>laser-fire</alias>
<layer source="sounds/laser-fire.mp3" volume="1" variance="300" />
</sound-bank>
This is the compatibility mechanism. Older content that named a raw file path still
resolves — it lands on the bank instead, and inherits everything the bank has since gained.
So you can improve a sound for all existing content by improving its bank, without touching
any of the content that plays it.
When you replace a base game bank in your own module, carry its aliases across or the
older references stop resolving.
Layers
A bank can stack several samples, each with its own settings. This is how you build a
sound that is more than one recording — a weapon with a transient and a body, an engine
with a rumble and a whine.
| Attribute | Effect |
source | The audio file. |
volume | Layer gain. |
detune | Fixed pitch offset in cents against the recording. |
variance | Random pitch spread in cents, applied per play. |
loop | Whether it repeats, when the trigger is a sustained one: a component's ambient slot, a map's ambient bed, a looping model cue or effect. A one‑shot trigger plays a looping layer once through. |
loop-start, loop-end | Loop points in seconds. Both 0 means the whole file. |
filter | Low‑pass cutoff in Hz. 0 means open. |
attack, release | Gain ramp in and out, in seconds. attack applies to a looping voice; release applies when a voice is stopped, not when a one‑shot ends on its own. |
instances, detune and variance must be whole
numbers, and loop must be exactly true or false. A
value the loader cannot read drops the bank or the layer it sits on, and that shows only in
the server log.
variance is the cheapest quality win available. A repeated
sample played identically reads as a machine gun of one recording; a few hundred cents of
random pitch spread makes ten explosions sound like ten explosions. The base game's laser
and explosion banks use 300. Weapon fire adds a small random spread of its own on top.
Every voice opens from silence over a few milliseconds, and a stopped one fades rather
than cutting, so a bank no longer needs attack and release just
to avoid clicks. Use them to shape a loop: a slow swell, a long tail.
Variants: one bank, several recordings
A bank can instead name other banks as variants, and playback picks one at random:
<sound-bank id="HullImpact" category="weapon">
<variant id="HullImpactA" />
<variant id="HullImpactB" />
<variant id="HullImpactC" />
</sound-bank>
Content references HullImpact and gets one of the three. This is the better
answer than pitch variance when you have genuinely different recordings, and the two combine.
The member is picked first and then played as itself, so its own instances
is the cap that applies; set it on each member, not on the container. Variants are one
level deep: a member that is itself a container does not play. A bank with both variants
and layers plays its variants.
Modulation: sound driven by game state
The most powerful feature, and the least used. A bank can bind a playback property to a
live game parameter:
<sound-bank id="Engine" category="engine" instances="1">
<layer source="sounds/engine.mp3" volume="1" loop="true" />
<modulate parameter="throttle" target="pitch" min="-200" max="400" />
<modulate parameter="throttle" target="volume" min="0.75" max="1" from="0" to="0.4" />
</sound-bank>
| Attribute | Meaning |
parameter | The game value driving it. Names are case‑sensitive; see below. |
target | volume, pitch or filter. |
min, max | Output range. Gain scale for volume, cents for pitch, Hz for filter. |
from, to | The input span that maps onto min..max, clamped outside it. Defaults to 0..1, which is the whole range only for a parameter that already runs 0..1. |
curve | linear or squared. |
layer | Which layer to drive, one‑based. Omitted means the whole bank. |
from and to are what let you express a knee without an expression
language. "Full gain by 40% throttle" is from="0" to="0.4".
Bindings that share a target combine, and not all the same way:
- pitch sums — cents are additive, so two offsets stack into one interval.
- volume multiplies — gains compose, each scaling what the others left.
- filter takes the minimum — the darkest constraint wins, because cutoffs
do not add.
The trap follows from the volume rule. A volume binding that reaches 0
multiplies the layer to silence regardless of every other binding. A contributor meant only to
lean on the gain wants a non‑zero minimum — min="0.75", not
min="0".
Which parameters exist. Every sound can read speed (0..1
of top speed), throttle (0..1) and altitude (raw). A component's
ambient loop on the player's own ship can also read the component's own values:
Level, Load, Integrity, ChargeFactor,
Enabled (0 or 1), Heat and Output (both raw), and any
other number the component reports, such as a rotor's Rpm. A raw parameter
needs an explicit from and to. An FTL spool bank reads
Spool, which runs from 0 at the jump order to 1 at the jump, and its
one‑shot layers are stretched to fit the spool. A binding to a parameter a sound cannot
read is skipped, and the layer stays at its authored level.
A bank with any <modulate> placed in a component's ambient slot
replaces the built‑in engine and power curves rather than adding to them.
The Sound Bank editor cannot edit from, to or
layer, and saving a bank in it resets all three. Author those in the
XML, and do not open that bank in the editor afterwards, or put them back after you
do.
Module-level settings
The wrapper element carries calibration that belongs to the asset set rather than the
engine:
<sound-banks master-volume="1" clip-radius="550">
master-volume trims every layer in the module — the control for a set of
masters that were recorded hotter than the base game's. It trims down only: keep it, and
every product of layer volume, bank volume and master volume, at or below 1, because on a
console's own sounds a gain above 1 is read as a percentage and comes out at a hundredth.
clip-radius is the positional audio horizon in world units, beyond which a
sound is not heard. It applies to sounds placed on objects in the 3D view; a console's own
sounds have no position. The fall‑off is linear and reaches silence well inside the radius,
at about half of it for a typical cue. A module working at a different scale needs a
different horizon.
Each bank uses its own module's settings. A module that sets neither gets 1 and 550, not
its parent's values.
Saving and reloading
A save in the Sound Bank editor takes effect on the server at once. Consoles that are
already open fetched their banks when they loaded, so reload them to hear the change. A
hand edit to sound-banks.xml needs a module reload from the Game Master
console, which cannot run while a mission is playing, or a server restart; a module reload
also tells open consoles to fetch the banks again.
When you audition right after a page load, the first sound fades in with the console
itself over about a second. Play it twice before you judge it.
Practical advice
- Set
instances from how often the sound really overlaps.
It is the difference between a battle and a stutter.
- Add
variance to anything that repeats. Weapons, impacts,
footsteps.
- Give loops an attack and release that suit them. The engine prevents
clicks; the ramps are for shaping.
- Keep aliases when you override a base bank, or older content stops
finding it.
- Fill in
description. It round‑trips through the editor,
and it is what makes a bank list navigable a year later.