# 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.

## Contents

- [1. Source, runtime and session](#model)

- [2. A complete first score](#first-score)

- [3. Lexical rules and declarations](#syntax)

- [4. Timing and pitch rules](#timing)

- [5. Sections, tempo and structure](#arrangement)

- [6. Built-in calls, mixing and automation](#effects)

- [7. Samples, vocals and provenance](#assets)

- [8. Validate, diagnose and choose an engine](#validation)

- [9. Install and inspect the CLI](#install)

- [10. Inspect, format and export](#cli)

- [11. Long exports and resumable work](#streaming)

- [12. Composition modules](#modules)

- [13. Video plans](#video)

- [14. Game exports and middleware](#game)

- [15. REPL and host protocols](#services)

- [16. Studio-only features and live following](#boundaries)

- [17. Canonical declaration and call examples](#reference-note)

- [Video](#reference-video)

- [Theme](#reference-theme)

- [Named effects](#reference-fx_chain)

- [Parsed variables](#reference-let)

- [Composition modules](#reference-modules)

- [Project](#reference-project)

- [Beat](#reference-beat)

- [Melody](#reference-melody)

- [Vocal](#reference-vocal)

- [Sample](#reference-sample)

- [Section](#reference-section)

- [Structure](#reference-structure)

- [LFO](#reference-lfo)

- [Effects](#reference-fx)

- [Mix](#reference-mix)

- [Instruments](#reference-instruments)

<a id="model"></a>

## 1. 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.

<a id="first-score"></a>

## 2. A complete first score

```gms
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]
```

1. Save this text as first-pocket.gms in a project folder.
2. Validate it, then check the intended engine and output target.
3. Play or export with the native CLI, or open it in a compatible Studio editor.
4. Change one element at a time: tempo, a kick step or a melody note. Save a new revision when you like the result.

```sh
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.wav
```

The standalone CLI must be installed with a matching native renderer. The source example itself does not invoke paid generation or external media.

<a id="syntax"></a>

## 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.

<a id="timing"></a>

## 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.

<a id="arrangement"></a>

## 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.

<a id="effects"></a>

## 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.

<a id="assets"></a>

## 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.

```sh
gms samples inspect library.gmspack
gms samples usage first-pocket.gms --json
```

Preserve 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.

<a id="validation"></a>

## 8. Validate, diagnose and choose an engine

```sh
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.sarif
```

validate 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.

<a id="install"></a>

## 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.

```sh
npm install
npm run build
cargo build --release
node dist/cli.js version --verbose
node dist/cli.js doctor --json
```

The 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.

```sh
gms version --verbose
musicscript version --verbose
gms packs
gms new brooklyn-boom-bap -o practice.gms
gms validate practice.gms
```

Factory-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.

<a id="cli"></a>

## 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 |

```sh
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 --stdio
```

The 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.

<a id="streaming"></a>

## 11. Long exports and resumable work

```sh
gms export first-pocket.gms --stream --output first-pocket.wav --progress
gms export first-pocket.gms --resume ./render-cache --output first-pocket.wav --progress
```

Streaming 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.

<a id="modules"></a>

## 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.

```sh
gms module inspect motif.gmsmodule.json
gms module instantiate motif.gmsmodule.json --param shift=7 -o raised.gms
```

<a id="video"></a>

## 13. 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.

```sh
gms video plan promo.gms
gms video export promo.gms -o ./promo-deliverable
```

<a id="game"></a>

## 14. Game exports and middleware

```sh
gms game-export game.gms --target unity --plan
gms game-export game.gms --target godot -o build/game-audio
```

Targets 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.

<a id="services"></a>

## 15. REPL and host protocols

```sh
gms repl
gms serve
gms session --no-device
gms daemon ./music
```

The 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.

<a id="boundaries"></a>

## 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.

- [Desktop manual](https://gomeow.media/docs/desktop)
- [Live-session setup](https://gomeow.media/docs/live-sessions)
- [Library APIs](https://gomeow.media/docs/libgms)

<a id="reference-note"></a>

## 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.

<a id="reference-video"></a>

## 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.

```text
video name { fps aspect framing clip "file" { at length } caption "text" { at length } }
```

```gms-fragment
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 }
}
```

<a id="reference-theme"></a>

## Theme

theme: Reusable melodic material referenced by section.play. Composition modules can transform theme note lists as well as melodies.

```text
theme name { notes: [steps] }
```

```gms-fragment
theme motif { notes: [C4:2 .:2 E4:4] }
```

<a id="reference-fx_chain"></a>

## Named effects

fx_chain: A named effect chain referenced from section.fx. Native audio resolves chains; validate selected engine and target before rendering.

```text
fx_chain name { effect(...) ... }
```

```gms-fragment
fx_chain room {
  reverb(0.3)
  delay(0.25, 0.2)
}
```

<a id="reference-let"></a>

## 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.

```text
let name = value
```

```gms-fragment
let amount = 4
```

<a id="reference-modules"></a>

## Composition 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.

```text
JSON template → MODULE / gms module instantiate → ordinary .gms
```

```json
{
  "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"
      }
    }
  ]
}
```

<a id="reference-project"></a>

## Project

project: Global timing and metadata. humanize is a deterministic maximum timing offset in seconds (0–0.05).

```text
project "Title" { bpm key time swing humanize bars }
```

```gms-fragment
project "Brooklyn Nights" {
  bpm:      140
  key:      Dm
  time:     4/4
  swing:    0.12
  humanize: 0.006
}
```

<a id="reference-beat"></a>

## 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.

```text
beat name { track: [steps] }
```

```gms-fragment
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 . . . . . . . .]
}
```

<a id="reference-melody"></a>

## 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.

```text
melody name { instrument notes chords arp fx velocity }
```

```gms-fragment
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

```text
chords: [Root Quality:len]
```

```gms-fragment
chords: [Dm:4 Am:4 Gm:4 Bb:4]
```

<a id="reference-vocal"></a>

## Vocal

vocal: Portable rendered vocal audio. text and voice are host generation hooks; native rendering consumes asset.

```text
vocal name { text voice asset pitch timing fx }
```

```gms-fragment
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)]
}
```

<a id="reference-sample"></a>

## Sample

sample: Load project-relative audio without traversal or URLs. chop selects ordered normalized ranges (0–1). Events/MIDI cannot represent sample audio.

```text
sample name { file pitch volume loop chop }
```

```gms-fragment
sample stab {
  file:  "samples/horn.wav"
  pitch: +2
  chop:  [0:0.5, 0.5:1.0]
}
```

<a id="reference-section"></a>

## Section

section: A named time block. bpm can be absolute (140) or relative (+5, -10).

```text
section name { bars bpm play fx automate }
```

```gms-fragment
section chorus {
  bars: 8
  bpm:  +5
  play: [main hook hook_vox]
  fx:   [reverb(0.5)]
}
```

<a id="reference-structure"></a>

## Structure

structure: Song arrangement. Each item is a section name with optional repeat count.

```text
structure [ section xN ... ]
```

```gms-fragment
structure [
  intro   x1
  verse   x2
  chorus  x2
  bridge  x1
  chorus  x4
]
```

<a id="reference-lfo"></a>

## 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.

```text
lfo { target shape rate depth }
```

```gms-fragment
lfo {
  target: lead.pan
  shape:  sine
  rate:   4n
  depth:  0.2
}
```

<a id="reference-fx"></a>

## Effects

reverb: Room reverb.

```text
reverb(wet)
```

```gms-fragment
reverb(0.4)
```

delay: Feedback delay.

```text
delay(time, feedback)
```

```gms-fragment
delay(1/8, 0.5)
```

filter: lpf | hpf | bandpass.

```text
filter(type, freq)
```

```gms-fragment
filter(lpf, 2000)
```

compress: Dynamics compression.

```text
compress(ratio:1, threshold)
```

```gms-fragment
compress(4:1, -18db)
```

eq: 3-band EQ.

```text
eq(low: Ndb, mid: Ndb, high: Ndb)
```

```gms-fragment
eq(low: +3db, mid: -2db)
```

distort: Waveshaper distortion.

```text
distort(amount)
```

```gms-fragment
distort(0.4)
```

autotune: Recognized syntax; current audio capability checks reject it. Use an explicitly processed vocal asset.

```text
autotune(key)
```

```gms-fragment
autotune(Dm)
```

chorus: Native chorus; current Web Audio capability checks reject it.

```text
chorus(rate, depth, wet)
```

```gms-fragment
chorus(1.5, 0.3, 0.25)
```

lofi: BitCrusher + warmth.

```text
lofi()
```

```gms-fragment
lofi()
```

<a id="reference-mix"></a>

## Mix

mix: Stereo channel and bus mix. Define buses as bus.name; master accepts lufs(-14) and limiter(-0.3db).

```text
mix { channel: level(Ndb) pan(N) send(bus, Ndb) }
```

```gms-fragment
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)
}
```

<a id="reference-instruments"></a>

## Instruments

instruments: Instrument presets for melody blocks. A theme declares notes only; it has no instrument property.

```text
instrument: name
```

```gms-fragment
juno106  tb303  jupiter8  sh101  dx7
piano  pad  organ  bass  synth  lead
```

Generated from shared/docs. Edit the source manual and run npm run docs:generate; do not edit this generated copy.
