Difference between revisions of "RKG (File Format)"

From Custom Mario Kart
Jump to navigation Jump to search
(New information about format written up.)
(More detailed info about the format. The format of the data is still missing.)
Line 1: Line 1:
RKG is the format of ghost data. In a savefile all ghosts are saved in the rksys file. Staff ghosts are saved each in a rkg file on the disc.
+
'''RKG''' is the format of Time Trial '''ghost data'''. This format is common between ghosts saved in the saved file, staff ghosts and ghosts stored on Time Trial servers. In a savefile all ghosts are saved in the rksys file.
 +
 
 +
The file consists of a header describing the settings of the ghost such as vehicle and character, as well as the driver information such as the Mii, controller type and drift type. The header also contains metadata such as finishing time of the ghost. The main contents of the file is then the sequence of controller inputs made by the player, which can be used to replay the ghost. This may be compressed or raw. Following the ghost input data is a CRC-32 which the game uses to verify the file has not corrupted.
 +
 
 +
If the game is perfectly deterministic, the same controller inputs should always yield the same finishing time. In practice however, Mario Kart Wii is not quite able to recreate the circumstances in which the ghost was recorded leading to the rare [[Wiggler Glitch]]. This causes the ghost to descynchronise from the original Time Trial, often failing to finish.
 +
 
 +
== File Header ==
 +
 
 +
