API and Hooks
The API is available as game.modules.get('minstrel').api and as the global MINSTREL. It is created during ready and passed to the minstrel.ready hook.
Hooks.once('minstrel.ready', (api) => { api.moods.apply('mood-id');});Mood playback and cue resolution run on the active GM’s client. Calls to moods.apply, moods.stop, and cues.refresh do nothing on other clients. cues.suppress, video.play, and video.stop save world settings, so the calling user needs permission to modify world settings.
Console
Section titled “Console”| Function | Description |
|---|---|
MINSTREL.openConsole() | Opens or closes the Minstrel console. |
| Function | Returns | Description |
|---|---|---|
MINSTREL.moods.list() | object[] | Every saved mood. |
MINSTREL.moods.apply(id) | Promise<void> | Applies the mood with this id. |
MINSTREL.moods.stop(id) | Promise<void> | Stops the mood with this id. Omit id to stop the active mood. |
MINSTREL.moods.active() | string | null | Id of the active mood. |
See Moods.
Soundboard
Section titled “Soundboard”| Function | Returns | Description |
|---|---|---|
MINSTREL.soundboard.list() | object[] | Every saved soundboard pad. |
MINSTREL.soundboard.play(id) | Promise | Plays the pad with this id. |
See Soundboard.
A cue object holds a moodId, or a playlistId with an optional soundId. It can also carry a priority.
| Function | Returns | Description |
|---|---|---|
MINSTREL.cues.read(doc, context) | object | null | The cue stored on a Scene, Actor, or Token for a context key. |
MINSTREL.cues.write(doc, context, cue) | Promise | Stores a cue on the document and refreshes. Pass null to clear it. |
MINSTREL.cues.active() | object | null | The candidate chosen by the last refresh. |
MINSTREL.cues.refresh() | Promise | Re-runs cue resolution and applies the winning cue. |
MINSTREL.cues.candidates() | object[] | Every cue that could play for the current scene and combat. |
MINSTREL.cues.resolve() | object | null | The candidate that would win right now, without changing playback. |
MINSTREL.cues.suppress(context, on = true) | Promise | Silences a context key, or restores it when on is false. |
MINSTREL.cues.isSuppressed(context) | boolean | Whether a context key is silenced. |
A candidate has the shape { context, doc, type, cue, priority }. The built-in context keys are area and combat. See Music Cues.
Sections
Section titled “Sections”registerSection
Section titled “registerSection”const handle = MINSTREL.registerSection({ id: 'my-module.weather', label: 'Weather', priority: 10, types: ['Scene'], predicate: () => game.myModule.isStormy, contextKey: 'weather', hint: 'Plays while a storm is active.'});Registered sections appear on the console’s Other tab and compete with the built-in sections during cue resolution.
| Property | Type | Description |
|---|---|---|
id | string | Required. Unique registry id. |
label | string | Section name shown in the console. |
priority | number | Default priority for cues in this section. Defaults to 0. |
types | string[] | Document types the section applies to: Scene, Actor, Token, DefaultMusic. |
predicate | Function | Called with no arguments on each refresh. A falsy return keeps the section silent. |
contextKey | string | Key used for cue flags and suppression. Defaults to id. Cannot be area or combat. |
hint | string | Text describing when the section plays. |
Minstrel does not watch your predicate’s state. Call handle.refresh() when that state changes.
An invalid definition is logged and the call returns null. A successful call returns a handle.
| Member | Description |
|---|---|
id | The registered id. |
contextKey | The resolved context key. |
unregister() | Removes the section and refreshes cues. |
refresh() | Re-runs cue resolution. |
Registry functions
Section titled “Registry functions”| Function | Returns | Description |
|---|---|---|
MINSTREL.unregisterSection(id) | boolean | Removes a registered section. Does not refresh cues. |
MINSTREL.getRegisteredSections() | object[] | Every registered section definition. |
Ducking
Section titled “Ducking”MINSTREL.duck('music', 0.3, 4000);Lowers a core audio channel on every connected client, holds it for holdMs, then ramps it back. The arguments are channel (music, environment, or interface), factor (multiplies the channel volume), and holdMs. All three are optional and default to music, 0.3, and 4000. The ramp time comes from the Ducking Fade setting.
| Function | Returns | Description |
|---|---|---|
MINSTREL.video.open({ detached }) | Promise | Opens the video window. Pass detached: true to open it in its own window. |
MINSTREL.video.play(url, { at, title }) | string | null | Plays a YouTube link or video id for everyone, starting at at seconds. Returns the video id. |
MINSTREL.video.stop() | Promise | Stops the shared video. |
MINSTREL.video.state() | object | null | The shared video state: { id, title, playing, time, at }. |
See Video.
Syrinscape
Section titled “Syrinscape”MINSTREL.syrinscape exposes the integration module.
| Function | Description |
|---|---|
syrinscapeEnabled() | Whether the integration is on and a token is set. |
listSoundsets() | Resolves to the soundsets in your Syrinscape library. |
listMoods(uuid) | Resolves to the moods in a soundset. |
listElements(uuid) | Resolves to the elements in a soundset. |
play({ kind, id }, label) | Plays a mood or element. kind is mood or element. |
stop({ kind, id }) | Stops a mood or element. |
stopAll() | Stops all Syrinscape audio. |
setElementVolume(id, volume) | Sets an element’s volume from 0 to 1. |
nowPlaying() | The playing Syrinscape mood as { id, title }, or null. |
sessionId() | The joined Syrinscape session id, or null. |
See Syrinscape.
| Hook | Arguments | Fires |
|---|---|---|
minstrel.ready | api | On every client at the end of Minstrel’s ready setup. |
minstrel.moodApplied | mood | On the active GM’s client after a mood is applied. |
minstrel.moodStopped | mood | On the active GM’s client after a mood is stopped. |
minstrel.padPlayed | pad | On the client that played a soundboard pad. |
minstrel.cueChanged | { cue, mood } | On the active GM’s client after a cue refresh switches playback. |
minstrel.suppressionChanged | Set<string> | On the client that changed suppression. Passes the suppressed context keys. |
minstrel.syrinscapeChanged | { id, title } | null | On clients running the Syrinscape player when the playing mood or its elements change. |
minstrel.padChanged | none | On every client, when a soundboard pad’s audio starts or stops playing. |
minstrel.nowPlayingRotated | none | On a client, when its Now Playing bar rotates to the next source. |
When a cue targets a playlist or track, moodApplied, moodStopped, and cueChanged receive a mood object built from that playlist.
Hooks.call('minstrel.openConsole') opens or closes the console.
Glyph actions
Section titled “Glyph actions”With Glyph active, three Minstrel actions are available: Set Mood (Minstrel), Play Soundboard Pad (Minstrel), and Duck Audio (Minstrel).