> ## Documentation Index
> Fetch the complete documentation index at: https://chart-spec.enchor.us/llms.txt
> Use this file to discover all available pages before exploring further.

# Metadata

> The song.ini keys that describe a song and place it in the song list, and how to write each value.

These keys say what a song is, and how a scanner lists it:

```ini theme={null}
[song]
name = Song Name (ft. Guest Artist)
artist = Artist
album = Album Name
genre = Progressive Metal
year = 2004
charter = Charter A & Charter B
song_length = 243512
diff_band = 5
diff_guitar = 5
diff_bass = 4
diff_drums = 5
preview_start_time = 62000
preview_end_time = 92000
loading_phrase = Tempo map by Charter C
album_track = 7
```

[song.ini syntax](/ini/reading-rules) gives the forms of the values and the order of the keys. [Settings](/ini/settings) gives the keys that change how the song plays.

## Text values

Every text value follows one style, so that songs read alike in the song list and are easy to find:

* **No abbreviations,** unless the artist uses them. "ft." or "feat.", and "OST", are common exceptions.
* **Title Case:** every word capitalized except minor words, such as "the", "an", "a" and "of".
* **The artist's own styling:** unusual capitalization or styling of the words, such as `deadmau5`, only where the artist uses it. [Style tags](#style-tags) are a separate choice.
* **"and" and "&":** text the artist wrote keeps its "and". Where separate names are joined, such as two artists or two charters, use "&": `Charter A & Charter B`.
* **Spacing:** single spaces, and a space on each side of `&`, `/` and each title tag. A title tag is text after the song's name in parentheses or brackets, such as `(Live)`.
* **Romanized names:** a value in a language that is hard to type on an English keyboard may be written in its romanized form, so that players can search for it. The original may follow it in a title tag: `Gangnam Style (강남스타일)`.

Clone Hero and YARG sort and search without letter case, so Title Case changes only how a value looks.

With its `metadataStyle` option, scan-chart reports some values that may not follow this style. These are guesses, and can be wrong. It reports two spaces in a row as `textSpacing`, and a `charter` that joins names with something other than " & " as `creditSeparator`. The keys below name its other reports.

### Style tags

A text value may hold style tags, the rich-text tags of Unity's TextMesh Pro, such as `<b>` and `<color=#AEFFFF>`:

```ini theme={null}
charter = <color=#AEFFFF>Charter</color>
```

Clone Hero and YARG show the tags as formatting wherever they show the value:

| Key | Clone Hero shows it in | YARG shows it in |
| - | - | - |
| `name` | The song list, song details, the loading screen, the start of the song and the results | The song list, the song setup screen, the start of the song, the pause menu and the results |
| `artist` | The song list, in capitals, song details, the start of the song and the results | The same places as `name` |
| `album`, `genre` | Song details, and the headers of the album or genre sort | The same, and `album` also at the start of the song and in the pause menu |
| `year` | Song details | Song details and the start of the song, as the year's digits only |
| `charter` | Song details, the results, and the headers of the charter sort | Song details, the start of the song, and the headers of the charter sort |
| `loading_phrase` | The loading screen | The song setup screen |
| `playlist`, `sub_playlist` | The headers of the playlist sort, in lowercase | `playlist` only, in the headers of the playlist sort |

* Every tag works, including tags that change size and position, such as `<size>`, `<voffset>` and `<br>`, which can push text out of its space in the song list. In `loading_phrase`, YARG keeps only `<b>`, `<i>`, `<u>`, `<s>`, `<sub>`, `<sup>`, `<color>`, `<alpha>`, `<lowercase>`, `<uppercase>`, `<smallcaps>` and `<br>`.
* **Recommended:** colors as `#RRGGBB`. The games also read 22 color names, such as `lime`, except Clone Hero in `loading_phrase`, where only `black`, `blue`, `green`, `orange`, `purple`, `red`, `white` and `yellow` work.
* Tags in `charter` stop Clone Hero from finding an icon named after the charter: set [`icon`](#icon) instead.
* Clone Hero and YARG remove the tags from text they send out of the game, such as their Discord status.
* scan-chart keeps the tags, unless its `removeStyleTags` option is `true`. The [SongHash](/hashes/songhash#style-tags) ignores them.
* Both games ignore tags and letter case to sort and search. Clone Hero ignores any text between `<` and `>`, even when it isn't a tag, and both games show such text as written: `Song <Live>` shows its `<Live>`, but sorts as "Song", and a search for "live" doesn't find it in Clone Hero.

## The song

| Key | Value |
| - | - |
| `name` | The song's title. **Required** |
| `artist` | The song's artist(s) |
| `album` | The album the song is on |
| `genre` | The song's genre |
| `year` | The year the song's album was released, or for a live recording the year it was performed |
| `charter` | The names of the people who charted the song |

* **Recommended:** every key in the table. A scanner lists a song without `artist`, `album`, `genre`, `year` or `charter` with a placeholder, such as "Unknown Artist".
* A `.chart` file's `[Song]` section may repeat these keys: see [\[Song\]](/chart/song).
* scan-chart reports a missing `name`, `artist`, `album`, `genre`, `year` or `charter` as `missingValue`.

### name

* Several songs in one chart: their names separated by `/`, as in `Song A / Song B`.
* Featured artists: in a title tag that starts with "ft.", or with "feat." when the original title uses it: `Song Name (ft. Guest Artist)`. scan-chart reports a featured artist outside a title tag, in `name` or in `artist`, as `featuringFormat`.
* Title tags that are part of the song's name whatever the chart, such as "ft.", a remix or "Full Album", come first.
* Title tags that tell charts of one song apart, such as "Overchart", "6-Fret" or "Open Notes", come after every other title tag. scan-chart reports one that comes before a title tag of the song as `titleTagOrder`.
* **Recommended:** title tags in parentheses. Brackets are for a title tag that has a reason for them. scan-chart reports a title tag in brackets as `bracketTitleTag`.

### artist

* The song's artists, joined with "&" when they're separate names.
* A cover: the covering artist, with the covered artist in the song's name.
* A remix: the remixed artist, with the remixing artist in the song's name.

YARG also reads `covered_by`: see [Read by YARG only](#read-by-yarg-only).

### album

* A song with no album: the song's name, followed by ` - (Single)`: `Song Name - (Single)`. scan-chart reports a single's album written another way, such as `Single`, as `singleAlbum`.
* A live recording: the place where it was performed.
* A song on several albums: any of them, with the audio and the album art of the album named.

### genre

One genre, as specific as possible: "Complextro" rather than "Electronic". scan-chart reports a value that lists several, such as `Rock, Metal`, as `multipleGenres`.

### year

* Only the year, in four digits, without a month, a day or a time. scan-chart reports any other form as `yearFormat`.
* The year the album named in `album` was released. For a live recording, the year of the performance. Clone Hero's Artist - Album sort orders by artist, then year, then album, so one year for every song of an album keeps the album together.

**Edge case: a value with more than the year.** Clone Hero shows `year` as written, in song details and on the main menu, and sorts and groups songs by the smallest four-digit number in the value. YARG shows only the value's first run of four or more digits, or the whole value when it has none. So `year = , 2002`, with the `, ` that older charts write before `[Song]`'s `Year`, shows as ", 2002" in Clone Hero and as "2002" in YARG.

### charter

* The names of everyone who placed notes in the chart, joined with "&".
* Credit for other work, such as reviewing note placement, adding lyrics, tempo mapping or preparing the audio, may go in `loading_phrase` instead.
* When charters split the work by instrument or difficulty, each name may be followed by its part in parentheses: `Charter A (Guitar) & Charter B (Keys)`. A song with [part credits](#part-credits) doesn't need the parts in parentheses.
* Write `charter`, not `frets`: see [Deprecated](#deprecated).

`charter` is the song's one credit. Clone Hero and YARG show it and sort songs by it, and Clone Hero looks for an icon named after it.

### Part credits

A song may also name the charters of each part, in these keys:

| Key | Part |
| - | - |
| `charter_guitar` | Lead guitar |
| `charter_rhythm` | Rhythm guitar |
| `charter_bass` | Bass guitar |
| `charter_drums` | Drums |
| `charter_elite_drums` | YARG's elite drums |
| `charter_keys` | Keys |
| `charter_pro_guitar` | YARG's pro guitar |
| `charter_pro_bass` | YARG's pro bass |
| `charter_pro_keys` | YARG's pro keys |
| `charter_guitar_6f` | 6-fret guitar |
| `charter_rhythm_6f` | 6-fret rhythm guitar |
| `charter_bass_6f` | 6-fret bass |
| `charter_vocals` | Vocals |
| `charter_lower_diff` | The difficulties below Expert |
| `charter_venue` | The venue: YARG's lighting and camera cuts |
| `charter_audio` | The audio |

```ini theme={null}
charter = Charter A & Charter B
charter_guitar = Charter A
charter_drums = Charter B
charter_vocals = Charter A & Charter B
```

* Each value names the charters of its part, joined with " & ", in the style of `charter`.
* **Recommended:** `charter` names every charter in the part keys. An exporter that writes part keys writes `charter` from them: each name once, in the order of this table, joined with " & ".
* A game that shows one credit shows `charter`. A game that shows credits by part shows each part key that's set.
* YARG reads the part keys, and shows some of them in its credits menu, for songs from its own sources. Clone Hero doesn't read them.
* scan-chart reads them. With its `metadataStyle` option, it reports a name in a part key that `charter` doesn't hold, as `uncreditedPartCharter`.

## Difficulties

Each key is the difficulty of one instrument:

| Key | Instrument |
| - | - |
| `diff_band` | The whole song. A `.chart` file's `[Song]` section writes it as `Difficulty` |
| `diff_guitar` | Lead guitar |
| `diff_guitar_coop` | Co-op guitar |
| `diff_rhythm` | Rhythm guitar |
| `diff_bass` | Bass guitar |
| `diff_drums` | Drums |
| `diff_drums_real` | Pro drums. Clone Hero uses `diff_drums` when it isn't set |
| `diff_keys` | Keys |
| `diff_guitarghl` | 6-fret guitar |
| `diff_guitar_coop_ghl` | 6-fret co-op guitar |
| `diff_rhythm_ghl` | 6-fret rhythm guitar |
| `diff_bassghl` | 6-fret bass |
| `diff_keys_ghl` | 6-fret keys. YARG doesn't read it |
| `diff_vocals` | Vocals. Clone Hero doesn't read it |

* Each value is a whole number. **Recommended:** from 0 to 6, or up to 10 for a very hard chart. scan-chart reports a value outside 0 to 10 as `difficultyRange`.
* **Recommended:** a difficulty for every instrument the chart has, vocals included, and no key for an instrument it doesn't have.
* **Recommended:** `diff_band` when the chart has more than one instrument part, counting vocals. With one part, that part's difficulty is the song's.
* Clone Hero shows any value, with 7 and up as higher tiers. A difficulty that isn't set shows as `?`.
* scan-chart reports a missing difficulty of an instrument the chart has as `missingValue`, except `diff_band` and `diff_drums_real`. It reports a difficulty of an instrument the chart doesn't have as `extraValue`.

## The song list

| Key | Value |
| - | - |
| `song_length` | The length of the longest audio file other than `crowd` and `preview`, in milliseconds, rounded up. **Recommended** |
| `preview_start_time` | Where the song list's preview starts, in milliseconds |
| `preview_end_time` | Where the preview ends, in milliseconds |
| `album_track` | The song's position on its album, from 1 |
| `playlist_track` | The song's position in its playlist, from 1 |
| `playlist` and `sub_playlist` | The playlist Clone Hero lists the song under, and a playlist within it |
| `icon` | The name of a source icon, without its extension |
| `loading_phrase` | Text shown before the song starts |
| `modchart` | `True` for a modchart |
| `explicit_lyrics` | `True` when the lyrics are explicit |

### song\_length

* **Required:** when set, the length of the longest audio file other than `crowd` and `preview`, in milliseconds, rounded up.
* Clone Hero and YARG show `song_length` in the song list, and sort by it. Clone Hero also adds it up for a setlist and for its play-time statistic, writes it into a replay, and sends it to the leaderboard as the song's duration.
* Neither game uses it to decide when the song ends: a song plays until its audio and its last note have ended, or until a valid `end` event. See [The end of the song](/chart/events#the-end-of-the-song).
* When `song_length` is missing or 0, Clone Hero measures the audio, without `crowd`. When it can't, it takes the end of the last note, plus one beat. It writes the value it found into `song.ini`, except for a `.sng` file or an encrypted song, which it doesn't write to. YARG measures the audio when the value is 0 or less, and doesn't write it.
* scan-chart reports a missing `song_length` as `missingSongLength`. It reports a `song_length` shorter than where the chart's last note ends in the audio as `shortSongLength`, a warning, placing the chart by `delay`, or without one by the `.chart` file's `Offset`. With its `mediaIssues` option, it also reports a `song_length` more than a second away from the longest audio file's length as `songLengthMismatch`. `fixIssues` sets the value to that length.
* A `.chart` file's `[Song]` section may repeat it as `Length`, in seconds: see [\[Song\]](/chart/song).

### Previews

Clone Hero and YARG play the preview from `preview_start_time` to `preview_end_time`. With only one of them set, they play 30 seconds from the start, or the 30 seconds before the end. An end at or before the start counts as not set.

With neither set, the games differ. Clone Hero plays 30 seconds from 20 seconds in, or from the start when the audio is shorter than 20 seconds. YARG plays from 20 to 50 seconds, or the middle 30 seconds of audio shorter than 50 seconds, or the whole of audio shorter than 30 seconds.

* A `preview_end_time` of 0 means not set: a preview can't end at the start of the song.
* A `.chart` file's `[Song]` section may repeat both times: see [\[Song\]](/chart/song).

### album\_track and playlist\_track

Clone Hero sorts the songs of an album by `album_track`, and the songs of a playlist by `playlist_track`, then by name. A song without one comes last.

* **`album_track`:** **Recommended** for a song on an album, counting from 1. A single has none. Clone Hero writes `16000`, its default, when it creates a `song.ini`: leave the key out instead. scan-chart reports a missing `album_track` as `missingAlbumTrack`, unless the album marks a single.
* **`playlist_track`:** the chart's position in its setlist, counting from 1, only when it's in one. A setlist is any group of charts meant to be downloaded as one unit, such as all the charts of an official game, a chart pack, a full album or a discography.

### playlist and sub\_playlist

Clone Hero reads both in lowercase, and lists the song under `sub_playlist` within `playlist`. When they aren't set, it makes a playlist from the song's folder path. YARG reads only `playlist`. scan-chart reads both.

### icon

Clone Hero shows the icon with this name, in any letter case, from the icons that come with the game or are in its custom icons folder, not from the song folder. When `icon` isn't set, or names no icon, it looks for an icon named after the charter instead: the `charter` value in lowercase, with any style tags.

* The icon's name, without its extension: `icon = mysetlist`, not `mysetlist.png`. Icon names hold only lowercase letters, digits, `-` and `_`. scan-chart reports any other form as `iconName`, and `fixIssues` removes the extension and writes the name in lowercase.
* No `icon` when it would be the charter's name in lowercase and `charter` has no style tags: Clone Hero already looks for that icon.
* Icons come with the game, not with a chart: the [list of icons](https://clonehero.gitlab.io/sources/) gives their names. A new icon is added through the [sources repository](https://gitlab.com/clonehero/sources/).
* scan-chart reads `icon` in lowercase, and as not set when it's the charter's name.

### loading\_phrase

A phrase shown before the song starts: Clone Hero shows it on the loading screen, and YARG on the song setup screen. It may also credit work other than placing notes: see [charter](#charter).

### modchart

`True` for a modchart, and left out otherwise. Clone Hero's song list can filter by it. It has no effect on play, and YARG doesn't use it. `modchart = False` changes nothing: scan-chart reports it as `defaultIniValue` with its `styleNotes` option, and `fixIssues` removes it.

### explicit\_lyrics

`True` when the lyrics are explicit, and left out otherwise.

* Clone Hero shows an explicit-lyrics badge after the song's name in the song list when it's `True`. It shows `False` and no key alike, so `explicit_lyrics = False` changes nothing.
* Clone Hero's test builds from 1.1.0.5275 to 1.1.0.5684 checked each song without the key against a list of words, and wrote `True` or `False` into its `song.ini`. Other builds don't.
* YARG doesn't read `explicit_lyrics`. Its own key for this is `rating`: see [Read by YARG only](#read-by-yarg-only).
* scan-chart reads it. In every scan, it reports lyrics that hold a word from its list of strong profanities and slurs while `explicit_lyrics` isn't `True`, as `missingExplicitLyrics`, a recommendation. It checks English words only, so it can also report a name, or a word that means something else in another language. A word list can't show that lyrics are clean, so it never reports a `True`, and `fixIssues` doesn't change the key.
* **Recommended:** when the check reports lyrics that aren't explicit, list its code in [`ignored_issues`](#read-by-tools). This records that the charter has checked the lyrics. `explicit_lyrics = False` can't record it, since it means the same as no key: scan-chart's `fixIssues` removes a key that holds its default value.

## Read by YARG only

YARG reads more keys, which other games ignore. A song may hold them, and an exporter keeps them. scan-chart reads each as a metadata field, by the rules on [Syntax](/ini/reading-rules), so a blank number there is not set, where YARG reads 0. It reports `video_loop = False`, `rating = 0`, `clean_vocals = False` and `tuning_offset_cents = 0` as `defaultIniValue`, since each is the key's default:

| Keys | What they hold |
| - | - |
| `preview` | Both preview times, as `<start> <end>` in milliseconds, the form Phase Shift used. YARG uses it instead of `preview_start_time` and `preview_end_time` |
| `video_end_time` and `video_loop` | Where the background video ends, and whether it loops |
| `background`, `video` and `cover` | The file names of the background image, video and album art to use |
| `rating` | The song's age rating: `1` Family Friendly, `2` Supervision Recommended, `3` Mature, `4` No Rating, `5` Sensitive Content. `0` is not set |
| `tags` | `cover` marks the song as a cover, not the original recording |
| `diff_vocals_harm`, `diff_guitar_real`, `diff_guitar_real_22`, `diff_bass_real`, `diff_bass_real_22`, `diff_keys_real` and `diff_elite_drums` | The difficulties of YARG's other instruments |
| `sub_genre`, `covered_by`, `date_released` and `location` | More about the song. `date_released` is `yyyy-MM-dd` or `yyyy-MM` |
| `credit_album_art_designed_by`, `credit_arranged_by`, `credit_background`, `credit_composed_by`, `credit_courtesy_of`, `credit_engineered_by`, `credit_license`, `credit_mastered_by`, `credit_mixed_by`, `credit_other`, `credit_performed_by`, `credit_produced_by`, `credit_published_by` and `credit_written_by`, and the `charter_` keys of [Part credits](#part-credits) | Credits for the song, its recording and its art, and the charters of each part |
| `link_bandcamp`, `link_bluesky`, `link_facebook`, `link_instagram`, `link_spotify`, `link_twitter`, `link_other` and `link_youtube` | Links |
| `vocal_gender`, `vocal_scroll_speed`, `clean_vocals`, `venue_hint`, `vocal_character_hint` and `tuning_offset_cents` | The vocals and the venue |

YARG also reads `credit_album_art_by` and `credit_album_cover` as `credit_album_art_designed_by`, and uses whichever of the three lines comes last. **Recommended:** `credit_album_art_designed_by`.

scan-chart reads these keys too, as fields of its metadata beside the keys above, by the rules of [Syntax](/ini/reading-rules), and reads the two other names of `credit_album_art_designed_by` as YARG does.

## Read by tools

| Key | What it holds |
| - | - |
| `ignored_issues` | Issue codes a tool such as scan-chart doesn't report for this song, separated by commas: `ignored_issues = isDefaultBPM, discouragedAudio`. A charter writes it to keep a recommendation or warning they've chosen not to follow out of the issue list, such as the warning for a tempo map left at 120 BPM in a song that is at 120 BPM throughout, or for an intended `preview` audio file. Games ignore it |

**Edge case:** an issue that means games read the file differently can't be ignored: scan-chart reports such a code, and an unknown code, in `ignored_issues` itself.

## Deprecated

* **`frets`**, an older name for `charter`. A scanner reads it only when there's no `charter` line. Write `charter` instead. `frets = 0`, common in older files, shows the charter as "0" when there's no `charter` line.
* **`track`**, an older name for `album_track`. Clone Hero reads it only when there's no `album_track` line, and YARG uses whichever of the two comes later in the file. Write `album_track` instead.

scan-chart's `fixIssues`, and its saving of an edited song, rename `frets` to `charter`, and `track` to `album_track`.

## Ignored

* **Keys of older games and tools** that no scanner acts on, such as `lyrics`, `version`, `count`, `tutorial`, `unlock_` keys, `cassettecolor`, `boss_battle`, `scores`, `scores_ext`, `early_hit_window_size`, `link_name_a`, `banner_link_a`, `sysex_` keys, `drum_fallback_blue`, `_type` keys such as `guitar_type`, `diff_drums_real_ps`, `diff_keys_real_ps`, `diff_dance`, `real_keys_lane_count_left`, `real_keys_lane_count_right`, the tunings `real_guitar_tuning`, `real_guitar_22_tuning`, `real_bass_tuning` and `real_bass_22_tuning`, and Editor on Fire's `eof_midi_import_` keys. YARG reads some of them, but nothing uses them. An exporter may keep them.
* **`diff_coop`, `diff_coopghl` and `diff_rhythmghl`,** names from one Clone Hero test build. No game reads them: write `diff_guitar_coop`, `diff_guitar_coop_ghl` and `diff_rhythm_ghl` instead.
* **`md5_hash`,** which only a Clone Hero tool reads, when it builds Clone Hero's encrypted song packs. It has no effect in a song folder.

## Invalid forms

<Accordion title="No name, or a blank one">
  Clone Hero doesn't list the song. YARG shows a blank `name` as "Unknown Name", and doesn't list a song with no `name` line. scan-chart shows "Unknown Name", and reports it as `missingValue`. A scanner's SongHash holds `Unknown Name`, as Clone Hero's HashScanTool and scan-chart calculate it: see [SongHash](/hashes/songhash#metadata).
</Accordion>

<Accordion title="A blank charter or album_track, or album_track = -1, with frets or track">
  Clone Hero uses the main key whenever it's in the file: a blank `charter` shows as "Unknown Charter", a blank `album_track` sorts the song last, and `album_track = -1` sorts it first. YARG does the same for `charter`, and for `album_track` and `track` uses whichever line comes later. A scanner reads the main key as not set, and doesn't read `frets` or `track`. scan-chart reports the main key's value as [a blank value or -1](/ini/reading-rules#invalid-forms).
</Accordion>

<Accordion title="A song_length that isn't the audio's length">
  Clone Hero measures the audio only when `song_length` is missing or 0, and YARG only when it's 0 or less, so both show the wrong length, and Clone Hero sends it to the leaderboard. scan-chart reports a `song_length` shorter than the end of the last note as `shortSongLength`. With its `mediaIssues` option, it reports one more than a second away from the longest audio file's length as `songLengthMismatch`, and `fixIssues` sets it to that length.
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.