-
Notifications
You must be signed in to change notification settings - Fork 1
Soundtracks Format Specification
Want a more beginner friendly guide? See the quickstart guide.
Your file structure will look as such: (Make sure Mason is installed to create the bootstrap.dll)
username-modname/
plugins/
resources/
...
boostrap.dll
icon.png
manifest.json
project.yaml
README.md
For most of this, i'll defer you to Thunderstore's packaging format.
For project.yaml, it should look as follows:
version: 1
dependencies:
hard:
dll.potatoes.ptnhbgml: 4.0.0
assets:
setup:
- path: soundtrack_manifest.yaml
plugin: dll.potatoes.ptnhbgml
loader: tnhbgml_soundtrack
Inside resources, it looks as follows:
resources/
soundtrack/
icon.png
soundtrack_manifest.yaml
soundtrack_manifest.yaml should look as follows:
name: My Awesome Mod Name
guid: my_user_name.my_mod_name
location: soundtrack
game_mode: tnh
soundtrack/
hold_[timing]_[metadata]_[identifier]/
intro_[metadata]_[identifier].ogg [OPTIONAL]
lo_[metadata]_[identifier].ogg
transition_[metadata]_[identifier].ogg [OPTIONAL]
medhi_[metadata]_[identifier].ogg [OPTIONAL]
end_[metadata]_[identifier].ogg [OPTIONAL]
endfail_[metadata]_[identifier].ogg [OPTIONAL]
orbactivate_[identifier].ogg [OPTIONAL]
orbwave_[identifier].ogg [OPTIONAL]
orbsuccess_[identifier].ogg [OPTIONAL]
orbfailure_[identifier].ogg [OPTIONAL]
take_[timing]_[metadata]_[identifier]/
takeintro_[metadata]_[identifier].ogg [OPTIONAL]
take_[metadata]_[identifier].ogg
alert_[metadata]_[identifier].ogg [OPTIONAL]
preview_loop.ogg [OPTIONAL] *Incompatible with preview.
preview.ogg [OPTIONAL] *Incompatible with preview_loop.
This may look intimidating, but let us break it down.
[metadata] is optional. If you have none, simply do not include it. As an example. hold_[timing]_[metadata]_[identifier]
-> hold_[timing]_[identifier]
.
There are two core parts to this: tracks (the ogg files) and track sets (the folders). And the preview.
Tracks are written as:
[type]_[metadata]_[identifier].ogg
And Track sets are written as:
[type]_[timing]_[metadata]_[identifier]
Type identifies where this song should be played. The types are:
takeintro - Optional
Plays at the start of the take phase.
If this does not exist, `take` will play at the start of the take phase.
take
Plays after the takeintro, if it exists.
Keep this on loop.
alert - Optional
Plays whenever in a fight with Sosigs during a take.
Returns back to take whenever finished.
By default, it will return to take at [time played take] + [time played alert], similar to seamless transition (st).
If you want it to return to start of take track, use "restart" metadata on alert theme.
If you want take to resume where it stopped, use "return" metadata on alert theme.
intro - Optional
Plays at the start of the hold phase- right after touching the orb.
Will transition to the `lo` theme.
If this does not exist, `lo` will be played directly after touching the orb.
lo
Plays after the intro, for the duration of the hold except on the last phase.
Keep this on loop.
transition - Optional
A song that plays to transition from the `lo` to the `medhi`.
Plays on the start of the last phase of the hold.
If this does not exist, it will be skipped and it will simply go from `lo` to `medhi`.
Requires `medhi` to exist.
medhi - Optional
Plays after the transition, for the duration of the last phase of the hold.
The only exception is the first hold, which uses `lo` for its one and only phase.
If this does not exist, the `lo` will be used for the duration of the whole hold, including the last phase.
`transition` requires `medhi` to exist.
end - Optional
Plays at the end of the hold phase.
If does not exist, it will transition directly to `takeintro`.
endfail - Optional
Plays if time runs out in the hold phase.
If does not exist, will use `end` instead. Requires `end` to exist in the trackset.
orbactivate
Replaces the sound the orb makes when you first touch the orb.
orbwave
Replaces the sound the orb makes when you finish a phase of a hold by destroying all encryptions.
orbsuccess
Replaces the sound the orb makes when you finish the hold
orbfailure
Replaces the sound the orb makes when you fail the hold by running out of time.
Note that Orb sounds are different in that, while other types are played directionless (appears to have no physical source), the orb sounds are played from the orb.
Other
preview
- Optional
Only one may exist.
Incompatible with preview_loop
Plays when the mod is selected from the TnH BGM selection panel in the TnH lobby.
If does not exist (and preview_loop
doesnt either), no song will play when your mod is selected.
Plays for as long as the preview is. Try to keep it short, with a high theme to show off how your mod sounds like mid-hold.
Minimum of 4 seconds.
Fades in for two seconds, fades out the last two seconds.
preview_loop
- Optional
Only one may exist.
Incompatible with preview
Plays when the mod is selected from the TnH BGM selection panel in the TnH lobby.
If does not exist (and preview
doesnt either), no song will play when your mod is selected.
preview_loop
will not stop. At the end of the preview, it will loop.
As this is a long, looping song, try to keep the song low-energy and more "main menu" theme-y.
Minimum of 2 seconds.
Fades in the first two seconds.
It is okay (and encouraged) to have several tracks with the same, overlapping type in a given trackset. When two tracks can both be played at a given point, the system will choose one at random to play. This offers greater variety and replayability (relistenability?) in your music mod.
The traditional 5 hold TnH timing goes as such:
TnH started
V
Take 0
V
Orb touched
V
Hold 0
V
Hold finish
V
Take 1
V
Orb touched
V
Hold 1
V
Hold finish
V
...
V
Take 4
V
Hold started
V
Hold 4
V
Hold finished
V
Victory!
You will notice despite having 5 holds, it ends at "hold 4". This is because we start counting from zero.
Timing indicates where this song may be played.
Same with overlapping types, it is okay to have overlapping timings. When two tracksets can be played, the system will choose one at random to play.
Regular timings
`0` -> The first hold and the take prior to it.
`1` -> The second hold and the take prior to it.
`2` -> The third hold and the take prior to it.
...
Glob timings
`1-3` -> the second, third, and fourth hold.
`0,2,4` -> the first, third, and fifth hold.
`ge1` -> Hold 2 and above. (ge = Greater than or Equal to)
`le1` -> Hold 2 and below. (le = Lesser than or Equal to)
... you get the idea.
Please do not mix two or more globs!
EG: 0-2,4
and 1,ge3
is INVALID!
General timings
fallback
Can be played at any opportunity, but `#` soundtracks will be prioritized. (e.g given `take_0_RedSong.ogg` vs `take_fallback_BluSong.ogg`, RedSong will always be played in the first take- never BluSong.)
all
Can be played at any opportunity, pulled at random. `#` soundtracks will NOT be prioritized. (e.g given `take_0_RedSong.ogg` vs `take_all_BluSong.ogg`, a coinflip will be made whether to use RedSong or BluSong in the first take.)
death
Song that plays once you die. Must be a take song (e.g take_death_AwesomeDeathMetalMusic.ogg)
win
Song that plays once you win. Must be a take song (e.g take_win_CoolAssSong.ogg)
If you are designing your soundtrack for a traditional 5 hold, please set the final timings not to 4
, but to ge4
. This makes it so endless players wont error out and can use your soundtrack.
You may use numbers greater than 4 for endless players- there is no restriction.
AKA, name.
This doesn't do much- it just makes sure two sets dont have the same name.
It is encouraged not to make two songs with the same identifier, for debugging reasons. And your own sanity. (It will still, however, work.)
Quite literally anything (Minus anything Windows won't let you type, obviously). Words, numbers, whatever. Please do not use the character _
in your identifier.
This can be useful if two sets have the same timings. (Example: hold_1_AwesomeBoneRiffs
vs hold_1_LessAwesomeBoneRiffs
)
When two soundtracks or tracks can be played, such as the example above, a random one will be picked.
Metadata is for more advanced users.
This allows modders to customize more their sequences to their likings.
If no metadata, skip. Write as [Base file name]_[identifier].ogg
If multiple metadata is available, separate with -
. EG: dnf-st
dnf - Do Not Fade
By default, tracks start fading into the next one 1.5s before the end of the track. (Or if caused by an event, like take -> intro when starting a hold.)
dnf, or Do Not Fade, will remove the fade into the song it is applied to. IT DOES NOT REMOVE THE FADE INTO THE NEXT SONG, UNLESS THAT NEXT SONG ALSO HAS DNF.
Example
take > fade > intro > fade > lo
take > intro_dnf > fade > lo
take > intro_dnf > lo_dnf
take > fade > intro > lo_dnf
st - Seamless Transition
This song will start playing at the same point as the previous track.
As an example:
Assume Transition.ogg does not exist. When Lo is 30s into its track and transition occurs, it will fade into MedHi at 30s.
This allows for a MedHi that mirrors the Lo song but is much more badass and cool and shit, and will naturally and seamlessly transition.
Applied to the track it is seamlessly transitioning TO, not FROM.
Applied to the situation above, you would apply st
to the MEDHI, NOT THE LO.
Incompatible with fs
.
loop - Loop
Makes the song repeat when track comes to end, instead of playing next track.
The following types of songs should be looped:
- take
- lo
- medhi
fs - Failure Sync
Failure Sync: Aligns the end of the song with the failure time of the hold.
May only be applied to `lo` and `medhi`.
NOTE: The amount of time to failure sync is VARIABLE. Be careful! Make sure your song is long enough or else it WILL throw an error if the amount of time to reach failure is longer than the length of your song.
The song preceding (usually intro or transition) must be AT LEAST 5s LONG.
Note that the track is set to finish 3 seconds after the actual failure time, for some buffer zone.
Incompatible with st
.
(Please note that the below metadata are Institution specific. They make no difference outside of Institution.)
center
Makes the trackset play only on central in Institution.
north
Makes the trackset play only in Government in Institution.
south
Makes the trackset play only in Industry in Institution.
west
Makes the trackset play only in Temple in Institution.
east
Makes the trackset play only in Power in Institution.
anyreg - Any Region
Makes the trackset play on any region.
Please not *not* adding this on a trackset will make it act as a fallback trackset
(Never played unless no other tracksets to play).
nsbr - No Switch Between Regions
Does not switch tracks when crossing regions. When selected, will continue to play until hold.
Recall that the traditional soundtrack system is:
soundtrack/
hold_[timing]_[metadata]_[identifier]/
intro_[metadata]_[identifier].ogg [OPTIONAL]
lo_[metadata]_[identifier].ogg
transition_[metadata]_[identifier].ogg [OPTIONAL]
medhi_[metadata]_[identifier].ogg [OPTIONAL]
end_[metadata]_[identifier].ogg [OPTIONAL]
endfail_[metadata]_[identifier].ogg [OPTIONAL]
orbactivate_[identifier].ogg [OPTIONAL]
orbwave_[identifier].ogg [OPTIONAL]
orbsuccess_[identifier].ogg [OPTIONAL]
orbfailure_[identifier].ogg [OPTIONAL]
take_[timing]_[metadata]_[identifier]/
takeintro_[metadata]_[identifier].ogg [OPTIONAL]
take_[metadata]_[identifier].ogg
alert_[metadata]_[identifier].ogg [OPTIONAL]
preview_loop.ogg [OPTIONAL] *Incompatible with preview.
preview.ogg [OPTIONAL] *Incompatible with preview_loop.
In some situations, you may want the take to be unified with the hold. I.E, a particular take plays with a particular hold, always.
To do this, simply put all the take songs into the hold trackset and remove the take trackset, like so.
soundtrack/
hold_[timing]_[metadata]_[identifier]/
intro_[metadata]_[identifier].ogg [OPTIONAL]
lo_[metadata]_[identifier].ogg
transition_[metadata]_[identifier].ogg [OPTIONAL]
medhi_[metadata]_[identifier].ogg [OPTIONAL]
end_[metadata]_[identifier].ogg [OPTIONAL]
endfail_[metadata]_[identifier].ogg [OPTIONAL]
orbactivate_[identifier].ogg [OPTIONAL]
orbwave_[identifier].ogg [OPTIONAL]
orbsuccess_[identifier].ogg [OPTIONAL]
orbfailure_[identifier].ogg [OPTIONAL]
takeintro_[metadata]_[identifier].ogg [OPTIONAL]
take_[metadata]_[identifier].ogg
alert_[metadata]_[identifier].ogg [OPTIONAL]
preview_loop.ogg [OPTIONAL] *Incompatible with preview.
preview.ogg [OPTIONAL] *Incompatible with preview_loop.
Phases is for more advanced users.
soundtrack/
hold_[timing]_[identifier]/
intro_[metadata]_[identifier].ogg [OPTIONAL]
phase0_[metadata]_[identifier].ogg
phasetr0_[metadata]_[identifier].ogg [OPTIONAL]
phase1_[metadata]_[identifier].ogg
phasetr1_[metadata]_[identifier].ogg [OPTIONAL]
phase2_[metadata]_[identifier].ogg
phasetr2_[metadata]_[identifier].ogg [OPTIONAL]
...
end_[metadata]_[identifier].ogg [OPTIONAL]
orbactivate_[identifier].ogg [OPTIONAL]
orbwave_[identifier].ogg [OPTIONAL]
orbsuccess_[identifier].ogg [OPTIONAL]
orbfailure_[identifier].ogg [OPTIONAL]
Phases is an alternate way to handle songs instead of the Lo/MedHi system.
phasetr stands for Phase Transition.
The sequence is as follows:
Intro > Phase0 > Phasetr0 > Phase1 > Phasetr1 > ... > PhaseX > end
phase is expected to have the loop
metadata, and phasetr is expected to not have the loop
metadata. (This is not necessary, however.)
At the end of every phase of a hold, it will play the following phase transition. If there is no phase transition, it will simply play the next phase song.
If number of phases outnumbers number of phase tracks, the last phase will loop.