NKM (File Format)
Introduction
NKM is a file format that describes objects, routes, cameras and other information about a course in Mario Kart DS and is the equivalent to Mario Kart Wii's KMP. The file is written in little endian.
Header
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x04 | String | File magic in ASCII (NKMD) |
0x04 | 0x02 | UInt16 | Version number. Final tracks are always 3.7 (0x25 = 37). Beta tracks are 3.0 (0x1E = 30), 3.2 (0x20 = 32) or 3.4 (0x22 = 34). The files written with MKDS Course Modifier 4.0 beta 10 are 4.0 (0x28 = 40), because of the additional information section |
0x06 | 0x02 | UInt16 | Header length |
0x08 | Header Length - 0x08 | UInt32[] | Section offsets. Not always the same amount. Some beta tracks are missing some sections |
Typical Header
A typical header is 0x4C long and has 17 sections.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x04 | String | File magic in ASCII (NKMD) |
0x04 | 0x02 | UInt16 | Version number |
0x06 | 0x02 | UInt16 | Header length |
0x08 | 0x04 | UInt32 | OBJI section offset |
0x0C | 0x04 | UInt32 | PATH section offset |
0x10 | 0x04 | UInt32 | POIT section offset |
0x14 | 0x04 | UInt32 | STAG section offset |
0x18 | 0x04 | UInt32 | KTPS section offset |
0x1C | 0x04 | UInt32 | KTPJ section offset |
0x20 | 0x04 | UInt32 | KTP2 section offset |
0x24 | 0x04 | UInt32 | KTPC section offset |
0x28 | 0x04 | UInt32 | KTPM section offset |
0x2C | 0x04 | UInt32 | CPOI section offset |
0x30 | 0x04 | UInt32 | CPAT section offset |
0x34 | 0x04 | UInt32 | IPOI section offset |
0x38 | 0x04 | UInt32 | IPAT section offset |
0x3C | 0x04 | UInt32 | EPOI section offset |
0x40 | 0x04 | UInt32 | EPAT section offset |
0x44 | 0x04 | UInt32 | AREA section offset |
0x48 | 0x04 | UInt32 | CAME section offset |
Sections
Section Header
Every sections except the STAG section starts with the section header. The section header is a 0x08 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x04 | String | Section magic in ASCII |
0x04 | 0x04 | UInt32 | Number of entries in section |
OBJI
The OBJI Section describes object used in tracks. Each entry is a 0x3C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector[1] | 3D position vector |
0x0C | 0x0C | Vector | 3D rotation vector |
0x18 | 0x0C | Vector | 3D scale vector |
0x24 | 0x20 | UInt16 | Object ID[2] |
0x26 | 0x02 | UInt16 | Route ID |
0x28 | 0x04 | UInt32 | Object setting 1 |
0x2C | 0x04 | UInt32 | Object setting 2 |
0x30 | 0x04 | UInt32 | Object setting 3 |
0x34 | 0x04 | UInt32 | Object setting 4 |
0x38 | 0x04 | UInt32 | Show in Time Trails. 1 if shown, 0 if not |
PATH
The PATH section describes paths used for objects and cameras. Each entry is a 0x04 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x01 | Byte | Route ID |
0x01 | 0x01 | Byte | 1 if the route loops, 0 otherwise |
0x02 | 0x02 | UInt16 | Nr points. The points are in the POIT section |
POIT
The POIT section describes points that is used by the PATH section. Each entry is a 0x14 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x02 | Int16 | Point index in the Route |
0x0E | 0x02 | Int16 | Point duration. Not always used |
0x10 | 0x04 | UInt32 | Unknown |
STAG
The STAG section describes global information about the track. It doesn't use the section header. The section is a 0x2C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x04 | String | Section magic in ASCII (STAG) |
0x04 | 0x02 | UInt16 | Track ID |
0x06 | 0x02 | UInt16 | Amount of laps |
0x08 | 0x0C | Byte[12] | Unknown 1 |
0x14 | 0x04 | UInt32 | Fog distance |
0x18 | 0x02 | GXRgb[3] | Fog color |
0x1A | 0x02 | UInt16 | Fog alpha (0-15) |
0x1C | 0x02 | GXRgb | KCL color 1, the default color |
0x1E | 0x02 | GXRgb | KCL color 2 |
0x20 | 0x02 | GXRgb | KCL color 3 |
0x22 | 0x02 | GXRgb | KCL color 4 |
0x24 | 0x08 | Byte[8] | Unknown 2 |
KTPS
The KTPS section describes start positions of racers. Each entry is a 0x1C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x0C | Vector | 3D rotation vector |
0x18 | 0x02 | UInt16 | Padding (0xFFFF) |
0x1A | 0x02 | Int16 | Start position index. Only used in battle stages and mission mode. For regular courses it is -1 |
KTPJ
The KTPJ section describes respawn positions. Each entry is a 0x20 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x0C | Vector | 3D rotation vector |
0x18 | 0x02 | Int16 | Enemy position ID (EPOI) |
0x1A | 0x02 | Int16 | Item position ID (IPOI) |
0x1C | 0x04 | Int32 | Respawn ID |
KTP2
The KTP2 section describes points you need to pass to let the lap count. Each entry is a 0x1C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x0C | Vector | 3D rotation vector |
0x18 | 0x02 | UInt16 | Padding (0xFFFF) |
0x1A | 0x02 | Int16 | Index. Always -1, because it's not used in battle stages. (If more than one works, it could be another value) |
KTPC
The KTPC section describes cannons (or pipe) destination points. Pipes do only work in battle mode by default. Each entry is a 0x1C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x0C | Vector | 3D rotation vector |
0x18 | 0x02 | UInt16 | Unknown |
0x1A | 0x02 | Int16 | Cannon index. Used for the 'Cannon Activator' collision type |
KTPM
The KTPM sections describes points that you need to pass to let a mission succeed. Each entry is a 0x1C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x0C | Vector | 3D rotation vector |
0x18 | 0x02 | UInt16 | Padding (0xFFFF) |
0x1A | 0x02 | Int16 | Index (last start position index + 1 is the first one) |
CPOI
The CPOI section describes check points. Each entry is a 0x24 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x04 | Vector | 2D position vector |
0x08 | 0x04 | Vector | 2D position vector |
0x10 | 0x04 | float | Sinus, it's sign has to be reversed sometimes[4] |
0x14 | 0x04 | float | Cosinus, it's sign has to be reversed sometimes[4] |
0x18 | 0x04 | float | Distance |
0x1C | 0x02 | Int16 | Section data 1. Has to do with different sections and such, but it is still very unknown[4] |
0x1E | 0x02 | Int16 | Section data 2. Has to do with different sections and such, but it is still very unknown[4] |
0x20 | 0x02 | Int16 | Keypoint ID. -1 if it is no key point |
0x22 | 0x01 | Byte | Respawn ID |
0x23 | 0x01 | Byte | Unknown |
CPAT
The CPAT section describes CPOI grouping. Each entry is a 0x0C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x02 | UInt16 | Point start |
0x02 | 0x02 | UInt16 | Point length |
0x04 | 0x03 | SByte[3] | Next group. The indicies of up to 3 the previous CPOI groups entries may have followed. Unneeded slots are set to value -1 |
0x07 | 0x03 | SByte[3] | Previous group. The indicies of up to 3 next CPOI group entries to follow. Unneeded slots are set to value -1 |
0x0A | 0x02 | Int16 | Section order |
IPOI
The IPOI section describes item points; the routes of items such as red shells. Each entry is a 0x14 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x04 | float | Point scale |
0x10 | 0x04 | UInt32 | Unknown |
IPAT
The IPAT section describes IPOI grouping. Each entry is a 0x0C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x02 | UInt16 | Point start |
0x02 | 0x02 | UInt16 | Point length |
0x04 | 0x03 | SByte[3] | Next group. The indicies of up to 3 the previous IPOI groups entries may have followed. Unneeded slots are set to value -1 |
0x07 | 0x03 | SByte[3] | Previous group. The indicies of up to 3 next IPOI group entries to follow. Unneeded slots are set to value -1 |
0x0A | 0x02 | Int16 | Section order |
EPOI
The EPOI section describes enemy points; the routes that the CPUs take. Each entry is a 0x18 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x04 | float | Point scale |
0x10 | 0x02 | Int16 | Drifting |
0x12 | 0x02 | UInt16 | Unknown |
0x14 | 0x04 | UInt32 | Unknown |
EPAT
The EPAT section describes EPOI grouping. Each entry is a 0x0C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x02 | UInt16 | Point start |
0x02 | 0x02 | UInt16 | Point length |
0x04 | 0x03 | SByte[3] | Next group. The indicies of up to 3 the previous EPOI groups entries may have followed. Unneeded slots are set to value -1 |
0x07 | 0x03 | SByte[3] | Previous group. The indicies of up to 3 next EPOI group entries to follow. Unneeded slots are set to value -1 |
0x0A | 0x02 | Int16 | Section order |
MEPO
The MEPO section describes minigame enemey points. Each entry is a 0x16 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x04 | float | Point scale |
0x10 | 0x02 | Int16 | Drifting |
0x12 | 0x04 | UInt32 | Unknown |
MEPA
The MEPA section describes MEPO grouping. Each entry is a 0x0C byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x02 | UInt16 | Point start |
0x02 | 0x02 | UInt16 | Point length |
0x04 | 0x03 | SByte[8] | Next group. The indicies of up to 8 the previous MEPO groups entries may have followed. Unneeded slots are set to value -1 |
0x07 | 0x03 | SByte[8] | Previous group. The indicies of up to 8 next MEPO group entries to follow. Unneeded slots are set to value -1 |
AREA
The AREA section describes areas, mosty used for determine which camera to use. Each entry is a 0x48 byte structure as follows.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector |
0x0C | 0x0C | Vector | 3D length vector |
0x18 | 0x0C | Vector | X-vector? |
0x24 | 0x0C | Vector | Y-vector? |
0x30 | 0x0C | Vector | Z-vector? |
0x3C | 0x02 | Int16 | Unknown |
0x3E | 0x02 | Int16 | Unknown |
0x40 | 0x02 | Int16 | Unknown |
0x42 | 0x01 | Byte | Unknown |
0x43 | 0x01 | SByte | Camera ID |
0x44 | 0x01 | Byte | Area type |
0x45 | 0x02 | UInt16 | Unknown |
0x47 | 0x01 | Byte | Unknown |
CAME
The CAME section describes cameras used in tracks. Each entry is a 0x4C byte structure as follows.
Offset | Size | Type | Description | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x00 | 0x0C | Vector | 3D position vector 1 | ||||||||||||||||||||
0x0C | 0x0C | Vector | 3D rotation vector | ||||||||||||||||||||
0x18 | 0x0C | Vector | 3D position vector 2 | ||||||||||||||||||||
0x24 | 0x0C | Vector | 3D position vector 3 | ||||||||||||||||||||
0x30 | 0x04 | UInt32 | Unknown | ||||||||||||||||||||
0x34 | 0x04 | UInt32 | Unknown | ||||||||||||||||||||
0x38 | 0x04 | UInt32 | Unknown | ||||||||||||||||||||
0x3C | 0x02 | Int16 | Camera zoom | ||||||||||||||||||||
0x3E | 0x02 | Int16 | Camera type
| ||||||||||||||||||||
0x40 | 0x02 | Int16 | Linked route (-1 if none) | ||||||||||||||||||||
0x42 | 0x02 | Int16 | Route speed | ||||||||||||||||||||
0x44 | 0x02 | Int16 | Point speed | ||||||||||||||||||||
0x46 | 0x02 | Int16 | Camera duration in 1/60 second units | ||||||||||||||||||||
0x48 | 0x02 | Int16 | Next camera (-1 if this is the last one) | ||||||||||||||||||||
0x4A | 0x01 | Byte | Intro pan first camera indicator (0x00 = none, 0x01 = top screen, 0x02 = bottom screen) | ||||||||||||||||||||
0x4B | 0x01 | Byte | Unknown (1 if camera type = 5) |
Special (additional) Sections
Since MKDS Course Modifier 4.0 beta 10, some additional information may be stored in the NKM file.
NKMI
The NKMI section describes some information about the track itself, like the name and the version etc. It doesn't use the section header. This section is never present in the header. This is because of compatibility reasons. (MKDS doesn't know that this section exists). StringNT means a null terminated string.
Offset | Size | Type | Description |
---|---|---|---|
0x00 | 0x04 | String | Section magic in ASCII (NKMI) |
0x04 | 0x04 | UInt32 | Section length |
0x08 | a | StringNT | Track name |
0x08 + a | b | StringNT | Author |
0x08 + a + b | c | StringNT | Version |
0x08 + a + b + c | d | StringNT | Last edit date. Format: dd/MM/yyyy HH:mm:ss (15/05/2013 16:18:04) |
Links
Tools
The following tools can handle Mario Kart DS NKM files: