Music Composition
Overview
Ultima Online has always given players freedom to express themselves through their characters, homes, and stories. On Angel Island, musicians can also decorate the air with the custom Angel Island Music System (AIMS).
With AIMS, bards can play notes using the [play command, write arrangements in Razor, create sheet music, and share or sell compositions through the Music Box.
Getting Started
Anyone can use [play — no Musicianship or other skill is required. No physical instrument is required either: AIMS supplies a virtual harp, lap harp, or lute. Sound effects (the + numbers) require 1000 music karma; type [play musickarma to see yours.
The basic command is:
[play note pause note pause ...
For example:
[play cl 0.4 cl 0.4 g 0.4 g 0.4 a 0.4 a 0.4 g 0.8
Numbers represent pauses between notes, in seconds. Begin with the sample tunes below, then explore instrument choices, timing, and reusable passages.
Note Values
The 25 available note names are:
| Register | Notes |
|---|---|
| Low | cl (low C), csl (low C#) |
| Main | d, ds, e, f, fs, g, gs, a, as, b, c (middle C), cs |
| High | dh, dsh, eh, fh, fsh, gh, gsh, ah, ash, bh, ch (high C) |
Instruments and Note Offsets
AIMS has three virtual instruments in order: Harp (0), LapHarp (1), and Lute (2). Use [play instrument harp, [play instrument lapharp, or [play instrument lute to choose one. The default is Harp.
Prefix a note with + or - to select an adjacent instrument without changing the main instrument. For example, with LapHarp selected, -a plays on Harp, a on LapHarp, and +a on Lute.
[play instrument lapharp [play a +a -a b +b -b c +c -c d +d -d
From Harp, ++ selects Lute; from Lute, -- selects Harp:
[play instrument harp [play a +a ++a b +b ++b [play instrument lute [play a -a --a b -b --b
Composing, Recording and Sharing
Music Recorder
The Music Recorder captures a Razor performance into a composition book, making it easier to edit than pasting scripts manually.
- Enter [MusicRecorder start.
- Play your Razor script.
- Enter [MusicRecorder stop.
- Target a blank composition book.
A script might contain:
say '[play -e 0.21 -fs b +eh 0.22 -e +eh 0.21 -g b +eh 0.21' say '♪ Take my money,' wait 1400
The recorder captures [play and spoken lyrics, and estimates waits rounded down to the nearest 100 milliseconds. Review recorded waits before publishing. If waits are consistently excessive, try another client or assistant; Razor bundled with the Angel Island Launcher has generally been responsive.
Sheet Music
Sheet Music lets composers transcribe compositions into saleable sheet music. Creating sheet music is also the first step toward adding a song to the Music Box.
Music Box
The Music Box is a luxury music player for homeowners. It supports spoken commands and lets players sample, purchase, and enjoy compositions by other musicians.
Advanced Composition: Sections and Repeats
Sections and repeats let you write a musical passage once and reuse it throughout a composition. They are especially helpful for verses, choruses, accompaniment, and songs approaching the 100-page composition-book limit.
Section markers are comment lines in the composition book. Razor and ordinary [play commands ignore them, so the musical lines remain Razor-compatible. AIMS expands the arrangement before previewing or transcription.
Named Sections
A normal section plays where it is written. You can play it again later by name:
# Section: Chorus say '[play c 0.3 e 0.3 g 0.3 c 0.5' # End # Play: Chorus # Play: Chorus x3
Here the chorus plays once at its definition, once at the first # Play, and three more times at the second # Play.
Silent Sections
A silent section defines material without playing it at that location. It plays only when called:
# Silent Section: Chords say '[play -e -a -cs 0.44 -e -a -cs 0.28' say '[play -e -a csl 0.28 -ds -gs -b 0.29' # End # Play: Chords
Simple Repeats
Use a repeat when you do not need a reusable name:
# Repeat from here say '[play c 0.2 d 0.2 e 0.2 f 0.2' say '[play g 0.2 a 0.2 b 0.2 c 0.5' # Repeat x3
The count is the total number of performances, including the first. Thus x1 plays once, x2 twice, and x3 three times.
Syntax Reference
| Marker | Meaning |
|---|---|
| # Section: Name | Begins a named passage that plays here and may be called later. |
| # Silent Section: Name | Defines a passage that plays only when called. |
| # End | Closes the current section. |
| # End: Name | Closes the named section; mismatched names are errors. |
| # Play: Name | Plays a previously defined, closed section once. |
| # Play: Name x3 | Plays it three times here. |
| # Repeat from here | Marks the start of a repeat. |
| # Repeat x3 | Ends the repeat and plays its contents three times in total. |
Putting It Together
This example uses a silent accompaniment inside a verse and repeats the verse:
# Song: Example # Author: Galois # Instrument: LapHarp # Silent Section: Chords say '[play -e -a -cs 0.44 -e -a -cs 0.28' say '[play -e -a csl 0.28 -ds -gs -b 0.29' # End # Section: Verse say '[play -ds -b 0.14 fs 0.14 -fsh 0.14' # Play: Chords # End # Repeat from here # Play: Verse # Repeat x2 # Play: Chords x2
The verse plays once at its definition, twice more inside the repeat, and the chords play twice at the end.
For first and second endings, define the shared passage as a silent section, play it, write the first ending, play it again, and write the second ending:
# Silent Section: Theme say '[play c 0.3 e 0.3 g 0.3' # End # Play: Theme say '[play a 0.3 g 0.5' # Play: Theme say '[play f 0.3 c 0.5'
Rules and Limits
- Commands are case-insensitive, and spacing is flexible: #play:Chorus x2 and # Play: CHORUS both work.
- Section names may contain spaces, must be unique, and must not contain the word "loop".
- Define and close a section before using # Play on it.
- Sections and repeats may be nested, including sections that play other sections, up to eight levels deep.
- Repeat counts range from x1 to x99.
- Each marker must occupy its own line; do not append one to a say line.
- Unrecognized # lines remain comments, such as # Verse 1, # Play softly here, and # End of verse.
- Existing header settings such as # Song:, # Author:, and # Instrument: continue to work.
- A reused section includes all its contents: musical lines, waits, lyrics, and comments.
Preview Without Using Paper
To hear a composition before transcribing it:
- Enter [play preview.
- Target the composition book in your backpack.
- Enter [play preview again to stop.
Preview plays the expanded arrangement just as sheet music would, without consuming manuscript paper. While a preview is active, other [play commands explain how to stop it. On shards with book context menus, single-click the book and choose Start Preview; while playing, choose Stop Preview.
Transcribing and Troubleshooting
Transcription still works as before: double-click manuscript paper and target your composition book. AIMS expands sections and repeats into the full arrangement on the resulting sheet. The compact composition and the same music written out in full have the same song identity (hash). Older books without section markers continue to transcribe normally.
If AIMS finds a structural mistake, transcription stops without consuming the paper. Up to five errors appear in red, followed by a count of any remaining errors. Messages identify the page and line and may suggest a correction:
page 37: '# Play: Brige' - no section named "Brige" (did you mean "Bridge"?)
The checks include unknown or duplicate sections, missing or mismatched endings, unmatched repeats, sections played before being closed, self-references, invalid counts, malformed marker placement, and excessive nesting.
Player Settings and Commands
The [play command also configures instruments, timing, volume, and performance behavior.
[play Config
Displays the current player settings.
[play Instrument
Select Harp, LapHarp, or Lute. Default: Harp.
[play instrument harp [play instrument lapharp [play instrument lute
[play Timer
Choose Classic, Dynamic, or Anchored:
[play timer anchored
A composition book can also declare its timer in the header:
# Timer: Anchored
Classic
Classic is the original Angel Island timer (2006). It uses a fixed 100-millisecond tick. Notes written together play sequentially, giving a strummed rather than simultaneous-chord effect. Pauses are rounded to 100 milliseconds. Classic is suitable for simple melodies, manual play, and older compositions. It ignores Tempo and Prefetch.
[play timer classic # Timer: Classic
Dynamic
Dynamic (2022) schedules notes using millisecond-based delays, supporting true chords and more detailed rhythms. Tempo specifies the default spacing between successive notes in milliseconds (default 100). Prefetch controls how explicit pauses interact with that spacing: with Tempo 100 and a pause of 500 milliseconds, Prefetch False gives 600 milliseconds between notes, while Prefetch True gives 500.
# Timer: Dynamic # Prefetch: True # Tempo: 0
Because Dynamic schedules relative to the previous note's actual playback time, small delays can accumulate in longer pieces. Testing has shown drift approaching 10% in some cases.
Anchored
Anchored supports Dynamic-style chords, Tempo, and Prefetch, but schedules notes relative to the composition's start. This reduces accumulated timing drift. After a server interruption such as a world save, it adjusts its timing reference rather than releasing a burst of overdue notes. Anchored is a good choice for long, rhythmically complex pieces.
# Timer: Anchored # Prefetch: True # Tempo: 0
Existing Dynamic pieces can generally use Anchored without rewriting their notes or pauses.
Timing Mode Comparison
| Feature | Classic | Dynamic | Anchored |
|---|---|---|---|
| Resolution | 100 ms tick | Millisecond-based | Millisecond-based |
| True chords | No | Yes | Yes |
| Tempo / Prefetch | Ignored | Supported | Supported |
| Timing drift | Fixed-tick behavior | Can accumulate | Minimized |
| Best for | Simple and legacy music | Detailed arrangements | Detailed arrangements with stable tempo |
Compatibility
Legacy NewTimer settings remain supported:
# NewTimer: False # NewTimer: True [play newtimer false [play newtimer true
NewTimer False corresponds to Classic; NewTimer True corresponds to Dynamic. If both Timer and NewTimer headers are present, Timer wins. Without an explicit timer setting, songs default to Classic.
[play Prefetch
Use with Dynamic or Anchored (not Classic):
[play prefetch true
When enabled, an explicit pause replaces rather than adds to the default Tempo interval. Default: False. Older compositions may need pause adjustments when switching modes. See Advanced Usage.
[play Tempo
Tempo controls the default spacing between notes in milliseconds for Dynamic and Anchored.
[play tempo 100
At 50, the default interval is half as long as at 100; at 200 it is twice as long. Changing Tempo after composing may require adjusting explicit pauses. Default: 100.
[play Reset
Resets the player to its defaults: Harp, Classic (NewTimer False), Prefetch False, Tempo 100.
[play + (Sound Effects)
With at least 1,000 Music Karma, musicians can use sound IDs from the game client:
[play +480
Here +480 is the sound associated with targeting the Cure spell. See Sound List.
[play Chatter
[play chatter true
Enables or disables the *Plays a tune* emote. Default: False.
[play ConcertMode
[play ConcertMode True
Allows nearby listeners to hear the volume levels set by the musician regardless of distance. Default: False.
[FilterMusic
Toggles whether composition music plays on your client; it does not silence music for others.
[StopMusic
Stops your character's [play performance immediately.
Volume, Music Karma and Composer Titles
Volume
Place vN before a note or group of notes to change volume. The original examples demonstrate volume steps with macros:
[play macro part1=v0 1 a v1 1 a v2 1 a v3 1 a v4 1 a v5 1 a v6 1 a v7 1 a [play macro part2=v8 1 a v9 1 a v10 1 a v11 1 a v12 1 a v13 1 a v14 1 a v15 1 a v16 1 a [play macro part3=v17 1 a v18 1 a v19 1 a v20 1 a v21 1 a v22 1 a v23 1 a v24 1 a [play macro part4=v25 1 a v26 1 a v27 1 a v28 1 a v29 1 a v30 1 a v31 1 a v32 1 a [play %part1% %part2% %part3% %part4%
Enable [play ConcertMode True if you want other listeners to hear these volume differences; otherwise their playback uses the normal distance-based volume.
Music Karma
Musicians earn Music Karma through publishing and selling compositions. At 1,000 Music Karma, they may use non-musical sounds from the game client with [play. An approved composition added to the Music Box global repository earns 100 points, and each purchase earns another 100 points. See Sound List.
Composer Titles
Join the NPC Bards Guild to work toward the Composer profession title, progressing from Neophyte to Grandmaster. Progress comes from publishing, sales, plays, and use of [play, with bonuses for advanced features. [play usage counts only after joining the guild; publishing, plays, and sales before joining are credited when you join. Published works can also earn ordinary Karma and Fame.
Algebraic Macros
Macros let you name a note sequence, reuse it, transpose it, reverse it, or change its pauses. Unlike sections, macros transform note patterns; sections reuse complete passages, including waits and lyrics.
Defining and Playing a Macro
[play macro bassline = cl 0.2 e 0.2 g 0.2 a [play %bassline% [play instrument harp [play %bassline% 0.2 %bassline%
Transposing
[play %bassline[+5]%
This transposes five half-steps upward (a perfect fourth):
[play f 0.2 a 0.2 c 0.2 dh
Use [+n] or [-n]. Notes outside the supported cl-to-ch range are dropped.
Reversing
[play %-bassline%
This reverses the sequence:
[play a 0.2 g 0.2 e 0.2 cl
For example, a blues-style pattern can combine original and reversed macros:
[play %bassline% 0.2 as 0.2 %-bassline% [play %bassline% 0.2 as 0.2 %-bassline% [play %bassline[+5]% 0.2 dsh 0.2 %-bassline[+5]% [play %bassline% 0.2 as 0.2 %-bassline% [play %bassline[+7]% 0.2 %bassline[+5]% 0.2 [play %bassline% 0.2 as 0.2 %-bassline%
Changing Pauses
[play %bassline<+0.1>%
Adds 0.1 second to every pause, producing:
[play cl 0.3 e 0.3 g 0.3 a
The arithmetic operators can be combined with a macro:
| Expression | Resulting pauses |
|---|---|
| %bassline% | 0.2 |
| %bassline<+0.01>% | 0.21 |
| %bassline<-0.01>% | 0.19 |
| %bassline<*2>% | 0.4 |
| %bassline</2>% | 0.1 |
Combining Operations
Define minor and major arpeggios:
[play macro min = cl 0.1 ds 0.1 g 0.1 c [play macro maj = cl 0.1 e 0.1 g 0.1 c
Then transpose, reverse, and change their pacing in the same expression:
[play %min[+2]</2>% 0.2 %-min[+2]</2>% 0.8 [play %min[+2]</2>% 0.2 %-min[+2]</2>% 0.1 e 0.1 f 0.1 g 0.1 a 0.8 [play %maj[+5]</2>% 0.2 fh 0.05 eh 0.05 c 0.05 a 0.8 [play %min[+2]</2>% 0.2 %-min[+2]</2>% 0.8
Or a Pachelbel-inspired progression:
[play %maj[+12]<2>% 0.2 %maj[+7]<2>% 0.2 %min[+9]<2>% 0.2 %min[+4]<2>% 0.2 [play %maj[+5]<2>% 0.2 %maj<2>% 0.2 %maj[+5]<2>% 0.2 %maj[+7]<2>%
Many thanks to Galois for contributing the algebraic macros material.
Sample Tunes
Twinkle Twinkle Little Star
In Razor, add a two-second pause after the third line and a four-second pause before the last line.
[play cl 0.4 cl 0.4 g 0.4 g 0.4 a 0.4 a 0.4 g 0.8 [play f 0.4 f 0.4 e 0.4 e 0.4 d 0.4 d 0.4 cl 0.8 [play g 0.4 g 0.4 f 0.4 f 0.4 e 0.4 e 0.4 d 0.8 [play g 0.4 g 0.4 f 0.4 f 0.4 e 0.4 e 0.4 d 0.8 [play cl 0.4 cl 0.4 g 0.4 g 0.4 a 0.4 a 0.4 g 0.8 [play f 0.4 f 0.4 e 0.4 e 0.4 d 0.4 d 0.4 cl 0.8
Frère Jacques
In Razor, add a one-second pause between the second and third lines.
[play c 0.3 dh 0.3 eh 0.3 c 0.4 c 0.3 dh 0.3 eh 0.3 c 0.3 [play eh 0.3 fh 0.3 gh 1.0 eh 0.3 fh 0.3 gh 1.0 gh 0.1 ah 0.1 gh 0.1 fh 0.1 eh 0.3 c 0.3 [play gh 0.1 ah 0.1 gh 0.1 fh 0.1 eh 0.3 c 0.4 c 0.3 g 0.3 c 1.0 c 0.3 g 0.3 c
Pop Goes the Weasel
[play d 0.2 g 0.6 g 0.2 a 0.6 a 0.2 b 0.2 dh 0.2 b 0.2 g 0.6 [play d 0.2 g 0.6 g 0.2 a 0.6 c 0.2 b 0.8 g 0.6 [play d 0.2 g 0.6 g 0.2 a 0.6 a 0.2 b 0.2 dh 0.2 b 0.2 g 0.8 [play eh 0.8 a 0.4 c 0.2 b 0.8 g
Advanced Usage
The following technical observations and examples were contributed by Galois. They describe the behavior of the Dynamic/NewTimer system and are useful for understanding timing choices.
Understanding Prefetch and NewTimer
Consider:
[play cl 0.1 d 0.1 e
Tempo determines the default note spacing. Prefetch controls whether an explicit pause begins without adding the default delay. Thus you can play closely spaced notes with Prefetch enabled:
[play cl 0.01 d 0.01 e 0.01 f 0.01 g
With Prefetch disabled, negative pauses can also request prefetch-style spacing:
[play cl -0.01 d -0.01 e -0.01 f -0.01 g
These tools help tune precise rhythms such as three notes against two. If no pause is specified (for example, [play cl d e), Prefetch has no effect on that interval.
Repeating Notes
The client has a limitation when replaying the same sound file rapidly. A repeated note may be ignored while its previous sound is still playing. Sound durations vary by instrument; lute notes can generally be repeated faster than standing-harp notes. Switching instruments can sometimes help because the client then plays a different sound file, provided the desired note exists in both registers.
Using Multiple Instruments
This example combines a standing-harp accompaniment with lap-harp melody, inspired by Chariots of Fire:
say '[play newtimer true' say '[play prefetch false' say '[play tempo 90' say '[play instrument harp' say '[play csl 0.1 csl 0.1 csl 0.1 csl 0.1' wait 800 say '[play csl 0.1 csl 0.1 csl -0.01 +cs 0.1 csl 0.1' wait 800 # Note 3 against 2 rhythm say '[play csl -0.01 +fsh 0.08 csl -0.07 +gsh -0.15 csl -0.15 +ash -0.07 csl 0.1' wait 800 say '[play csl -0.01 +gsh 0.08 csl 0.1 csl 0.1 csl 0.1' wait 800 say '[play csl -0.01 +fh 0.08 csl 0.1 csl 0.1 csl 0.1'
Case Study: A Three-Over-Two Rhythm
Galois first chose Tempo 90 with 0.1-second pauses for the desired accompaniment feel. To estimate the effective timing interval, he compared:
[play cl 0.1 cl 0.1 cl 0.1 cl 0.1 g 0.3 g 0.3 cl 0.1 cl 0.1 cl 0.1 cl 0.1 g 0.3 g 0.3
With a more closely matched rhythm:
[play cl 0.1 cl 0.1 cl 0.1 cl 0.1 g 0.34 g 0.34 cl 0.1 cl 0.1 cl 0.1 cl 0.1 g 0.34 g 0.34
The timing relationship was:
2 * (0.01 + x + 0.1) = 0.01 + x + 0.34
This suggested an effective interval component of about 0.13 seconds at that tempo. Four eighth-note intervals then total:
4 * (0.01 + 0.13 + 0.10) = 0.96 seconds
Dividing this into three yields 0.32 seconds per triplet. The bassline falls at 0.00, 0.24, 0.48, 0.72, and 0.96 seconds, while the triplets fall at 0.00, 0.32, and 0.64 seconds.