.osu is a human-readable file format containing information about a beatmap.
The first line of the file specifies the file format version. For example,
osu file format v14 is the latest version.
The following content is separated into sections, indicated by section titles in square brackets.
||General information about the beatmap||
||Saved settings for the beatmap editor||
||Information used to identify the beatmap||
||Beatmap and storyboard graphic events||Comma-separated lists|
||Timing and control points||Comma-separated lists|
||Combo and skin colours||
||Hit objects||Comma-separated lists|
|Option||Value type||Description||Default value|
||String||Location of the audio file relative to the current folder|
||Integer||Milliseconds of silence before the audio starts playing||0|
||Integer||Time in milliseconds when the audio preview should start||-1|
||Integer||Speed of the countdown before the first hit object (
||String||Sample set that will be used if timing points do not override it (
||Decimal||Multiplier for the threshold in time where hit objects placed close together stack (0–1)||0.7|
||Integer||Game mode (
||0 or 1||Whether or not breaks have a letterboxing effect||0|
||0 or 1||Deprecated||1|
||0 or 1||Whether or not the storyboard can use the user's skin images||0|
||0 or 1||Deprecated||0|
||String||Draw order of hit circle overlays compared to hit numbers (
||String||Preferred skin to use during gameplay|
||0 or 1||Whether or not a warning about flashing colours should be shown at the beginning of the map||0|
||Integer||Time in beats that the countdown starts before the first hit object||0|
||0 or 1||Whether or not the "N+1" style key layout is used for osu!mania||0|
||0 or 1||Whether or not the storyboard allows widescreen viewing||0|
||0 or 1||Whether or not sound samples will change rate when playing with speed-changing mods||0|
These options are only relevant when opening maps in the beatmap editor. They do not affect gameplay.
||Comma-separated list of integers||Time in milliseconds of bookmarks|
||Decimal||Distance snap multiplier|
||Integer||Beat snap divisor|
||Decimal||Scale factor for the object timeline|
||String||Romanised song title|
||String||Romanised song artist|
||String||Original media the song was produced for|
||Space-separated list of strings||Search terms|
||Decimal||HP setting (0–10)|
||Decimal||CS setting (0–10)|
||Decimal||OD setting (0–10)|
||Decimal||AR setting (0–10)|
||Decimal||Base slider velocity in hundreds of osu! pixels per beat|
||Decimal||Amount of slider ticks per beat|
eventType(String or Integer): Type of the event. Some events may be referred to by either a name or a number.
startTime(Integer): Start time of the event, in milliseconds from the beginning of the beatmap's audio. For events that do not use a start time, the default is
eventParams(Comma-separated list): Extra parameters specific to the event's type.
filename(String): Location of the background image relative to the beatmap directory. Double quotes are usually included surrounding the filename, but they are not required.
yOffset(Integer): Offset in osu! pixels from the centre of the screen. For example, an offset of
50,100would have the background shown 50 osu! pixels to the right and 100 osu! pixels down from the centre of the screen. If the offset is
0,0, writing it is optional.
Video may be replaced by
yOffset(Integer) behave exactly as in backgrounds.
2 may be replaced by
endTime(Integer): End time of the break, in milliseconds from the beginning of the beatmap's audio.
For information about storyboard syntax, see Storyboard Scripting.
Storyboards can be defined in a separate optional storyboard file with the
.osb extension. External storyboards are shared between all difficulties in a beatmap.
Each beatmap may contain its own difficulty-specific storyboard, either in conjunction with the external storyboard or by itself.
Each timing point influences a specified portion of the map, commonly called a "timing section". The
.osu file format requires these to be sorted in chronological order.
Timing point syntax:
time(Integer): Start time of the timing section, in milliseconds from the beginning of the beatmap's audio. The end of the timing section is the next timing point's time (or never, if this is the last timing point).
beatLength(Decimal): This property has two meanings:
-50would make all sliders in this timing section twice as fast as
meter(Integer): Amount of beats in a measure. Inherited timing points ignore this property.
sampleSet(Integer): Default sample set for hit objects (0 = beatmap default, 1 = normal, 2 = soft, 3 = drum).
sampleIndex(Integer): Custom sample index for hit objects.
0indicates osu!'s default hitsounds.
volume(Integer): Volume percentage for hit objects.
uninherited(0 or 1): Whether or not the timing point is uninherited.
effects(Integer): Bit flags that give the timing point extra effects. See the effects section.
Timing points have two extra effects that can be toggled using bits 0 and 3 (from least to most significant) in the
The rest of the bits are unused.
The first timing point at 10 seconds is uninherited, and sets:
1 / 333.33 * 1000 * 60)
The second timing point at 12 seconds is inherited, changing the slider velocity to 4x and the sample set to drum.
All options in this section represent colours. They are comma-separated triplets of integers 0–255, representing the red, green, and blue components of the colours.
||Additive combo colours|
||Additive slider track colour|
||Slider border colour|
Hit object syntax:
y(Integer): Position in osu! pixels of the object.
time(Integer): Time when the object is to be hit, in milliseconds from the beginning of the beatmap's audio.
type(Integer): Bit flags indicating the type of the object. See the type section.
hitSound(Integer): Bit flags indicating the hitsound applied to the object. See the hitsound section.
objectParams(Comma-separated list): Extra parameters specific to the object's type.
hitSample(Colon-separated list): Information about which samples are played when the object is hit. It is closely related to
hitSound; see the hitsounds section. If it is not written, it defaults to
The hit object's type parameter is an 8-bit integer where each bit is a flag with special meaning.
|0||Marks the object as a hit circle|
|1||Marks the object as a slider|
|2||Marks the start of a new combo|
|3||Marks the object as a spinner|
|4, 5, 6||A 3-bit integer specifying how many combo colours to skip, a practice referred to as "colour hax". Only relevant if the object starts a new combo.|
|7||Marks the object as an osu!mania hold note.|
hitSound bit flags determine which sounds will play when the object is hit:
If no bits are set, the normal hitsound is used by default.
In every mode except osu!mania, the
LayeredHitSounds skin property forces the normal sound to be included regardless of bit 0's setting. It is enabled by default.
hitSample can further customise the sounds that play. It defaults to
0:0:0:0: if it is not written.
Hit sample syntax:
normalSet(Integer): Sample set of the normal sound.
additionSet(Integer): Sample set of the whistle, finish, and clap sounds.
index(Integer): Index of the sample. If this is
0, the timing point's sample index will be used instead.
volume(Integer): Volume of the sample from 1 to 100. If this is
0, the timing point's volume will be used instead.
filename(String): Custom filename of the addition sound.
additionSet can be any of the following:
0: No custom sample set
1: Normal set
2: Soft set
3: Drum set
All of these options (besides volume) are used to determine which sound file to play for a given hitsound. The filename is
drum, determined by either
additionSetdepending on which hitsound is playing
indexis the same
indexas above, except it is not written if the value is
The sound file is loaded from the first of the following directories that contains a matching filename:
filename is given, no addition sounds will be played, and this file in the beatmap directory is played instead.
Hit circles do not have additional
curveType(Character): Type of curve used to construct this slider (
C= centripetal catmull-rom,
P= perfect circle)
curvePoints(Pipe-separated list of strings): Anchor points used to construct the slider. Each point is in the format
slides(Integer): Amount of times the player has to follow the slider's curve back-and-forth before the slider is complete. It can also be interpreted as the repeat count plus one.
length(Decimal): Visual length in osu! pixels of the slider.
edgeSounds(Pipe-separated list of integers): Hitsounds that play when hitting edges of the slider's curve. The first sound is the one that plays when the slider is first clicked, and the last sound is the one that plays when the slider's end is hit.
edgeSets(Pipe-separated list of strings): Sample sets used for the
edgeSounds. Each set is in the format
normalSet:additionSet, with the same meaning as in the hitsounds section.
When constructing curves for a slider,
y are used for the first point, and
curvePoints supply the rest.
There are four types of slider curves in osu!:
If the slider's
length is longer than the defined curve, the slider will extend until it reaches the target length:
Notice: The slider's
length can be used to determine the time it takes to complete the slider.
length / (SliderMultiplier * 100 * SV) * beatLength tells how many milliseconds it takes to complete one slide of the slider (where
SV is the slider velocity multiplier given by the effective inherited timing point, or
1 if there is none).
Apart from edge hitsounds, sliders also have an ongoing hitsound whenever the player is in range of the slider's follow circle. The sound file is looped for as long as it is active.
This hitsound uses the hit object's
hitSample properties, but only the normal and whistle sounds are supported. Its filename is
hitSound is either
slide for normal or
whistle for whistle.
endTime(Integer): End time of the spinner, in milliseconds from the beginning of the beatmap's audio.
ydo not affect spinners. They default to the centre of the playfield,
endTime(Integer): End time of the hold, in milliseconds from the beginning of the beatmap's audio.
xdetermines the index of the column that the hold will be in. It is computed by
floor(x * columnCount / 512)and clamped between
columnCount - 1.
ydoes not affect holds. It defaults to the centre of the playfield,
256,192,11000,21,2 256,192,11200,8,12,12000,3:0:0:80: 100,100,12600,6,1,B|200:200|250:200|250:200|300:150,2,310.123,2|1|2,0:0|0:0|0:2,0:0:0:0:
The first object is a hit circle:
The second object is a spinner:
The third object is a slider:
osu!taiko's hit objects only use
time to determine how they are placed on the play field, so
y are ignored. Likewise, the only significant part of slider curves is
curvePoints are only relevant when opening the map in the editor. Combo colours and new combos are ignored, and mode-specific hitsounds are used.
osu!catch's play field only uses the x-axis, so
y is not relevant. Slider curves may utilise vertical space to achieve horizontal acceleration when they are flattened to a one-dimensional play field.
Similarly to osu!catch, osu!mania hit objects do not use
x is used to determine the column; see the Holds section.