Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Command Reference

All commands accept the global --json flag. Successful diagnostic commands write JSON to stdout; errors write one JSON object to stderr.

CommandPurpose
doctorProbe the platform, architecture, FFmpeg, and render backends
validate <scene>Validate scene syntax and semantics
schemaPrint the scene JSON Schema
schema --grammarPrint the grammar-profile schema
schema --profilePrint the leaf renderer-profile schema
schema --orchestrationPrint the orchestration-profile schema
schema --texture-profilePrint the texture-source profile schema
schema --resolverPrint the instrument-resolver config schema
lint <scene> --grammar <file> [--corpus <dir> …]Check compiled music against measurable style rules; --corpus supplies the scenes that style-independence rules compare against
midi <scene> -o <file>Compile deterministic Standard MIDI
makecode <scene> -o <file>Compile MakeCode music.createSong TypeScript (plus a .meta.json manifest)
render <midi> -o <wav>Render one MIDI file through a selected backend
export <audio> -o <file>Convert or trim audio through FFmpeg
build <scene> -o <file> [--space dry|room|hall] [--master <-LUFS>]Run the complete asset pipeline, optionally with a real room and a loudness target
profile check <profile>Render probes through every mapped SFZ patch in a leaf renderer profile
orchestration check <file>Validate palette bindings and every referenced leaf profile/SFZ file
inspect-instruments <scene>Resolve every track’s instrument and report substitutions and gaps
texture inspect <profile>Enumerate or exactly filter texture sources before writing textures[].source
texture check <profile>Verify every source exists, decodes, and is audible
diff <old> <new>Compare scene semantics
batch <scenes...> --out-dir <dir>Build several scenes and write a JSON report
mcpServe MCP (Model Context Protocol) over stdio; each tool wraps one CLI command

Exit codes are stable: 0 success, 1 I/O failure, 2 invalid input, 3 missing dependency, and 4 external tool failure.

Run scorekit <command> --help for the complete flag list shipped by the installed binary.

--space selects the ambience room (FluidSynth/TiMidity). It is separate from a scene’s reverb, which is only the CC91 send into that room; without it the render is dry, and a scene that sends reverb anyway prints WARN ambience:. --master <LUFS> measures the assembled asset with FFmpeg’s EBU R128 filter and applies one static gain, capped by --master-true-peak (default −1.0 dBFS). Because the gain is static it is distributive and time-invariant: stems still sum to the mix, the loop seal stays bit-exact, and meta.json records the plan under master together with space. Dynamics are not applied — compression and limiting are a post step on the delivered asset. Suite scenes refuse --master (per-section normalization would flatten the authored arc), and sfizz refuses any non-dry --space because .sfz patches own their own tails.

lint --corpus is the only flag that reads more than the scene: it is required by the corpus rules (corpus_instrument_overlap_max, corpus_axes_changed_min), repeatable, scanned recursively for *.yaml/*.yml, tolerant of non-scene YAML sidecars (counted as skipped), and exclusive of the scene under test. A corpus rule without --corpus, or a corpus that yields no scenes, is exit 2 rather than a silent pass.

Numeric audio-command options reject non-finite or out-of-range values before resolving tools or writing files: --sample-rate is 8000..=384000 Hz, --gain is 0.0..=8.0, --quality is 0..=10, --tail is 0.0..=3600.0 seconds, and --crossfade-ms is 0..=60000.

Scenes with textures require build/batch --texture-profile <file>. This flag is independent of the musical renderer: it works alongside either an SF2 --soundfont or an sfizz --orchestration profile.

Texture profile schema v1 structured sources and path-only mappings remain supported. Schema v2 adds family, tags, playback, optional curated audio descriptors (duration_seconds, intensity, brightness, and tonality), and scenes. texture inspect <profile> supports exact conjunctive filters (--family, repeated --tag, --scene, --mode, audio-property bounds, and --loopable); --limit/--offset page results. JSON includes the full inventory total, filter matched count, returned page, resolved paths, and file-existence flags. No candidate is reported as status: "no_match" with exit 0, never as an approximate match. Legacy path-only entries remain enumerable with metadata_available: false; texture check verifies file readability, decoding, and audible samples.

Standalone midi can encode melodic instruments with exact GM programs plus channel-10 drums/tabla. It rejects profile-only melodic identities before writing the output: the command has no renderer-profile input, and omitting a program change would make a generic GM player select piano. Use build --renderer sfizz --orchestration <file> to render those identities.

makecode compiles a scene to Microsoft MakeCode’s synth-song format (song encoding v0, played by MakeCode Arcade and micro:bit V2): a paste-ready .ts snippet with one let <name> = music.createSong(hex`…`) statement per song — one song per section for a suite — plus a .meta.json manifest reporting the tick grid and each track’s mapped MakeCode chip or drum voice. Synthesis happens entirely in the MakeCode runtime. Chip and drum amplitudes are scaled from track intensity against a ~1.2 full-scale mix budget so stacked voices stay near the MakeCode editor’s own 220–384 / 1024 range; tiny PWM speakers clip if every voice is written at full scale. Features the format cannot express fail with structured exit-2 errors (pitch bends/glide, clip CC automation, textures, timing finer than 255 ticks per beat such as humanize); pan/reverb are dropped with a WARN line and a manifest record. Keep bass in a chip-safe register — sub-bass square waves distort on Arcade and micro:bit speakers.

Instrument resolution

build and batch resolve every track’s instrument against what the selected backend actually provides before anything is rendered. SF2 backends resolve the 60-instrument core plus exact named extension programs (shakuhachi, sitar, shamisen); non-GM world identities fail rather than defaulting to piano. With --renderer sfizz availability is each track’s effective palette’s leaf renderer profile (routed through --orchestration <file>, the only sfizz routing input for build/batch/inspect-instruments), and unmapped instruments go through a scored fallback policy confined to that one palette — resolution never crosses palettes, even when another palette in the same orchestration happens to map the same instrument:

  • --fallback-mode conservative (default) substitutes within the same instrument family only, minimum score 0.70. Missing instruments never silently become strings — substituting into strings always requires an explicit allowed_families: [strings] opt-in in the resolver config.
  • --fallback-mode strict performs no substitution: an unmapped instrument fails the build (exit 2, code resolution) and the error names the best candidate it refused to use.
  • --fallback-mode flexible also reaches related families and synth stand-ins.
  • World instruments are exact-source-only under every mode: no fallback may enter, leave, or occur within that family.
  • --resolver <file> supplies a config (see scorekit schema --resolver) with default_mode, minimum_score, allow_cross_family, allow_synth, allowed_families, and excluded_families.

Every substitution prints one WARN instrument fallback: line with its score and reasons; meta.json embeds the full instrument_resolution report, including each track’s id, declared/effective palette, resolved leaf profile, requested/effective articulation, and resolved SFZ path. Unresolved instruments abort before staging, leaving no partial artifacts.

inspect-instruments <scene> [--orchestration <file>] [--resolver <file>] [--fallback-mode <mode>] [--verbose] prints the same resolution standalone: per-track status (exact/alias/fallback/missing/rejected), scores, reasons, palette/profile/SFZ routing, and the missing-instrument list. It exits 2 when instruments are unresolved, and --verbose lists every scored candidate. Alias spellings (e.g. french_horn for horn) are pure surface syntax and never change MIDI bytes.