song.ini is a text file of key = value lines in one [song] section:
Encoding
A scanner decodessong.ini as it decodes a .chart file: see Encoding. Recommended: UTF-8.
The [song] section
- Required: one
[song]section, on the file’s first line. Every key is inside it. - Required:
[song]alone on its line, with no spaces inside the brackets. - A scanner matches the section’s name in any letter case, as written between the brackets. Recommended:
[song], in lowercase.
Lines
Required: each line after[song] a key line, a comment, or a blank line.
- 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.
- A scanner ignores blank lines, and white space at the start and the end of each line.
- White space is a space, a tab, or another character that .NET counts as white space, such as a no-break space (U+00A0). A byte order mark (U+FEFF) isn’t white space.
Comments
;. It takes the whole line. A scanner ignores it.
Required: a comment on a line of its own.
Key lines
- The key is the text before the first
=. A scanner matches keys in any letter case. Recommended: in lowercase, as these pages write them. Required: a key without spaces, and a value that doesn’t start with=. - The value is the text after the
=, without the white space at its start and end. - Required: no quotation marks around a value.
- Required: no white space other than spaces and tabs at either end of a value.
- Recommended: one space on each side of the
=. - Required: each key once in a file.
- Required: keys and section names of at most 1,024 characters.
Key order
Recommended: the keys a song needs, in this order:name, artist, album, genre, year, charter, song_length, diff_band, diff_guitar, diff_guitar_coop, diff_rhythm, diff_bass, diff_drums, diff_drums_real, diff_keys, diff_keys_ghl, diff_guitarghl, diff_guitar_coop_ghl, diff_rhythm_ghl, diff_bassghl, diff_vocals, preview_start_time, preview_end_time, icon, loading_phrase, album_track, playlist_track, playlist, sub_playlist, modchart, explicit_lyrics, sustain_cutoff_threshold, chord_snap_threshold, video_start_time, five_lane_drums, pro_drums
- The keys only YARG reads go after
explicit_lyrics, in the order of Read by YARG only. - A deprecated key that an older chart still holds goes after them, before
sustain_cutoff_threshold, in the orderdelay,hopo_frequency,eighthnote_hopo,multiplier_note. - Other keys, such as
ignored_issues, come last. - The order doesn’t change how a scanner reads the file. It keeps files alike, so that each key is in the same place in every file.
- scan-chart writes keys in this order. It reports keys out of order as
iniTagOrder, with itsstyleNotesoption, andfixIssuesputs them in order.
Values
Each key takes one type of value:- No key takes a decimal number.
- Times are in milliseconds.
- A scanner also reads
trueandfalsein any other letter case, and1and0, as booleans. They mean the same asTrueandFalse. - Required: each value in the form of its key’s type.
Values that mean not set
A key that isn’t in the file isn’t set, and a scanner uses its default. Metadata and Settings give each key’s default. Required: a value in every key line, and no-1 in a number key. To leave a value unset, leave its key out.
In a text key, 0 and -1 are text: charter = 0 shows the charter as “0”.
Ignored
- Sections other than
[song]. An exporter may keep them. scan-chart reports one asiniLayout, andfixIssueskeeps its lines as;comments. - Keys a scanner doesn’t read. An exporter should keep them as written. Metadata lists the keys of older games.
Invalid forms
Lines before [song]
Lines before [song]
[song] section after them. scan-chart reports any line that isn’t blank before [song] as iniLayout, comments included, and fixIssues writes [song] on the first line, with the earlier lines kept as comments after it.No [song] section
No [song] section
song.ini: see Files in a song folder. A [song] section with no key lines counts as none. scan-chart reports it as invalidMetadata.Two [song] sections
Two [song] sections
iniLayout, and when its fixIssues lays out or orders the file, it merges them into one section.A section header with spaces or a comment, such as [ song ]
A section header with spaces or a comment, such as [ song ]
[ song ] or [song] ; comment as [song], so the key lines after it aren’t in a [song] section.A comment that starts with #
A comment that starts with #
#, which it doesn’t know, so it has no effect. A scanner ignores the line. scan-chart’s fixIssues rewrites it as a ; comment.A line that starts with //
A line that starts with //
=, and reads it as a key that no scanner knows when it has one. scan-chart reports a // line without = as badIniLine, and fixIssues rewrites any // line as a ; comment.A comment after a value, such as preview_start_time = 45500 ; ms
A comment after a value, such as preview_start_time = 45500 ; ms
A line without =
A line without =
name Song is name = Song. A scanner ignores the line. scan-chart reports it as badIniLine.A space inside a key, or a value that starts with =
A space inside a key, or a value that starts with =
diff guitar = 3 as a key named diff guitar, which no scanner knows, and name = = Song as the value = Song. YARG reads them as the key diff with the value guitar = 3, and as the value Song. A scanner reads them as Clone Hero does.A key or section name longer than 1,024 characters
A key or section name longer than 1,024 characters
song.ini: see Files in a song folder. YARG and scan-chart read the line as a key or section they don’t know. A scanner reads it as YARG and scan-chart do.A value that starts or ends with other white space, such as a no-break space
A value that starts or ends with other white space, such as a no-break space
Quotation marks around a value
Quotation marks around a value
.chart file, a scanner keeps them as part of the value, so a text value shows them. A scanner reads a number or boolean in quotation marks as not set, as Clone Hero and scan-chart do, and YARG reads 0. scan-chart reports quotation marks as quotedIniValue, and a quoted difficulty, such as diff_guitar = "4", also as missingValue. fixIssues removes the quotation marks around text, and leaves a quoted number or boolean for the charter to write as meant.A key written more than once
A key written more than once
duplicateIniKey, and saving an edited song removes the earlier lines.A number in another form, such as 1.5 or 12abc
A number in another form, such as 1.5 or 12abc
12abc is 12 and 1.5 is 1, and reads 0 when there are none. A scanner reads it as Clone Hero does. Clone Hero reads a delay with a decimal point as seconds instead: see Settings.scan-chart reads the leading number of most keys, so 12abc is 12, and rounds 1.5 to 2 and reports it as invalidValue. It reads hopo_frequency, multiplier_note, sustain_cutoff_threshold and chord_snap_threshold as Clone Hero does, and reports anything else as invalidValue.A boolean in another form, such as yes or 2
A boolean in another form, such as yes or 2
true or false as not set. YARG reads a value that starts with 1 or true as true, and anything else as false: 2 is false, and 10 is true. A scanner reads it as Clone Hero does.A blank value
A blank value
name is blank.YARG reads a blank number as 0 and a blank boolean as false, and counts the key as set: a blank preview_start_time starts the preview at 0:00, a blank album_track sorts the song first, a blank difficulty shows 0 instead of no rating, and a blank sustain_cutoff_threshold turns off the cutoff of a .mid file.A scanner reads a blank value as not set, as if the key weren’t in the file. A blank charter or album_track still counts as written, so a scanner doesn’t read frets or track instead: see Metadata. scan-chart reports a blank number as blankIniNumber, and blank text as blankIniValue with its styleNotes option. fixIssues removes the line.-1 in a number key, such as diff_keys = -1
-1 in a number key, such as diff_keys = -1
-1 in a difficulty, preview_start_time or preview_end_time as not set. In other number keys, Clone Hero and YARG read it as the number -1: album_track = -1 sorts the song first, and delay = -1 moves every note 1 millisecond earlier. scan-chart reads -1 as not set in every number key.A scanner reads -1 in a number key as not set, as if the key weren’t in the file. An album_track of -1 still counts as written, so a scanner doesn’t read track instead.When Clone Hero creates a song.ini for a folder without one, it writes -1 for each difficulty without a rating. Tens of thousands of song folders hold these values. scan-chart reports -1 as blankIniValue with its styleNotes option, and fixIssues removes the line.