Skip navigation

This post tries to describe the OJN format. This far from complete but we can already extract most of the good stuff from the file.


The OJN file is where all the notes are stored, including the meta-data of the music.
It’s basically divided in 3 parts: header, notes and cover section.


The header section is where all the song meta-data and offsets is stored.
meta-data consists in the song title, levels, genre, etc..
offsets are numbers used to know where to get the actual data.

In C struct notation, this is how the header looks like:

Note: For the sake of simplicity, consider “char” to be a byte(8 bits) long, “short” to be 2 bytes, “float”s and “int”s are 4 bytes. All in little endian order.

struct header {
int songid;
char signature[4];
float encode_version;
int genre;
float bpm;
short level[4];
int event_count[3];
int note_count[3];
int measure_count[3];
int package_count[3];
short old_encode_version;
short old_songid;
char old_genre[20];
int bmp_size;
int old_file_version;
char title[64];
char artist[32];
char noter[32];
char ojm_file[32];
int cover_size;
int time[3];
int note_offset[3];
int cover_offset;

You will see the word ‘usually’ a lot here, when I say ‘usually something is like X’ I mean that I observed it in most, if not all, of the official songs, but can’t say it will be always like that because anyone can change it to anything.

  • songid: the ID of the song, usually the same ID in the name of the file: o2ma[songid].ojn
  • signature: a magic number to identify the files, the content is ojn<null-byte>
  • encode_version: The OJN encode version, the value
    usually 2.9 (float).
  • genre: a code number representing the genre of the song as follows in the table:
    0 Ballad
    1 Rock
    2 Dance
    3 Techno
    4 Hip-hop
    5 Soul/R&B
    6 Jazz
    7 Funk
    8 Classical
    9 Traditional
    10 Etc
  • bpm: the song bpm. this is probably not related with the song actual bpm, ie. changing this field will not change the song speed.
  • level: 3 values representing respectively the easy, normal and hard levels of the song.
  • event_count: the number of events in the respective notes section.
  • note_count: the number of notes in each level(easy, normal, hard).
  • measure_count: the number of measures in each section.
  • package_count: the number of packages in each level section( more about packages in the below Notes section).
  • bmp_size: the size of the thumbnail image.
  • title: the title of the song.
  • artist: the artist of the song.
  • noter: the noter of the song.
  • ojm_file: the name of the OJM file with the sounds of this music, usually is the same name of this file but ending in ojm.
  • cover_size: this is the size of the cover image, in bytes.
  • time: this is the duration of each level in seconds.
  • note_offset: this 4 numbers are respectivly, the offset of the easy, normal, hard and cover section. these section are
    together, which means the normal offset is the end of the easy and the cover offset is the end of the hard section.
  • file_version: Version of the chart.
  • old variables:

    Looks like some variables survived old versions of the OJN format, these are:

  • old_encode_version: Looks like they used this as the version ? now superseded by the float encode_version.
  • old_songid: The old songid, I guess they changed because this is a short, int holds a lot more values.
  • old_genre: They used this to store the genre in string, but end up replacing it by the genre code. I guess.
  • Notes section


    Cover section

    At the cover_offset starts the cover image data, in JPEG format and with size cover_size from the header,
    also they usually have a 8×8 thumbnail image in BMP format right after this one, the size is also on the header in the bmp_size variable.

    I got some scripts I made to extract info from the files. take a look at open2jam on github

    If you see any errors in this post, or got any info that’s not already here, please, post in the comments. thank you.



    1. there is still something, the cells measurement. In the actual notechart creator (aka Notetool), you can set the measurement to 1/2 as example, leaving an empty gap before the next cell, which will cause the note reader to skip the gap and jump directly to the next head of the cell. I cant really explain it in detail as i do not have enough information to explain it yet. i hope this will help a little.

      • Yes, I noticed that in notetool, though I still don’t know where this is stored… I gonna try create some tests on notetool and see what happens. thanks.

      • I founded, although almost no song use this feature( and o2mania just ignores it!) it is used on Phase 1. I updated the notes section reflecting this.

    2. i have found out that it crashes converters too. By having a halved measure grid, the converter crashes and no result is produced. rofl

    3. Hello.

      I noticed you are missing the “jpeg offset” uint just after the note offsets.

      And also, “encode_value” is, at least in practice, fixed. But it also represents the OJN format version, represented as float (“2.9” is the actual value). This also explains why funny unk_id[0] is 29, although I don’t know why it exists, afterall. Go figure.

      And unk_zero[2] is the file version. I guess, theoretically, they thought about updating bogus notecharts.

      By the way, I see that you assume easy.note_offset_end to be normal.note_offset_start, but if it was always like that, there would be no note_offset[3]. Rather than assuming that, use package_count. That’s what it’s there for. Same thing for cover_offset, use the offset value (as I mentioned earlier) rather than assuming it’s right after the hard notes.

      • Hi, much thanks for the input Kishi.

        I updated the doc with the new info. I guess it’s very close to completion now T_T, if we don’t consider the newest o2china songs I guess..

    4. Just curious,
      any report on the new, encrypted OJNs?


    One Trackback/Pingback

    1. By The Notes section « open2jam on 15 Oct 2010 at 11:42 am

      […] AboutThe OJN Documentation « Hello world! You failed to me google […]

    Leave a Reply

    Fill in your details below or click an icon to log in: Logo

    You are commenting using your account. Log Out /  Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )


    Connecting to %s

    %d bloggers like this: