Skip to content
3 Death Saves

API Reference

The API is published as the global MINSTREL and at game.modules.get('minstrel').api. Both point to the same object.

Mood and cue playback runs on one client. moods.apply, moods.stop, and cues.refresh return early unless the calling client is the active GM, so a call from a player client does nothing. Ducking and file-backed soundboard pads are broadcast and take effect on every client.

The API object is built during Foundry’s ready hook, before minstrel.ready fires. Register sections from that hook.

MethodReturnsDescription
MINSTREL.moods.list()object[]Every saved mood.
MINSTREL.moods.apply(id)Promise<void>Starts a mood. Accepts a mood id or a mood object.
MINSTREL.moods.stop(id)Promise<void>Stops a mood. Called with no argument, stops the active mood.
MINSTREL.moods.active()string | nullThe id of the mood currently applied.
MethodReturnsDescription
MINSTREL.soundboard.list()object[]Every saved pad.
MINSTREL.soundboard.play(id)Promise<Sound | void>Plays a pad. A file-backed pad plays on every client.

A pad record is { id, label, src, icon, color, volume, duck }. A pad wired to Syrinscape carries syrinscapeId and syrinscapeKind instead of playing src.

MethodReturnsDescription
MINSTREL.cues.read(doc, context)object | nullThe cue stored on a document for a context key.
MINSTREL.cues.write(doc, context, cue)PromiseStores a cue, then re-resolves playback. A cue with neither moodId nor playlistId clears the assignment.
MINSTREL.cues.active()object | nullThe winning cue candidate.
MINSTREL.cues.refresh()Promise<void>Re-runs cue resolution, for when a predicate would now answer differently.
MINSTREL.cues.suppress(context, on)Promise<void>Adds or removes a context key from the suppressed set. on defaults to true.
MINSTREL.cues.isSuppressed(context)booleanWhether a context key is suppressed.

read and write take a Scene, Actor, or Token document.

active() returns the resolved candidate, not the raw cue:

FieldTypeDescription
contextstringThe context key that won.
docDocumentThe document the cue came from.
typestringThe document type: Scene, Actor, Token, or DefaultMusic.
cueobjectThe stored cue.
prioritynumberThe priority used for sorting.

Suppression is a world-scoped set of context keys covering the built-in area and combat contexts and any registered section’s context key. Changing it re-runs cue resolution.

MINSTREL.duck('music', 0.3, 4000);

Dips an audio channel, holds it, then ramps it back. The call is emitted over the socket, so every client ducks.

ParameterTypeDescription
channelstringmusic, environment, or interface. Defaults to music.
factornumberMultiplier applied to the channel’s configured volume, clamped to 0 through 1. Defaults to 0.3.
holdMsnumberHow long to hold the dip before restoring. Defaults to 4000.

The ramp duration comes from the Ducking Fade setting rather than from the call. See Settings.

MINSTREL.openConsole() toggles the console window. It opens when closed and closes when open.

The MINSTREL.syrinscape namespace wraps the Syrinscape Online frontend API using the token stored in settings.

MethodReturnsDescription
syrinscapeEnabled()booleanTrue when the integration is enabled and a token is set.
listSoundsets()Promise<object[]>Soundsets as { uuid, name }.
listMoods(uuid)Promise<object[]>Moods in a soundset as { id, name }.
listElements(uuid)Promise<object[]>Elements in a soundset as { id, name }.
playMood(id), stopMood(id)Promise<void>Starts or stops a Syrinscape mood.
playElement(id), stopElement(id)Promise<void>Starts or stops a Syrinscape element.
stopAll()Promise<void>Stops all Syrinscape playback.
play(trigger), stop(trigger)Promise<void>Routes { kind, id } to the mood or element call. kind is mood or element.

Every request runs from the calling client. play and stop do nothing while the integration is disabled or the trigger has no id. The list helpers return an empty array when no token is set, and a failed request is logged rather than thrown.

const handle = MINSTREL.registerSection({
id: 'my-module.weather',
label: 'MYMODULE.WeatherMusic',
priority: 10,
types: ['Scene'],
predicate: () => game.myModule.isStormy,
contextKey: 'weather'
});

Registers a cue section. A registered section gets its own group on the console’s Other tab, with rows for the documents of each type it covers, and competes in the same priority ordering as the built-in sections. The Other tab stays hidden while no section is registered.

PropertyTypeDescription
idstringRequired. Unique registry id.
labelstringLocalization key for the group heading. Used verbatim when it resolves to nothing.
prioritynumberDefault sort priority for the section’s cues. Defaults to 0.
typesstring[]Document type names the section applies to: Scene, Actor, Token, DefaultMusic. Defaults to an empty array.
predicateFunctionActivation test, called with no arguments once per cue resolution. A falsy return keeps the section silent.
contextKeystringContext key used for flags, suppression, and playback. Defaults to the id.
hintstringLocalization key describing when the section plays, shown as the tooltip on each row’s name.

Registration is validated. It is rejected, logged, and returns null when:

  • id is missing or not a string.
  • id is already registered.
  • types is not an array, or contains a name outside Scene, Actor, Token, DefaultMusic.
  • predicate is defined but not a function.
  • The context key is area or combat, or is already claimed by another registered section.

A successful call returns a handle:

MemberDescription
idThe registered id.
contextKeyThe resolved context key.
unregister()Removes the section and refreshes cues.
refresh()Re-runs cue resolution.

A predicate that throws is logged and disables its section for that resolution pass.

MINSTREL.unregisterSection(id) removes a section by id and returns true when one was removed. MINSTREL.getRegisteredSections() returns every registered definition. Neither one refreshes cues on its own.

SectionPriority
Token combat5
Actor combat0
Global combat-5
Scene combat-10
Scene area-20

A cue’s own priority overrides the section default.

A cue is a small object stored per context key. It names either a mood or a playlist.

FieldTypeDescription
moodIdstringId of a saved mood.
playlistIdstringId of a Playlist document.
soundIdstringOptional. Id of a PlaylistSound in that playlist, to start one track instead of the whole playlist.
prioritynumberOptional. Overrides the section’s default priority.

Cues live at flags.minstrel.cues.<context> on Scene, Actor, and Token documents. The Global row is stored in a world setting instead of on a document.

read falls back to legacy data when the document carries no Minstrel cue. On a Scene it reads flags.minstrel.moodId for a non-combat context and flags.minstrel.combatMoodId for the combat context. It then reads a flags.vgmusic.music.<context> entry, mapping its playlist, initialTrack, and priority onto the cue shape.

HookPayloadDescription
minstrel.readyapiFires once the API object is published.
minstrel.moodAppliedmoodFires on the active GM when a mood starts.
minstrel.moodStoppedmoodFires on the active GM when a mood stops.
minstrel.padPlayedpadFires on the client that triggered a soundboard pad.
minstrel.cueChanged{ cue, mood }Fires on the active GM when cue resolution settles on a different mood. Both fields are null when nothing wins.
minstrel.suppressionChangedSet<string>Fires on the client that changed suppression, with the new set of suppressed context keys.
Hooks.on('minstrel.cueChanged', ({ cue, mood }) => {});

Minstrel also listens for one inbound hook. Calling Hooks.call('minstrel.openConsole') toggles the console, the same as MINSTREL.openConsole().

Pack authors can ship these flags on documents inside a compendium.

FlagTypeDescription
flags.minstrel.artstringPath to the cover image shown on the album tile and in the mini player.
flags.minstrel.colorstringAccent color. Falls back to a color derived from the playlist id when unset.
flags.minstrel.favoritebooleanPins the playlist to the top of the library.
flags.minstrel.crossfadebooleanRuns the playlist through the crossfade conductor.
flags.minstrel.levelnumberPlaylist fader level applied on top of each track’s own volume. Treated as 1 when unset.
flags.minstrel.packSourcestringLinks a world playlist to the compendium playlist it was imported from. A later pad import from the same origin reuses that playlist instead of creating a second one.
FlagTypeDescription
flags.minstrel.artiststringArtist credit shown for the playing track.
flags.minstrel.sourcestringSource credit shown for the playing track.
flags.minstrel.padobjectSoundboard pad preset. label, icon, color, volume, and duck seed the pad created from this track.
FlagTypeDescription
flags.minstrel.cuesobjectCues keyed by context, using the shape above.