An '''RKG''' file begins with the 0x88 byte header.
  
 
{| class="wikitable"
 
{| class="wikitable"
 +
|+ Header of RKG file
 
|-
 
|-
 
! Offset
 
! Offset
! Type
+
! Size
 
! Description
 
! Description
 
|-
 
|-
| 0x00
+
| 0x00 || 4 || "'''RKGD'''" in ASCII; '''R'''evolution '''K'''art '''G'''host '''D'''ata file identifier.
| char[4]
 
| 'RKGD' in ASCII; File identifier
 
 
|-
 
|-
| 0x04
+
| 0x04 || 7 bits || '''Minutes''' field of finishing time.
| char[3]
 
| time (7 bits minutes, 7 bits seconds, 10 bits milliseconds)
 
 
|-
 
|-
| 0x07
+
| 0x04.7 || 7 bits || '''Seconds''' field of finishing time.
| char[1]
 
| track (important - determines on which slot it loads. Non-standard.)
 
 
|-
 
|-
| 0x08
+
| 0x05.6 || 10 bits || '''Milliseconds''' field of finishing time.
| char[1]
 
| vehicle
 
 
|-
 
|-
| 0x09
+
| 0x07 || 6 bits || '''[[Slot|Track ID]]'''.
| char[1]
 
| character
 
 
|-
 
|-
| 0x0A
+
| 0x07.6 || 2 bits || {{Unknown|'''Unknown'''. Probably padding.}}
| char[2]
 
| Unknown / Used controller?
 
 
|-
 
|-
| 0x0C
+
| 0x08 || 6 bits || '''Vehicle ID''' used by the ghost.
| char[2]
 
| A bitfield indicating ghost properties. 08 00 indicates compression. 00 04 for normal/your own ghost, 08 94 for staff ghost and 08 98 for expert ghost.  
 
 
|-
 
|-
| 0x0E
+
| 0x08.6 || 6 bits || '''Character ID''' used by the ghost.
| char[2]
 
| Decompressed input data length (from 0x88 onwards)
 
 
|-
 
|-
| 0x10
+
| 0x09.4 || 7 bits || '''Year''' that the ghost was set, stored relative to the year 2000.
| char[1]
 
| Lap count (tested with lap modifier)
 
 
|-
 
|-
| 0x11
+
| 0x0A.3 || 4 bits || '''Month''' that the ghost was set.
| char[3]
 
| 1st lap time
 
 
|-
 
|-
| 0x14
+
| 0x0A.7 || 5 bits || '''Day''' that the ghost was set.
| char[3]
 
| 2nd lap time
 
 
|-
 
|-
| 0x17
+
| 0x0B.4 || 4 bits || '''Controller ID'''; 0 for Wii Wheel, 1 for Wiiremote + Nunchuck, 2 for Classic controller, 3 for GabeCube controller.
| char[3]
 
| 3rd lap time
 
 
|-
 
|-
| 0x1A
+
| 0x0C || 4 bits || {{Unknown|'''Unknown'''. Always 0?}}
| char[3]
 
| 4th lap time
 
 
|-
 
|-
| 0x1D
+
| 0x0C.4 || 1 bit || '''Compressed''' flag; 1 for compressed, 0 for raw.
| char[3]
 
| 5th lap time
 
 
|-
 
|-
| 0x20
+
| 0x0C.5 || 2 bits || {{Unknown|'''Unknown'''. Always 0?}}
| char[20]
 
| padding / NOT 6th lap and so on.
 
 
|-
 
|-
| 0x34
+
| 0x0C.7 || 7 bits || '''Ghost type'''; 0x01 typical, 0x25 normal staff ghost, 0x26 expert staff ghost.
| char
 
| country (see http://wiibrew.org/wiki/Country_Codes)
 
 
|-
 
|-
| 0x35
+
| 0x0D.6 || 1 bit || '''Drift type'''; 1 for automatic, 0 for manual.
| char
 
| state (see [[MKWii_Network_Protocol/USER/State_codes]])
 
 
|-
 
|-
| 0x36
+
| 0x0D.7 || 1 bit || {{Unknown|'''Unknown'''. Probably padding.}}
| char[2]
 
| Unused - always 0x00
 
 
|-
 
|-
| 0x38
+
| 0x0E || 2 || '''Input data length''', measured when decompressed and without padding.
| char[2]
 
| Padding (00 00)
 
 
|-
 
|-
| 0x3C
+
| 0x10 || 1 || '''Lap count'''; total laps driven by ghost.
| char[4B]
 
| Driver's Mii Data
 
 
|-
 
|-
| 0x52
+
| 0x11 || 3 × 5 || Lap '''split''' times. Stored in the same 7 bit, 7 bit, 10 bit format as the finish time at offset 0x4. Unused split times are set to 0.
| char[1]
 
| country
 
 
|-
 
|-
| 0x88
+
| 0x20 || 0x14 || {{Unknown|'''Unknown''', probably unused. The game attempts to store lap splits beyond the 5th here, but the internal data structures do not store that many splits, so RAM trash is stored instead when the lap count is greater than 5 (notably the finish time in the 6th split).}}
| int
 
| Length of the Yaz1 data in bytes, if data is compressed. Start of input data if not.
 
 
|-
 
|-
| 0x8C
+
| 0x34 || 1 || '''[http://wiibrew.org/wiki/Country_Codes Country code]''' or 0xff if sharing location disabled.
| char
 
| The actual ghost controller input data. outside of the savegame it is compressed in [[Yaz0]] with Yaz1 as an file identifier.
 
 
|-
 
|-
|  
+
| 0x35 || 1 || '''[[MKWii_Network_Protocol/USER/State_codes|State code]]''' or 0xff if sharing location diabled.
| int
+
|-
| A CRC-32 Checksum of the whole file (excluding the last 4 bytes of course).
+
| 0x36 || 2 || {{unknown|'''Unknown'''. 0x0000 typically, 0xffff if sharing location disabled.}}
 +
|-
 +
| 0x38 || 4 || {{unknown|'''Unknown'''. 0x00000000 typically.}}
 +
|-
 +
| 0x3C || 0x4A || Driver's '''[http://wiibrew.org/wiki/Mii_Data#Mii_format Mii Data]'''.
 +
|-
 +
| 0x86 || 2 || [https://en.wikipedia.org/wiki/Cyclic_redundancy_check CRC16-CCITT] of Mii.
 +
|-
 +
| 0x88 || colspan=2 {{unknown|End of this header; start of data}}
 
|}
 
|}
  
The bytes 0x34 to 0x37 are set to 0xFFFFFFFF if the user who created that ghost data disabled sharing his country / location information.  
+
== Controller Input Data ==
 +
 
 +
The header is then followed by the input data. For compressed input data, the first 4 bytes are the length of the compressed data, followed by YAZ1 compressed data (including the YAZ1 header). The comrpessed data is always padded with zeros to a multiple of 4 bytes in length. Compressed data is used in the online rankings and in staff ghosts, uncompressed data is used in the save file. In a compressed ghost the compressed data (including YAZ1 header) must be less than or equal to 0x2774 bytes in length. For both compressed and uncompressed ghosts, the uncompressed input data must also be less than 0x2774 in length. In uncompressed files the input data is padded to exactly 0x2774 bytes in length. The length of the input data in the header always refers to the input data without padding.
 +
 
 +
== CRC ==
 +
Following the data is a [https://en.wikipedia.org/wiki/Cyclic_redundancy_check CRC-32] of the file up to that point. For compressed files, this is a CRC of the compressed data '''not''' the decompressed data.
  
 
[[category:File Format]]
 
[[category:File Format]]

Revision as of 15:26, 25 March 2016

RKG is the format of Time Trial ghost data. This format is common between ghosts saved in the saved file, staff ghosts and ghosts stored on Time Trial servers. In a savefile all ghosts are saved in the rksys file.

The file consists of a header describing the settings of the ghost such as vehicle and character, as well as the driver information such as the Mii, controller type and drift type. The header also contains metadata such as finishing time of the ghost. The main contents of the file is then the sequence of controller inputs made by the player, which can be used to replay the ghost. This may be compressed or raw. Following the ghost input data is a CRC-32 which the game uses to verify the file has not corrupted.

If the game is perfectly deterministic, the same controller inputs should always yield the same finishing time. In practice however, Mario Kart Wii is not quite able to recreate the circumstances in which the ghost was recorded leading to the rare Wiggler Glitch. This causes the ghost to descynchronise from the original Time Trial, often failing to finish.

File Header

An RKG file begins with the 0x88 byte header.

Header of RKG file
Offset Size Description
0x00 4 "RKGD" in ASCII; Revolution Kart Ghost Data file identifier.
0x04 7 bits Minutes field of finishing time.
0x04.7 7 bits Seconds field of finishing time.
0x05.6 10 bits Milliseconds field of finishing time.
0x07 6 bits Track ID.
0x07.6 2 bits Unknown. Probably padding.
0x08 6 bits Vehicle ID used by the ghost.
0x08.6 6 bits Character ID used by the ghost.
0x09.4 7 bits Year that the ghost was set, stored relative to the year 2000.
0x0A.3 4 bits Month that the ghost was set.
0x0A.7 5 bits Day that the ghost was set.
0x0B.4 4 bits Controller ID; 0 for Wii Wheel, 1 for Wiiremote + Nunchuck, 2 for Classic controller, 3 for GabeCube controller.
0x0C 4 bits Unknown. Always 0?
0x0C.4 1 bit Compressed flag; 1 for compressed, 0 for raw.
0x0C.5 2 bits Unknown. Always 0?
0x0C.7 7 bits Ghost type; 0x01 typical, 0x25 normal staff ghost, 0x26 expert staff ghost.
0x0D.6 1 bit Drift type; 1 for automatic, 0 for manual.
0x0D.7 1 bit Unknown. Probably padding.
0x0E 2 Input data length, measured when decompressed and without padding.
0x10 1 Lap count; total laps driven by ghost.
0x11 3 × 5 Lap split times. Stored in the same 7 bit, 7 bit, 10 bit format as the finish time at offset 0x4. Unused split times are set to 0.
0x20 0x14 Unknown, probably unused. The game attempts to store lap splits beyond the 5th here, but the internal data structures do not store that many splits, so RAM trash is stored instead when the lap count is greater than 5 (notably the finish time in the 6th split).
0x34 1 Country code or 0xff if sharing location disabled.
0x35 1 State code or 0xff if sharing location diabled.
0x36 2 Unknown. 0x0000 typically, 0xffff if sharing location disabled.
0x38 4 Unknown. 0x00000000 typically.
0x3C 0x4A Driver's Mii Data.
0x86 2 CRC16-CCITT of Mii.
0x88 End of this header; start of data

Controller Input Data

The header is then followed by the input data. For compressed input data, the first 4 bytes are the length of the compressed data, followed by YAZ1 compressed data (including the YAZ1 header). The comrpessed data is always padded with zeros to a multiple of 4 bytes in length. Compressed data is used in the online rankings and in staff ghosts, uncompressed data is used in the save file. In a compressed ghost the compressed data (including YAZ1 header) must be less than or equal to 0x2774 bytes in length. For both compressed and uncompressed ghosts, the uncompressed input data must also be less than 0x2774 in length. In uncompressed files the input data is padded to exactly 0x2774 bytes in length. The length of the input data in the header always refers to the input data without padding.

CRC

Following the data is a CRC-32 of the file up to that point. For compressed files, this is a CRC of the compressed data not the decompressed data.