# Crash BASIC 1.51.0 Release Notes

*~written by Crash-tan~*

## YOUR MUSIC IS CODE NOW

Multi-track songs have always been something you made in the Music Editor and then played. Good songs, but finished ones — the program could start them, stop them, fade them, and that was the whole conversation.

Now a program can write a song, and rewrite it while it plays.

A `MUSIC` block lays a song out the way the editor does, in text you can read:

```basic
MUSIC "battle"
  TEMPO 140
  LOOP ON
  PATTERN "verse"
    TRACK CHANNEL(1) INSTRUMENT(12) VOLUME(80) NOTES "o4 c d e f"
    TRACK CHANNEL(10) VOLUME(90) REPEAT NOTES "c8 c8 r8 c8"
  END PATTERN
  ARRANGEMENT
    PLAY "verse" REPEAT 4
  END ARRANGEMENT
END MUSIC

PLAYMUSIC "battle"
```

A song, from nothing, with no `.cbm` file anywhere. Patterns hold tracks, each track is one part on one channel with its own instrument, volume and pan, and the arrangement plays those patterns in order — `REPEAT` to hold on one, `WITH` to layer several at once so a drum loop rides under a melody without merging into it.

The block edits as happily as it declares. Point it at a song your Music Editor made and it changes only what it mentions: a block that sets just `TEMPO` leaves every pattern and the whole arrangement exactly as you drew them. And running the same block twice is safe — re-declaring a pattern replaces its tracks rather than stacking a second copy on top, so a level restart can't quietly double every part.

## AND YOU CAN REACH INTO IT MID-GAME

Whole-song statements are for setting a scene. For reacting to one, there's a statement per property:

```basic
SET MUSIC "battle" TEMPO(160)
SET TRACK "battle", "verse", 1 VOLUME(20) PAN(-0.4)
MUTE TRACK "battle", "verse", 2
```

`SET TRACK` is a partial update, and that's the point — setting a volume leaves the notes, the instrument and the pan untouched. So you can build every layer of a song up front and bring them in as the game escalates: drums when combat starts, a counter-melody when the player is close to winning, the bass dropping out when they're nearly dead. `MUTE TRACK` silences a part without removing it, `SOLO TRACK` plays only what you've soloed, and both are readable so you never have to shadow your own mixer state in variables.

Patterns and arrangements are editable too — `CREATE MUSIC PATTERN`, `CREATE TRACK`, `ADD ARRANGEMENT`, `INSERT ARRANGEMENT`, `DELETE ARRANGEMENT` — and a family of queries reads the whole thing back: `MUSICTEMPO`, `TRACKCOUNT`, `TRACKNOTES$`, `ARRANGEMENTPATTERN$` and friends.

One thing to know: music is rendered ahead of being heard, so a change lands on the *next* `PLAYMUSIC` rather than reaching into a song already sounding. Set your layers, then start the track.

## MUSIC THAT WRITES ITSELF

This is the part I'm most pleased with. A track's notes can come from a function instead of a string:

```basic
SET TRACK "ambient", "drift", 0 GENERATOR "MakeArp"

FUNCTION MakeArp$(pattern$, track, repeat)
  DIM notes(4) AS STRING
  notes(0) = "c"
  notes(1) = "e"
  notes(2) = "g"
  notes(3) = "b"
  seq$ = "o4 "
  FOR i = 0 TO 15
    seq$ = seq$ + notes(INT(RND * 4)) + "16"
  NEXT
  RETURN seq$
END FUNCTION
```

You return MML — exactly what you'd have typed into `NOTES` — and the song plays it. The function runs once per arrangement repeat, every time the song starts. So `PLAY "chorus" REPEAT 4` gets four different passes instead of the same bar four times over, and starting the song again gets four new ones. Endless music that never quite repeats, from a dozen lines.

The `repeat` parameter is the pass number, which is where the musicality lives — check for the last time round and return a fill instead of the usual bar. You don't have to take all three parameters; a generator that ignores its context can be declared `FUNCTION Bass$()` and nothing else changes. `GENERATOR ""` hands the track back to written notes whenever you want it back.

## YOUR GAME STARTS FASTER

**Read this one if you ship music.** Turning a song into sound is the expensive part — for a dense song with sampled or wavetable instruments it can take seconds — and until now every game paid for its entire music bank at startup, whether it played a note of it or not. A big bank meant a long wait on a black screen before anything happened.

That doesn't happen any more. Loading a bank is now nearly instant, and the rendering happens when the music is actually needed.

Which means you decide where the wait goes:

```basic
LOADMUSIC SONG "battle"     ' render it now, behind your loading screen
PLAYMUSIC "battle"          ' instant
```

`LOADMUSIC` waits until the song is ready, so when it returns you know the music will start on time. Run it inside an `ASYNC` function and the rendering happens off to the side while your loading screen keeps drawing. Name a `.cbm` file to bring in a per-level bank — banks merge, so a level's music adds to what you already had rather than replacing it — and add `SONG` to pay for just the one song the next scene needs.

**Nothing breaks if you ignore all of this.** A song you never preload still plays; `PLAYMUSIC` renders it first. What changes is *when* you wait: your game now starts quickly and the first play of a heavy song may take a beat, where before the wait was at launch. If a song needs to start on a precise cue, `LOADMUSIC` it beforehand and it will.

## THE PLAYHEAD WORKS

`MUSICPOSITION()` and `MUSICLENGTH()` both used to answer 0, no matter what was playing. They answer properly now, both in ticks — four per beat — so they divide straight into each other:

```basic
total = MUSICLENGTH("battle")
IF total > 0 THEN progress = MUSICPOSITION() / total
```

Progress bars, cues timed to a point in the music, a boss arriving on the second chorus — all without keeping a second clock of your own and hoping it stays in step. A looping song's position cycles with the loop instead of counting up forever, a one-shot's runs on past the end of its music so you can time an outro, and a paused song holds still.

## A PAUSE NOW ACTUALLY PAUSES

Speaking of which: while music was paused, its clock kept running. Nothing was audible, but time was passing as far as the song was concerned — so `EVENTSON` cue points could fire during the pause, against music nobody heard, and be gone when playback resumed.

Paused music now consumes no song time at all. Cues wait where they are and fire when the music reaches them, however long you leave it. Pause a game mid-song, come back, and the music picks up exactly where it left off — cues included.
