Song Architecture
Song Class
TheSong class manages song data and metadata:
Unique song identifier (e.g., “tutorial”, “bopeebo”)
Display name shown to players
Artist credit
Person who created the chart
Current variation (e.g., “default”, “erect”)
Song Metadata Format
Song metadata is stored inassets/data/songs/[id]/[id]-metadata.json:
Metadata Fields
Metadata format version (currently “2.2.4”)
Display name of the song
Song artist name
Person who charted the song
Number of divisions per beat (used for chart precision)
Whether the song should loop
Time format:
"ms" (milliseconds), "ticks", or "float"Tool or person that generated this metadata
Time Changes
Songs can have multiple BPM and time signature changes:SongTimeChange Fields
Timestamp when the change occurs (in the format specified by
timeFormat)New BPM value (quarter notes per minute)
Time signature numerator (the ‘4’ in 4/4)
Time signature denominator (the ‘4’ in 4/4)
Beat time at this change (calculated automatically if not provided)
Beat tuplets - defines step subdivisions for each beat
Audio Offsets
Offsets compensate for timing discrepancies:Offset Fields
Offset for the main instrumental track (in milliseconds). Negative values start the track earlier.
Offsets for alternate instrumental tracks
Per-character vocal offsets (applied on top of instrumental offset)
- Negative offset: Audio starts earlier (compensates for delayed chart)
- Positive offset: Audio starts later (compensates for early chart)
- Vocal offsets are added to instrumental offset
- Instrumental starts 50ms early
- BF vocals start 40ms early (-50 + 10)
- Dad vocals start 50ms early (-50 + 0)
Play Data
TheplayData section contains gameplay-related metadata:
Play Data Fields
List of variations (e.g.,
["erect"]). Each variation has its own metadata file.Available difficulty levels for this song
Character IDs for player, opponent, and girlfriend
Stage ID to use for this song
Note skin/style ID
Difficulty ratings shown in freeplay (1-10 scale)
Album ID for freeplay display
Start time for audio preview in freeplay (milliseconds)
End time for audio preview in freeplay (milliseconds)
Character Data
Player character ID
Opponent character ID
Girlfriend character ID
Default instrumental track ID (empty string = default)
List of alternate instrumental IDs
Character IDs whose vocals are in the player track
Character IDs whose vocals are in the opponent track
Audio File Structure
Audio files are located inassets/songs/[id]/:
Required files:
Inst.ogg- Main instrumental trackVoices-Player.ogg- Player vocals (if song has vocals)Voices-Opponent.ogg- Opponent vocals (if song has vocals)
Inst-[altId].ogg- Alternate instrumental (e.g.,Inst-remix.ogg)
- Use
.oggformat (Vorbis codec) - Capitalize properly:
Inst.ogg, notinst.ogg - Alternate instrumentals:
Inst-[id].ogg - Character-specific vocals:
Voices-[charId].ogg
Vocal Tracks
Vocals can be split by character or combined: Split by role (recommended):Song Variations
Variations allow alternate versions of a song: Variation structure:- Separate metadata file
- Separate chart file
- Can have different BPM, characters, or stage
- Can share or have unique audio files
Time Formats
FNF supports three time formats:Milliseconds (Default)
Ticks
- 1 beat =
divisionsticks (typically 96) - Grid-aligned, prevents floating point errors
Float
Loading Songs
Songs are loaded viaSongRegistry:
Conductor Integration
Songs provide timing data to the Conductor:- Loads time changes from song metadata
- Calculates beat/step times based on BPM
- Fires timing signals (stepHit, beatHit, measureHit)
- Provides timing utilities for gameplay
