Timeline format
Compiling a score produces a timeline: plain JSON that places the score’s intent on numbered bars. It contains nothing specific to a model, and no real-time values; the renderer converts bars to seconds during playback. Produce one with the CLI, or with compileSource in the JavaScript API:
npx @luna-estelar/gas@0.2.0 compile song.gas --out song.timeline.jsonTop level
| Field | Meaning |
|---|---|
formatVersion |
{ major, minor } version of this JSON format |
timelineId |
Identifier for the timeline; "timeline" unless the caller supplies one |
languageVersion |
Version of the GAS language, currently "1.0" |
compilerVersion |
Version of the compiler package, currently "0.1.3" |
source |
{ mediaType, byteLength, name? } |
playback |
Finite, loop, or infinite playback |
arrangedBars |
Total span of the section calls |
musicalContext |
Optional tempo, time signature, and key |
globals |
Document-level flavor and level |
tracks |
Declared instruments and their defaults |
arrangement |
Section instances in order |
resources |
Referenced resources |
events |
Intent placed at musical positions |
The three versions change independently: a compiler update need not change the language or the JSON format.
Playback and context
playback is one of these objects:
[
{ "mode": "finite", "declaredBars": 4 },
{ "mode": "loop", "declaredBars": 4 },
{ "mode": "infinite" }
]Infinite playback has no bar count: the arrangement plays once, then holds its final state.
musicalContext can include:
{
"tempo": 88,
"timeSignature": { "beatsPerBar": 4, "beatUnit": 4 },
"key": "C major"
}Every field is optional. During playback, a missing tempo defaults to 120 and a missing time signature to 4/4; a missing key stays unspecified.
Tracks and arrangement
A track has an ID, name, description, and defaults:
{
"trackId": "track.piano",
"name": "piano",
"description": "Soft felt piano",
"defaults": []
}Each default has a defaultId, an action, and a value for flavor, timbre, notes, motif, or level.
Each section call has its own arrangement entry:
{
"sectionInstanceId": "section.intro.0",
"sectionName": "intro",
"callIndex": 0,
"start": { "bar": 1 },
"end": { "bar": 5 }
}end is exclusive, so this instance covers bars 1–4. A repeated call gets another instance with its own span.
Events and values
This event starts the piano at bar 1:
{
"eventId": "event.0000",
"type": "track",
"targetId": "track.piano",
"action": "play",
"position": { "bar": 1 },
"sequence": 0,
"scope": "timed",
"sectionInstanceId": "section.intro.0"
}Every event has an ID, a target, a position, a sequence, and a scope. sequence orders events on the same bar. A timed event lasts until something replaces it; a section event applies only inside its section instance.
Track play and stop events are always timed. Track events for flavor, timbre, notes, motif, or level carry a value. A section’s flavor has type: "section", action: "flavor", and scope: "section".
| Value kind | Shape |
|---|---|
text |
{ "kind": "text", "text": "..." } |
level |
{ "kind": "level", "value": 0.8 } |
alda |
{ "kind": "alda", "source": "..." } |
resource |
{ "kind": "resource", "resourceId": "..." } |
Alda notation stays as written. Converting it to notes or MIDI is up to whatever uses it.
Positions and provenance
A MusicalPosition has an absolute bar, counted from 1, and an optional beat.
A node can carry provenance that maps it back to the score:
{
"sourceRange": {
"start": { "line": 12, "character": 8 },
"end": { "line": 12, "character": 18 }
},
"sectionName": "intro",
"sectionInstanceId": "section.intro.0",
"callIndex": 0,
"sectionPosition": { "bar": 1 }
}Editors can use it to highlight the source behind an event. Playback ignores it.
Schema and validation
The types ship in @luna-estelar/gas/protocol. The individual gas-protocol package also includes schemas/1.0/timeline.schema.json and the session schemas. To check a timeline, use validateTimelinePayload from /protocol/validation, which runs without a schema compiler. session.loadTimeline validates before it loads.
The protocol source has the complete definitions.