.chart file and a .mid file that play the same have one TrackHash. This .chart file has one track, Expert guitar:
Its TrackHash is
JuNMNQmSSnOcJ5loj4W1niOlY9vU7MQZK-RtMemomls. A .mid file with the same note and a tempo of 499,999 microseconds a beat, which is 120.00024 BPM, has the same TrackHash, because the TrackHash rounds each tempo to a thousandth of a BPM: see TrackHash.
This page specifies version 20260801 of the file. The legacy TrackHash is the hash of an older version: see BTrack 20240320. The SongHash of a song holds the TrackHashes of all its tracks.
Which tracks have one
Each track has a BTrack: each instrument at each difficulty that holds at least one note. The instruments are:- 5-fret guitar, co-op guitar, rhythm guitar, bass and keys;
- 6-fret guitar, co-op guitar, rhythm guitar, bass and keys;
- drums.
- a section or difficulty without notes: see Tracks and Difficulties;
- vocals and harmonies;
- a second track for an instrument in a
.midfile, since the first counts; - tracks the format pages don’t cover, such as pro keys and pro guitar.
notes.chart and notes.mid uses notes.mid: see The chart.
The file
Every number is little-endian.- Required: the sections in ascending order of ID, in the map and in the data, each ID once.
- Required: offsets counted from the file’s first byte. The first section starts right after the map, each next section right after the one before, and the last section ends the file.
- Required: the Resolution section. Each other section is in the file only when it holds at least one record.
- IDs below 100 are kept for this specification. A program may add a section of its own with a higher ID. A reader skips the data of a section whose ID it doesn’t know, but checks its place in the map as for any other section.
Sections
The Resolution section holds the chart’s resolution, as an unsigned 32-bit number, and nothing else. Each other section holds a count, as an unsigned 32-bit number, then that many records:
Ticks, lengths, positions and sizes are signed 64-bit numbers. Numerators, denominators, note types and flags are unsigned 32-bit numbers. A section’s length in the map is exactly 4 bytes for its count, plus its records.
- Required: a resolution of at least 1.
- Required: every tick, length, position and size 0 or more.
- Required: a finite tempo greater than 0, and a numerator and denominator of at least 1.
- Required: records in ascending order of tick. Tempos, time signatures, star power phrases, solos and range shifts each have at most one record at a tick. Notes at one tick are in ascending order of note type, with at most one note of a type.
- Required: no star power phrase overlaps another, no solo overlaps another, and no note overlaps the next note of its type. Lanes may overlap.
- Required: at each tick, at most one single lane and one double lane, the single lane first.
- Required: a note in each star power phrase, solo and lane, as Star power and solos and Lanes say. A drum fill needs none.
- Required: a range shift’s position from 1 to 5, its size from 1 to 5, and the two adding up to no more than 6.
Note types and flags
Open is the open note of 5-fret and 6-fret. Black 1 to 3 and White 1 to 3 are the 6-fret frets, from the lowest.
A note’s flags are the sum of these values:
- Required: each flag only on the notes the table gives it.
- Required: at most one of strum, HOPO and tap; at most one of double kick, tom and cymbal; at most one of disco no-flip and disco; and at most one of ghost and accent.
- Required: exactly one of strum, HOPO and tap on each 5-fret and 6-fret note.
From a chart to a BTrack
A scanner reads the chart as the format pages say, and writes what it read. This section says which events fill each section, and the steps that apply to each.Resolution
The chart’s resolution:Resolution in a .chart file, or the header’s division in a .mid file.
Tempos and time signatures
Every tempo marker and time signature, from[SyncTrack] or the tempo track. Every track of a song holds the same ones.
- A tempo is in beats per minute, as a 64-bit float: a
.chartBvalue divided by 1000, or 60,000,000 divided by a.midtempo’s microseconds per beat. The division is done in 64-bit floating point and rounded to the nearest value, with no step through decimal text. - A time signature holds its denominator, not the power of 2 that a
.chartTSevent writes:TS 7 3is 7/8. - Of two tempo markers or two time signatures at one tick, the later one in the file counts.
- A chart without a tempo marker at tick 0 gets 120 BPM there, and one without a time signature at tick 0 gets 4/4, as The start of the chart says. So a scanner always writes both sections.
Star power and solos
Star power phrases areS 2 in a .chart file and note 116 in a .mid file, along with any solos read as star power. Solos are solo and soloend in a .chart file and note 103 in a .mid file. A .chart solo’s length is its soloend tick minus its solo tick, plus 1, so that it covers its soloend tick, as on Phrases.
For each, in this order:
- Of two phrases at one tick, the longer counts.
- When a phrase starts before an earlier one ends, the earlier one ends where the later one starts, and the later one ends where the later of the two ended.
- A phrase without a note is left out. A phrase holds a note when a note starts from its tick up to, but not including, its end tick. A phrase of length 0 holds the notes on its tick.
Lanes
Single lanes areS 65 in a .chart file and note 126 in a .mid file, and double lanes S 66 and note 127. A .mid lane’s velocity gives the difficulties it’s on: see Lanes.
- Of two lanes of one kind at one tick, the longer counts.
- A lane without a note is left out. A lane holds a note when a note starts from its tick through its end tick.
- Lanes that overlap stay as they are, even lanes of one kind.
Drum fills
Drum fills and Big Rock Endings areS 64 in a .chart file and note 120 in a .mid file. Every one goes in the BTrack as written, on every instrument: none is left out, and no step applies. A .mid fill goes in the BTrack of every difficulty.
The byte after a fill’s length is 1 when the fill starts at or after the first coda, which makes it a Big Rock Ending: see The coda and the .mid coda.
Range shifts
Every valid range shift of a 5-fret track, in.chart or .mid, with its position and size. A range shift without a size has the size of its difficulty.
- Of two range shifts at one tick, the later one in the file counts.
- A range shift that repeats the range before it stays.
- A track without range shifts has no Range shift section. The full range before the first one isn’t written.
Notes
The notes are those a player plays, after every step of How notes resolve, with the.mid rules of Note pairing and Note modifiers. So each note’s length is its sustain after the cutoff, two notes of one type are never at one tick, and no note overlaps the next one of its type.
- 5-fret: open, and green to orange. Each note has the strum, HOPO or tap flag it resolves to.
- 6-fret: open, and black 1 to 3 and white 1 to 3, with strum, HOPO or tap as on 5-fret. See 6-fret.
- Drums: as below.
A 5-lane chart’s notes are those a pro kit plays: see Playing one type on another kit. On top of the table:
- Disco and disco no-flip: on red and yellow drum notes during a disco flip, and the notes keep their written pads.
- Flam: on every drum note at a flam, kicks included.
- Accent and ghost: on pad notes, as Accents and ghosts says. Never on a kick, even when a
.midkick has the velocity of one. - A kick and a double kick at one tick are one note: the longer one, or the double kick when their lengths are equal.
What the TrackHash holds that games ignore
A BTrack holds every event above, including some that the format pages call ignored, or that no game plays. A change to any of them changes the TrackHash, and an exporter that drops one changes it too:- a drum fill or Big Rock Ending without a note, and a
.midfill on a difficulty where it covers no note; S 64on 5-fret before the coda, and note 120 there;S 64toS 66on 6-fret, and notes 120, 126 and 127 there;.chartlanes and Big Rock Endings on 5-fret, which no game plays;- each drum note’s length;
- a
.chartcymbal marker on a tick without its note, which still makes the chart pro; - double kicks on Easy, Medium and Hard;
- range shifts, which change no note.
S 67, notes 121 to 125, and modifiers and markers that apply to no note. Some song.ini keys change what a BTrack holds, because they change how the chart reads: hopo_frequency, eighthnote_hopo, sustain_cutoff_threshold, chord_snap_threshold, multiplier_note, pro_drums and five_lane_drums. The BTrack doesn’t hold the keys themselves.
TrackHash
A track’s TrackHash is calculated from its BTrack, and only from a valid one. It hashes the Resolution section and each of sections 2 to 9 that the file holds. The identifier, the version, the offsets, the lengths and any section of another ID aren’t hashed, so a later version of the file can keep every TrackHash.- Write the number of sections hashed, as an unsigned 32-bit number.
- Write each of their IDs, as an unsigned 64-bit number, in ascending order.
- Write each of their data, in the same order. In the Tempo section, round each tempo to the nearest thousandth of a BPM first:
floor(bpm × 1000 + 0.5) ÷ 1000, in 64-bit floating point. - Hash those bytes with BLAKE3, which gives 32 bytes.
- Write the 32 bytes in base64url without padding: base64, with
-for+and_for/, and no=at the end. A TrackHash has 43 characters.
.chart file stores tempos in thousandths of a BPM and a .mid file in microseconds a beat, so a chart converted between them keeps its tempos only to a thousandth of a BPM. Rounding lets it keep its TrackHash. A .chart tempo is already a whole number of thousandths, so rounding never changes one. A tempo exactly halfway rounds up: 307,200 microseconds a beat is 195.3125 BPM, which rounds to 195.313.
For the example at the top of the page, with the .mid file’s tempo of 120.00024 BPM rounded to 120, these 108 bytes are hashed:
JuNMNQmSSnOcJ5loj4W1niOlY9vU7MQZK-RtMemomls, for the .chart file and the .mid file alike. The two BTrack files are 164 bytes each, and differ only in the 8 bytes of the tempo.
scan-chart’s golden vectors test an implementation: charts with their BTracks and TrackHashes, song folders with their SongHashes, and BTrack files that a reader accepts or rejects. scan-chart passes all of them, and so does Clone Hero’s implementation of this version.
Edge case: other hashes of a BTrack. Clone Hero’s HashScanTool scan lists a BLAKE3 hash of the whole BTrack file for each track, which isn’t the TrackHash. Clone Hero’s leaderboards also record a hash of the song’s exact tempos and time signatures. The legacy TrackHash of Clone Hero 1.1 is on BTrack 20240320.
Invalid forms
A file that breaks a requirement
A file that breaks a requirement
A reader rejects the whole file: it reads nothing from it, and calculates no TrackHash. Clone Hero and scan-chart accept and reject the same files.
Another version, such as 20240320
Another version, such as 20240320
A reader of this version rejects the file. A reader that also reads BTrack 20240320 tells the two apart by the version, since both start with
CHNF.A section with no records
A section with no records
A reader rejects the file. A scanner leaves such a section out.
Two notes of one type at one tick, or other overlaps a scanner removes
Two notes of one type at one tick, or other overlaps a scanner removes
A reader rejects the file. A scanner never writes one, because How notes resolve and the steps above remove them first.