Skip to main content
A .chart file is text, divided into named sections. Each section holds one entry per line:

Encoding

Recommended: UTF-8, with or without a byte order mark. A file may also be UTF-16 or UTF-32, with a byte order mark. A scanner decodes a file by its byte order mark. It checks the marks in this order, so a file that starts with FF FE 00 00 is UTF-32, not UTF-16: Required: after a byte order mark, text that is valid in that encoding. Required: no other byte order mark, such as UTF-7’s, 2B 2F 76. Edge case: ISO-8859-1 reads each byte as the character with the same number. Bytes 80 to 9F are control characters, not the characters Windows-1252 gives them, such as €.

Sections

A section is a name in square brackets on its own line, then a body between curly brackets, each on its own line:
  • The name is every character between [ and ], as written. Names are case-sensitive.
  • The { is alone on the line after the name.
  • The } is alone on the section’s last line, and is the section’s only }.
  • Between sections, a file holds only blank lines.

Section names

  • Events and the instrument sections follow SyncTrack, in any order.
  • Required: each section name once.

Lines

  • A line ends at a line feed, or at a carriage return followed by a line feed. A carriage return alone doesn’t end a line. Recommended: a carriage return and a line feed.
  • Recommended: each entry indented with two spaces, and no blank lines inside a section.
  • A .chart file has no comments.
Edge case: spaces and tabs. A scanner ignores spaces and tabs at the start and the end of every line, in every section, so 0 = TS 4 with a space at the end is 0 = TS 4. An exporter ends each line with its last value.

Events

Every entry of the SyncTrack, Events, and instrument sections is an event:
  • Tick: the position, written in the digits 0 to 9, without a sign.
  • Type: a code of one or two capital letters, such as N or TS.
  • Values: whole numbers in the digits 0 to 9, or one text value in an E event. Each type takes a set number of values, and an event has exactly that number. TS alone takes one or two: see Time signatures.
  • Spaces: exactly one space comes before and after the =, after the type, and between values.
  • Required: every event in exactly this form.
Each section holds only some types of event: Required: in SyncTrack and Events, only the types the table gives them. A scanner ignores a note or phrase value that has no meaning on its instrument, and an event of another type in an instrument section.

Tick order

Required: within a section, each event’s tick the same as the previous event’s or later:
Events at the same tick may be written in any order. Recommended: at one tick, notes, then phrases, then text events in an instrument section, and the time signature before the tempo marker in SyncTrack.

Named entries

Each entry of the Song section names a value:
  • The key is followed by exactly one space, =, and one space.
  • Required: each key once in the section.
  • Text values are written in quotation marks: Name = "Song Name". Numbers are written without them: Resolution = 192.
  • Required: every entry in exactly this form.
[Song] lists the keys. Edge case: white space in an entry. A scanner removes white space from both ends of the key and of the value, and from both ends of the text inside the quotation marks, so Name = " Song Name " is Song Name. White space is every character that .NET counts as white space, such as a tab or a no-break space, U+00A0, but not a byte order mark, U+FEFF.

Text

Text events are written differently in the two kinds of section:
  • In Events, the text is in quotation marks: 0 = E "section Intro".
  • In an instrument section, the text has no quotation marks: 768 = E solo.
A .chart file has no escape characters. Text can’t hold a line break, and a quotation mark inside the text is part of it. Required: no quotation marks around the text in an instrument section. Edge case: brackets in Events. A scanner removes spaces around the text, then one [ at its start and one ] at its end, so 0 = E "[section Intro]" means the same as 0 = E "section Intro". Older charts write the brackets. An exporter writes the text without them. A bracket anywhere else is part of the text, as in E "section Verse [2]".

Ignored

  • A tempo anchors in SyncTrack, such as 0 = A 0. Chart editors such as Moonscraper write them to hold a tempo marker at a time in the audio. Games ignore them. An exporter may keep them.
  • H events in Events, from older charts.
  • A section with any other name.

Invalid forms

Clone Hero refuses the file. A scanner that reads it reads each byte sequence that isn’t valid as the replacement character, U+FFFD, and takes no metadata from [Song], as scan-chart does. scan-chart keeps the bytes as they are when saving.
Clone Hero refuses the file. A scanner that reads it reads it as a file without a byte order mark, and takes no metadata from [Song], as scan-chart does.
Clone Hero refuses a file whose events go back in time in any section, and YARG’s song list refuses the file too. A scanner that reads it reads each section’s events in tick order, keeping the file’s order at one tick, as scan-chart does. YARG’s chart loader sorts the instrument sections, and drops each SyncTrack or Events line that goes back in time. scan-chart reports unsortedChartLines, and saving puts the lines in tick order.
Both games use the later one, and so does scan-chart. Saving removes the earlier one, which changes no hash.
A scanner reads the first section with each name, and ignores the rest, as scan-chart does. Clone Hero reads the first instrument section with that name, but joins every [Song], [SyncTrack] and [Events] section into one, and the last Resolution counts. YARG’s chart loader reads the first [Song] and [SyncTrack], and joins the [Events] sections and the instrument sections of one name. Saving with scan-chart removes the others.
A scanner reads the file with a resolution of 192, as it reads a [Song] section without Resolution. scan-chart’s saving adds a [Song] section with Resolution = 192.
A scanner refuses the file, as YARG’s chart loader and scan-chart do. From its code, Clone Hero plays the chart at 120 BPM in 4/4.
A scanner reads [Song] and [SyncTrack] wherever they are, and takes the song’s metadata from the file’s first section, whatever its name, as Clone Hero and scan-chart do. YARG’s chart loader refuses the file, and its song list reads [Song] only when the file starts with it. Saving with scan-chart puts them first.
Clone Hero refuses a file with one in SyncTrack or Events. A scanner that reads it ignores the event, as YARG and scan-chart do. scan-chart keeps it, and writes it back as it is.
Clone Hero, YARG and scan-chart read 768 = E "solo" as a solo. The same holds for soloend, mix and ld_range_shift events. scan-chart reports quotedChartTrackEvent, and saving removes the quotation marks.
Games read these differently, or not at all. A scanner reads such a line as Clone Hero does where Clone Hero loads the file, and otherwise by its probable meaning, as scan-chart does. Nonstandard files lists them. Saving with scan-chart writes the standard spelling.