MusicScript language and toolchain reference
The .gms language describes compositions. This manual combines a checked first score, timing rules, runtime boundaries, CLI workflows and declaration examples taken directly from canonical libgms.
Documentation baseline: 2026-09-12. Describes the September 12 software checkpoints. Deployment and real-device/listening acceptance are separate; availability depends on the installed build, account permissions and rollout flags.
Download this manual as Markdown1. Source, runtime and session
MusicScript is declarative: named blocks describe musical material and structure determines when sections occur. It is not JavaScript. Built-in call notation configures musical values; it does not enable arbitrary functions, executable imports or general control flow.
Canonical libgms owns the parser, AST, reference data, semantic checks and shared compilation helpers. Desktop, Web Studio and the standalone CLI consume that language, but each runtime has different audio, filesystem and host capabilities. Syntax highlighting alone cannot prove that a program can render.
.gms stores composition source. .gmstudio stores DAW state such as recorded takes, routing, plugins and picture edits. Those features do not become new language keywords simply because Studio supports them. Keep source and session files when both workflows matter.
2. A complete first score
project "First pocket" {
bpm: 100
key: Dm
time: 4/4
swing: 0
humanize: 0
}
beat drums {
kick: [X . . . . . . . X . . . . . . .]
snare: [. . . . X . . . . . . . X . . .]
hihat: [X . X . X . X . X . X . X . X .]
}
melody lead {
instrument: juno106
notes: [D4:4 F4:4 A4:4 F4:4]
velocity: 0.6
}
section verse { bars: 4 play: [drums lead] }
structure [verse x2]
- Save this text as first-pocket.gms in a project folder.
- Validate it, then check the intended engine and output target.
- Play or export with the native CLI, or open it in a compatible Studio editor.
- Change one element at a time: tempo, a kick step or a melody note. Save a new revision when you like the result.
gms validate first-pocket.gms
gms check first-pocket.gms --engine native --target export
gms play first-pocket.gms --engine native
gms export first-pocket.gms --engine native -o first-pocket.wavThe standalone CLI must be installed with a matching native renderer. The source example itself does not invoke paid generation or external media.
3. Lexical rules and declarations
Use named blocks with braces, property colons, bracketed lists, double-quoted strings and // comments. Commas are optional in many lists. Preserve ordinary ASCII characters for punctuation; a typographic minus is not the ASCII hyphen used in C-1.
Supported declaration families are project, beat, melody, theme, vocal, sample, video, fx_chain, section, structure, mix, lfo and parsed let. The declaration reference later in this manual comes from the same package as the editor. Some parsed constructs are deliberately rejected by output capability checks.
if/repeat are reserved tokens, not a general control-flow system. Structure repetition is written as a section name followed by xN. A .gmsmodule.json template expands to ordinary source; there is no executable module/import keyword.
4. Timing and pitch rules
| Context | Unit and meaning |
|---|---|
| Beat row | Expanded entries divide one bar evenly |
| Pitched beat D1:4 | One pitched hit followed by three padding rests: four grid positions total |
| Melody/theme D4:4 | Four sixteenth-note steps, equal to one quarter note |
| Omitted melody length | Two sixteenth-note steps |
| Bare dot / .:2 | One / two sixteenth-note rests; a rest does not inherit the prior note duration |
| Video at/length/fade | Quarter-note positions or lengths |
| Video offset_seconds | Seconds into the source file |
| humanize | Maximum deterministic timing offset in seconds, 0–0.05 |
Beat hits use X, rests use dots, and digits 0–9 encode velocity. A row of sixteen entries in 4/4 is a sixteenth-note grid. A row with another expanded length still fills a bar; count pitched padding before deciding its rhythmic division. Expansion is bounded to 4,096 steps per grid and 65,536 beat steps per program.
Pitches use A–G with optional #/b and octave, including -1. C-1 is MIDI note zero; playable pitches remain in MIDI 0–127. Melody notation is Pitch:Length:Velocity:Expression, with octave four when omitted. Explicit rest lengths are now honored; older builds that ignored them can play a different rhythm.
Chord qualities include major, m, m7, maj7, 7, dim, aug, sus2 and sus4. Arpeggiator direction and rate are separate settings. Expressions include accent, ghost, staccato, legato, tie, slide, cresc and decresc; event/MIDI output cannot represent every audio transformation.
5. Sections, tempo and structure
A section has a bar length and a play list of named material. Structure orders section occurrences and repetitions. Section BPM can be absolute or relative; relative changes apply in arrangement order, including repetitions.
Native timing uses the time signature, tempo map, eighth-note swing and deterministic humanize. Melody lengths remain sixteenths in changing meter. Deterministic humanize derives offsets from stable event identity rather than fresh randomness on every render.
Keep a live-synchronized score finite and within the selected adapter’s restrictions. A local export that accepts a tempo map does not prove that a network-following adapter accepts tempo overrides or infinite loops.
6. Built-in calls, mixing and automation
Effects include supported forms of reverb, delay, filter, compress/compression, distort, chorus, lofi and eq. level, pan, send, lufs, limiter and bar have context-specific meanings. They are not general functions that can execute arbitrary code.
Use playable names or beat.track targets for mix channels and bus.name for buses. Native mixing is stereo with equal-power panning and post-fader sends. In the native CLI, the authored master LUFS/limiter path performs its defined mastering; this differs from Desktop delivery presets that report targets without automatically normalizing.
Native section automation and LFO support include volume/pan targets; arbitrary effect-parameter targets are not implicitly supported. Parsed let variables are preserved but unresolved output semantics are rejected. Parsed autotune notation does not gain an implementation from the separate Studio pitch-correction panel.
Use the current capability checker rather than treating this list as engine parity. Web play and web export can differ in looping, effects, sample/vocal handling, automation, buses and mastering.
7. Samples, vocals and provenance
Keep referenced assets under the project root with portable relative paths. The CLI rejects absolute paths, home aliases, URLs and parent traversal. For direct IR consumption, choose the correct asset root explicitly. A path that works on the author’s machine is not evidence that a package contains its audio.
Sample chop ranges are normalized fractions from zero to one and concatenate in declared order before pitch/loop handling. Native sample decoding uses the supported decoder formats and bounded processing; multichannel source handling does not imply discrete surround output.
A vocal can refer to a prepared asset, with text/voice serving as generation metadata where a host explicitly supports it. Paid generation is a consumer operation. Audit the chosen executor bridge before embedding vocal playback; a default browser adapter may perform a remote request when credentials exist.
gms samples inspect library.gmspack
gms samples usage first-pocket.gms --jsonPreserve source rights and credits when importing samples or exporting selected material. Event and MIDI files carry musical events, not sample/vocal audio. Declared provenance is not a legal clearance or a digital signature.
8. Validate, diagnose and choose an engine
gms capabilities --engine native --json
gms check first-pocket.gms --engine native --target export
gms check first-pocket.gms --engine web --target export --json
gms check first-pocket.gms --engine native --sarif > diagnostics.sarifvalidate checks syntax. check adds semantic and selected-engine/target support, including references, ranges, arrangement reachability, assets and unsupported features. Targets distinguish play, export, events and midi. Do not consume a partial AST or output after errors.
Native is the default CLI engine. Ordinary Node lacks browser AudioContext globals; the optional web engine requires an explicitly compatible host and does not silently substitute another renderer. Native export supports WAV/FLAC at supported rates from 8–192 kHz. Web export is 44.1 kHz WAV with its narrower capability contract.
For a failure, retain the stable diagnostic code, source span, command and engine/version information. Fix the reported boundary first rather than deleting checks or repeatedly submitting the same unsupported render.
9. Install and inspect the CLI
In a source checkout, install dependencies and build the JavaScript command and native Rust renderer. Release installation must pair exact matching versions; an explicit missing native-binary override fails instead of searching elsewhere. Public package availability and signing are separate release decisions.
npm install
npm run build
cargo build --release
node dist/cli.js version --verbose
node dist/cli.js doctor --jsonThe source-checkout commands above use node dist/cli.js directly. Run npm link after building to register both gms and musicscript on PATH. Both names execute the same CLI and support the same commands and language. The shorter commands elsewhere assume an installed or explicitly linked CLI. For side-by-side development the CLI consumes canonical libgms at its documented sibling path; release staging bundles a clean canonical library. Do not point it at another product’s vendored snapshot. doctor reports environment/device metadata without intentionally playing sound.
gms version --verbose
musicscript version --verbose
gms packs
gms new brooklyn-boom-bap -o practice.gms
gms validate practice.gmsFactory-pack creation produces editable source and refuses an existing destination. A pack is a starting point, not proof that all target engines support every subsequent edit.
10. Inspect, format and export
| Command family | Purpose |
|---|---|
| parse / compile / ast | Canonical AST JSON or a concise declaration summary |
| compile-ir | Checked engine-neutral audio IR for native consumers |
| events / midi-out | Event or MIDI output through the canonical IR boundary |
| play / watch / export | Selected-engine audio with preflight checks |
| fmt / format and LSP | Formatting and editor diagnostics/navigation |
| module inspect / instantiate | Bounded reusable composition templates |
| video plan / export | Separate local picture-plan workflow |
| game-export | Targeted game assets and middleware import artifacts |
| serve / session / daemon / repl | Local host protocols and interactive workflows |
gms ast first-pocket.gms
gms compile-ir first-pocket.gms --engine native > first-pocket.ir.json
gms events first-pocket.gms
gms midi-out first-pocket.gms -o first-pocket.mid
gms fmt --check first-pocket.gms
gms lsp --stdioThe formatter preserves comments/authored literals and refuses invalid syntax rather than rewriting damaged source. Use fmt --check for a non-mutating gate; inspect ordinary formatting commands before running them across a folder.
11. Long exports and resumable work
gms export first-pocket.gms --stream --output first-pocket.wav --progress
gms export first-pocket.gms --resume ./render-cache --output first-pocket.wav --progressStreaming is native offline export, not unlimited live playback. It accumulates bounded work on disk and mixes in blocks. Limits include six hours with tails, 128 played tracks, 128 buses, 128 MiB per synthesized section voice, 64 MiB aggregate effect state per chain and an estimated 8 GiB working set. WAV also has its RIFF size bound; FLAC can avoid that particular output limit.
Resume retains completed tracks in a verified private cache; an interrupted track restarts. Changed inputs must pass cache validation before reuse. Temporary staging protects existing output on cooperative failure/cancellation. A forced process kill may leave an orphan directory; remove it only after its owner process has exited.
Disk backing limits memory, not CPU time. Reverb/effect tails and many sections may still render slowly. Split an oversized individual section rather than assuming a stream flag bypasses every budget.
12. Composition modules
.gmsmodule.json v1 contains self-contained instrumental source, bounded numeric parameters and ordered transforms of explicit melody/theme note lists. Instantiation returns ordinary editable source and resolved parameter values.
| Transform | Bound or rule |
|---|---|
| transpose | Integer −48…48 semitones; output MIDI pitches stay 0…127 |
| stretch | 0.25…4; resulting whole lengths 1…4096 |
| rotate | Integer −1024…1024 steps; positive moves the front toward the end |
| velocity | 0…2 multiplier; resulting velocities remain 0…1 |
| reverse | Literal boolean |
| Module limits | Up to 32 parameters, 64 transforms, bounded source and aggregate steps |
Transforms apply in order; note expression travels with its note. Unknown overrides, invalid pitches/lengths and out-of-range values fail rather than clipping. Modules do not support nested imports, external samples, vocals/video, beat/chord transformations or arbitrary expressions.
gms module inspect motif.gmsmodule.json
gms module instantiate motif.gmsmodule.json --param shift=7 -o raised.gms13. Video plans
Video is a separate versioned picture plan. Positions/lengths/fades are quarter-note units; source offsets are seconds. Decimal timing is resolved rationally through final frame rounding, including exact NTSC clocks for the supported fractional rates.
The first clip starts at zero; clips must be contiguous after outgoing crossfades. Fades/crossfades have clip-duration and five-second bounds. Captions are ordered, nonoverlapping and inside the picture. Limits are 200 clips, 2,000 captions and one hour.
CLI video export creates a new directory containing video.mp4 and video-plan.json, not a single output filename. compileVideo does not read source files. The host must validate real-path containment, readable media, codecs and source trim lengths. Picture-source audio is not automatically the soundtrack. Video is excluded from audio IR v1; arbitrary compositing and visualizers are not part of this language contract.
gms video plan promo.gms
gms video export promo.gms -o ./promo-deliverable14. Game exports and middleware
gms game-export game.gms --target unity --plan
gms game-export game.gms --target godot -o build/game-audioTargets include generic, unity, unreal, godot and web. A plan is deterministic metadata, not rendered audio. Full output uses safe target paths, validated rendered assets, hashes and staging; an existing output directory is not overwritten.
Middleware files include fmod-import.js, wwise-import.tsv, middleware-map.json and instructions. They assist asset/event import; Wwise looping/Music Segments/transitions/bank setup remain explicit vendor authoring. No vendor project is automatically opened, saved or built. Test timing, seams and rights in the target application.
15. REPL and host protocols
gms repl
gms serve
gms session --no-device
gms daemon ./musicThe REPL supports transactional source edits, undo and transport. serve offers versioned NDJSON checking/compilation/event services. session retains a native output stream while valid rendered generations are prepared away from the callback. --no-device supports headless hosts without opening a playback device.
daemon watches bounded local .gms inputs and retains the last valid state on bad edits. These are local protocols, not an automatic connection to Go Meow Server. A network host must explicitly integrate the server client/scheduling SDK and supply local content.
Cancellation is cooperative at documented boundaries. A web executor operation may finish before late disposal; do not assume an abort signal proves that all underlying audio work stopped immediately.
16. Studio-only features and live following
Recording takes/comping, third-party plugin state and MPE, sidechains/multibus routing, surround delivery, OSC/MIDI mixer recall and detailed video-edit state belong to Studio/host APIs and session formats. The episode pipeline’s videos runs/ship commands are not gms subcommands.
Desktop Go Meow Server following currently needs four quarter-note beats per bar, a finite single-tempo score without section BPM overrides or infinite melody loops, and local sample assets instead of vocal declarations. Re-arm after editing. Late joins skip earlier attacks; content and synth tails are not distributed by the clock server.
17. Canonical declaration and call examples
The sections below are generated from the installed canonical reference data, not maintained as a second syntax table. Entries may be fragments requiring named tracks/sections or prepared assets. The module entry is JSON. Parse recognition is not an engine-support guarantee; validate a complete score for the intended target.
Video
video: Separate local picture plan: at/length/fades/crossfade use quarter notes; offset_seconds uses source seconds. CLI video export and desktop video import consume it; ordinary audio IR omits it.
video name { fps aspect framing clip "file" { at length } caption "text" { at length } }video promo {
fps: 29.97
aspect: portrait
framing: cover
clip "media/clip.mp4" { at: 0 length: 4 fade_out: 1 }
caption "Make some noise" { at: 0 length: 2 }
}Theme
theme: Reusable melodic material referenced by section.play. Composition modules can transform theme note lists as well as melodies.
theme name { notes: [steps] }theme motif { notes: [C4:2 .:2 E4:4] }Named effects
fx_chain: A named effect chain referenced from section.fx. Native audio resolves chains; validate selected engine and target before rendering.
fx_chain name { effect(...) ... }fx_chain room {
reverb(0.3)
delay(0.25, 0.2)
}Parsed variables
let: Parsed and preserved, but current output engines do not resolve variables and reject let declarations. For reusable parameterized compositions, use a .gmsmodule.json template.
let name = valuelet amount = 4Composition modules
.gmsmodule.json: External JSON format, not a .gms declaration or executable function. Bounded numeric parameters drive transpose, stretch, reverse, rotate and velocity transformations of melody/theme notes. Create an editable instance in desktop MODULE or the CLI.
JSON template → MODULE / gms module instantiate → ordinary .gms{
"version": 1,
"name": "Motif",
"source": "melody lead { notes: [C4:2 .:2 E4:4] } section hook { bars: 1 play: [lead] } structure [hook]",
"parameters": {
"shift": {
"default": 0,
"min": -12,
"max": 12
}
},
"transforms": [
{
"target": "lead",
"transpose": {
"parameter": "shift"
}
}
]
}Project
project: Global timing and metadata. humanize is a deterministic maximum timing offset in seconds (0–0.05).
project "Title" { bpm key time swing humanize bars }project "Brooklyn Nights" {
bpm: 140
key: Dm
time: 4/4
swing: 0.12
humanize: 0.006
}Beat
beat: One bar divided evenly by expanded step count. X = hit, . = rest, 0-9 = velocity; Note:len adds a pitched hit and len−1 padding rests. Maximum 4096 steps per grid and 65536 beat steps per program.
beat name { track: [steps] }beat main {
kick: [X . . . X . . . X . . . X . . .]
snare: [. . X . . . X . . . X . . . X .]
hihat: [X 7 X 7 X 7 X 7 X 7 X 7 X 7 X 7]
808: [D1:8 . . F1:4 . . A1:2 . . . . . . . .]
}Melody
melody: Pitch:Length:Velocity:Expression; lengths are sixteenth notes and .:2 is a two-step rest. Octave -1 is supported (C-1 = MIDI 0). Expressions: accent, ghost, staccato, legato, tie, slide, cresc, decresc. Check engine/target support before output.
melody name { instrument notes chords arp fx velocity }melody hook {
instrument: juno106
notes: [D4:2:0.7:accent F4:2:1:slide A4:4:0.8:legato]
arp: up rate: 1/16
fx: [reverb(wet: 0.4) delay(time: 0.25, feedback: 0.5)]
velocity: 0.8
}chords: Chord progression. Quality: m m7 maj7 7 dim aug sus2 sus4
chords: [Root Quality:len]chords: [Dm:4 Am:4 Gm:4 Bb:4]Vocal
vocal: Portable rendered vocal audio. text and voice are host generation hooks; native rendering consumes asset.
vocal name { text voice asset pitch timing fx }vocal hook_vox {
text: "from Marcy to the world"
voice: hip_hop_male
asset: "vocals/hook.wav"
pitch: -2
timing: bar(1)
fx: [reverb(wet: 0.3)]
}Sample
sample: Load project-relative audio without traversal or URLs. chop selects ordered normalized ranges (0–1). Events/MIDI cannot represent sample audio.
sample name { file pitch volume loop chop }sample stab {
file: "samples/horn.wav"
pitch: +2
chop: [0:0.5, 0.5:1.0]
}Section
section: A named time block. bpm can be absolute (140) or relative (+5, -10).
section name { bars bpm play fx automate }section chorus {
bars: 8
bpm: +5
play: [main hook hook_vox]
fx: [reverb(0.5)]
}Structure
structure: Song arrangement. Each item is a section name with optional repeat count.
structure [ section xN ... ]structure [
intro x1
verse x2
chorus x2
bridge x1
chorus x4
]LFO
lfo: Native audio supports channel.volume and channel.pan; effect-parameter targets fail validation. Web live/offline support differs. Shapes: sine, triangle, square, sawtooth. Rate accepts note-time (4n) or Hz.
lfo { target shape rate depth }lfo {
target: lead.pan
shape: sine
rate: 4n
depth: 0.2
}Effects
reverb: Room reverb.
reverb(wet)reverb(0.4)delay: Feedback delay.
delay(time, feedback)delay(1/8, 0.5)filter: lpf | hpf | bandpass.
filter(type, freq)filter(lpf, 2000)compress: Dynamics compression.
compress(ratio:1, threshold)compress(4:1, -18db)eq: 3-band EQ.
eq(low: Ndb, mid: Ndb, high: Ndb)eq(low: +3db, mid: -2db)distort: Waveshaper distortion.
distort(amount)distort(0.4)autotune: Recognized syntax; current audio capability checks reject it. Use an explicitly processed vocal asset.
autotune(key)autotune(Dm)chorus: Native chorus; current Web Audio capability checks reject it.
chorus(rate, depth, wet)chorus(1.5, 0.3, 0.25)lofi: BitCrusher + warmth.
lofi()lofi()Mix
mix: Stereo channel and bus mix. Define buses as bus.name; master accepts lufs(-14) and limiter(-0.3db).
mix { channel: level(Ndb) pan(N) send(bus, Ndb) }mix {
bus.room: level(-3db) pan(0.2)
main.kick: level(-4db) pan(-0.4) send(room, -12db)
hook: level(-10db) pan(0.2)
master: lufs(-14) limiter(-0.3db)
}Instruments
instruments: Instrument presets for melody blocks. A theme declares notes only; it has no instrument property.
instrument: namejuno106 tb303 jupiter8 sh101 dx7
piano pad organ bass synth lead