Difference between revisions of "Ghost Data (File Format)"

From MK8
Jump to navigation Jump to search
(driver data, race settings, yaz0/replay data (WIP))
(Added replay data info; updated or cleaned up other sections)
Line 2: Line 2:
 
{{textbox|center white|Platform Notice|This article is about [[Mario Kart 8]] for [[Wii U]]. [[Mario Kart 8 Deluxe]] uses a similar file format, but that is still a WIP and the offsets are different.}}
 
{{textbox|center white|Platform Notice|This article is about [[Mario Kart 8]] for [[Wii U]]. [[Mario Kart 8 Deluxe]] uses a similar file format, but that is still a WIP and the offsets are different.}}
  
In [[Mario Kart 8]], Ghost Data is stored in ''[[DAT (File Format)|DAT]]''-files. This includes player ghosts, staff ghosts, and downloaded ghosts. [[MKTV Replay (File Format)|MKTV replays]] have a similar file format. Each Ghost is stored in a separate DAT-file.
+
In [[Mario Kart 8]], Ghost Data is stored in ''[[DAT (File Format)|DAT]]''-files. This includes player ghosts, staff ghosts, and downloaded ghosts ("time trial ghosts" in short). [[MKTV Replay (File Format)|MKTV replays]] have a similar file format, and relics of such replays are thus present in time trial ghost data. Each ghost is stored in a separate DAT-file.
  
 
Player Ghosts, Downloaded Ghosts, and MKTV Replays are stored in the user's save folder. Staff Ghosts are stored among the [[Filesystem/Wii U/content/ghost/slow|game files]].
 
Player Ghosts, Downloaded Ghosts, and MKTV Replays are stored in the user's save folder. Staff Ghosts are stored among the [[Filesystem/Wii U/content/ghost/slow|game files]].
Line 10: Line 10:
 
In [[:mkw:RKG (File Format)|Mario Kart Wii]], as well as earlier titles, ghost files most notably store controller inputs. When a ghost is viewed, the game replays these controller inputs. 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 [[:mkw:Wiggler Glitch|Wiggler Glitch]]. This causes the ghost to descynchronise from the original Time Trial, often failing to finish.
 
In [[:mkw:RKG (File Format)|Mario Kart Wii]], as well as earlier titles, ghost files most notably store controller inputs. When a ghost is viewed, the game replays these controller inputs. 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 [[:mkw:Wiggler Glitch|Wiggler Glitch]]. This causes the ghost to descynchronise from the original Time Trial, often failing to finish.
  
In [[Mario Kart 8]], this is different. Ghost files must also contain kart positions in some form, possibly in addition to controller inputs (unknown). In practise, this means that a ghost is always able to finish a race in the exact same way as it was recorded in. This can be verified by replacing the file contents of a ghost file with that of another. When doing so, the ghost will ignore any collisions of the track (e.g. drive through walls) and follow the layout of the course it was initially recorded in.
+
In [[Mario Kart 8]], this is different. Ghost files also contain kart positions in some form in addition to controller inputs. In practise, this means that a ghost is always able to finish a race in the exact same way (give or take) as it was recorded in. This can be verified by replacing the file contents of a ghost file with that of another. When doing so, the ghost will ignore any collisions of the track (e.g. drive through walls) and follow the layout of the course it was initially recorded in.
 
<!-- Would be nice to add a video showcasing this -->
 
<!-- Would be nice to add a video showcasing this -->
  
As a result, this means that the [[:mkw:Wiggler Glitch|Wiggler Glitch]] cannot occur in [[Mario Kart 8]].
+
As a result, the [[:mkw:Wiggler Glitch|Wiggler Glitch]] cannot occur in [[Mario Kart 8]].
 +
 
 +
The relation to [[Mario Kart 7]] ghosts is currently unknown. <!-- Help is welcome -->
  
 
= Filename =
 
= Filename =
Some ghost data information is encoded into the filename of the ghost file. The first two characters indicate what type of ghost data is inside the file. The remaining characters should be interpreted as hexadecimal values.
+
Some ghost data information is encoded into the filename of the ghost file. The first two characters indicate what type of ghost data is inside the file. The remaining characters should be interpreted as hexadecimal values. The tables below assumes the characters are parsed as hex values.
 +
 
 +
== Timestamp ==
 +
Several timestamps are encoded in a ghost's filename. These all have an identical format. These offsets are relative to the start of the timestamp data. Examples of timestamps are the total time and lap splits.
 +
 
 +
{| class="wikitable"
 +
|+ Timestamp
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0 || 1 || '''Minutes'''.
 +
|-
 +
| 1 || 2 || '''Seconds'''.
 +
|-
 +
| 3 || 3 || '''Milliseconds'''.
 +
|-
 +
| 6 || colspan=2 {{unknown|End of timestamp}}
 +
|}
 +
 
 +
A timestamp of <i>9:59:999</i> is thus represented as <i>9 3b 3e7</i> (spaces added for clarity).
  
<!-- Offsets and size are a bit weird, since the filename's characters should be interpreted as HEX values. A better formatting for this table would be nice, as the current way feels a bit off. -->
+
== Data ==
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ Ghost Data Filename
 
|+ Ghost Data Filename
 
|-
 
|-
! Offset (#characters)
+
! Offset
! Size (#characters)
+
! Size
 
! Description
 
! Description
 
|-
 
|-
| 0 || 2 || '''Ghost Type'''. "sg" for Staff Ghost, "gs" for Player Ghost (possibly a shorthand for "ghost save"), "dg" for Downloaded Ghost, "rp" for MKTV Replay.
+
| 0 || 2 || '''Ghost Type'''. "sg" for Staff Ghost, "gs" for Player Ghost (possibly a shorthand for "ghost save"), "dg" for Downloaded Ghost, "rp" for [[MKTV Replay (File Format)|MKTV Replay]].
 
|-
 
|-
 
| 2 || 2 || '''Ghost Number'''. For staff ghosts and player ghosts this is simply the track ID minus 16.
 
| 2 || 2 || '''Ghost Number'''. For staff ghosts and player ghosts this is simply the track ID minus 16.
Line 33: Line 56:
 
| 4 || 2 || '''Track ID'''. Each track has a unique value here. This does not correspond to the order in which the apear in the game's cups. E.g. [[Wii U Mario Circuit|Mario Circuit]] has a value of 16.
 
| 4 || 2 || '''Track ID'''. Each track has a unique value here. This does not correspond to the order in which the apear in the game's cups. E.g. [[Wii U Mario Circuit|Mario Circuit]] has a value of 16.
 
|-
 
|-
| 6 || 2 || '''Character ID'''. E.g. Yoshi has a value of 4.
+
| 6 || 2 || '''Character ID'''. E.g. 04 for Yoshi.
 
|-
 
|-
| 8 || 2 || '''Character Variant ID'''. Only used fro Yoshi, Shy Guy, and Mii (standard and Amiibo suits)
+
| 8 || 2 || '''Character Variant ID'''. Only used for Yoshi, Shy Guy, and Mii (standard and Amiibo suits)
 
|-
 
|-
 
| 10 || 2 || '''Mii Weight Class'''. Only used for Mii to signify whether it is a light (0x00), medium (0x01), or heavy (0x02) character. Defaults to 0x00 for all other characters.
 
| 10 || 2 || '''Mii Weight Class'''. Only used for Mii to signify whether it is a light (0x00), medium (0x01), or heavy (0x02) character. Defaults to 0x00 for all other characters.
 
|-
 
|-
| 12 || 2 || '''Kart ID'''. E.g. Buggybud has a value of 9.
+
| 12 || 2 || '''Kart ID'''. E.g. 09 for the Buggybud.
|-
 
| 14 || 2 || '''Wheels ID'''. E.g. Button Wheels have a value of 6.
 
|-
 
| 16 || 2 || '''Glider ID'''. E.g. Cloud Glider has a value of 1.
 
|-
 
| 18 || 1 || '''Minutes''' of total finishing time.
 
|-
 
| 19 || 2 || '''Seconds''' of total finishing time.
 
|-
 
| 21 || 3 || '''Milliseconds''' of total finishing time.
 
|-
 
| 24 || 1 || '''Minutes''' of lap 1 finishing time.
 
|-
 
| 25 || 2 || '''Seconds''' of lap 1 finishing time.
 
|-
 
| 27 || 3 || '''Milliseconds''' of lap 1 finishing time.
 
|-
 
| 30 || 1 || '''Minutes''' of lap 2 finishing time.
 
|-
 
| 31 || 2 || '''Seconds''' of lap 2 finishing time.
 
|-
 
| 33 || 3 || '''Milliseconds''' of lap 2 finishing time.
 
|-
 
| 36 || 1 || '''Minutes''' of lap 3 finishing time.
 
 
|-
 
|-
| 37 || 2 || '''Seconds''' of lap 3 finishing time.
+
| 14 || 2 || '''Wheels ID'''. E.g. E.g. 06 for the Button Wheels.
 
|-
 
|-
| 39 || 3 || '''Milliseconds''' of lap 3 finishing time.
+
| 16 || 2 || '''Glider ID'''. E.g. 01 for the Cloud Glider.
 
|-
 
|-
| 42 || 1 || {{maybe-left|'''Minutes''' of lap 4 finishing time. "9" if there is no 4th lap.}}
+
| 18 || 6 || '''Finishing Time''' timestamp.
 
|-
 
|-
| 43 || 2 || {{maybe-left|'''Seconds''' of lap 4 finishing time. 3b (i.e., "59") if there is no 4th lap.}}
+
| 24 || 6 || '''Lap 1 Split''' timestamp.
 
|-
 
|-
| 45 || 3 || {{maybe-left|'''Milliseconds''' of lap 4 finishing time. 3e7 (i.e., "999") if there is no 4th lap.}}
+
| 30 || 6 || '''Lap 2 Split''' timestamp.
 
|-
 
|-
| 48 || 1 || {{maybe-left|'''Minutes''' of lap 5 finishing time.}}
+
| 36 || 6 || '''Lap 3 Split''' timestamp.
 
|-
 
|-
| 49 || 2 || {{maybe-left|'''Seconds''' of lap 5 finishing time.}}
+
| 42 || 6 || '''Lap 4 Split''' timestamp. If this lap split goes unused (e.g., for tracks that only have three laps), then a placeholder lap split of <i>9:59:999</i> (i.e., <i>93b3e7</i>) is used. This was always the case prior to the introduction of [[GCN Baby Park|<small>GCN</small> Baby Park]] in the second DLC pack in version 4 of the game.
 +
It is unknown what happens to this data when modifying the lap count of a track to be higher than 3 prior to version 4 of the game.
 
|-
 
|-
| 51 || 3 || {{maybe-left|'''Milliseconds''' of lap 5 finishing time.}}
+
| 48 || 6 || '''Lap 5 Split''' timestamp. Same restriction as the Lap 4 split.
 
|-
 
|-
 
| 54 || 40 || '''Player Name''' in UTF-16 (big Endian).
 
| 54 || 40 || '''Player Name''' in UTF-16 (big Endian).
 
|-
 
|-
| 94 || 2 || '''Flag ID'''. E.g. The Dutch flag has a value of 5e.
+
| 94 || 2 || '''Flag ID'''. E.g. 5e for the Dutch flag.
|-
 
| 96 || 2 || '''Motion Control Flag'''. 0x01 if motion controls are used. 0x00 otherwise.
 
|-
 
| 98 || 2/4 || {{Unknown-left|'''Unknown'''. Probably padding (Always 0). Prior to v4 of the game, this could be 2 characters instead if the ghost was a player ghost. The cause for this is unknown.}}
 
 
|-
 
|-
| 102 || 1 || {{no-left|'''Minutes''' of lap 6 finishing time.}}
+
| 96 || 2 || '''Motion Control Flag'''. 01 if motion controls are used, 00 otherwise.
 
|-
 
|-
| 103 || 2 || {{no-left|'''Seconds''' of lap 6 finishing time.}}
+
| 98 || 2/4 || {{Unknown-left|'''Unknown'''. Probably padding (always 0). For some player ghosts prior to version 4 of the game, the length of this unknown data was sometimes 2 instead of 4. The cause for this is unknown.}}
 
|-
 
|-
| 105 || 3 || {{no-left|'''Milliseconds''' of lap 6 finishing time.}}
+
| - || colspan=2 {{Unknown-left|The following values are not present in the filename prior to version 4 of the game. The game will still accept ghosts that omit this data as of version 4 of the game. On the contrary, earlier versions of the game reject ghosts that include this data. Manually removing this part of the filename will make earlier versions of the game also accept the ghosts.}}
 
|-
 
|-
| 108 || 1 || {{no-left|'''Minutes''' of lap 7 finishing time.}}
+
| 102 || 6 || {{no-left|'''Lap 6 Split''' timestamp. <i>9:59:999</i> (i.e., <i>93b3e7</i>) if lap split is unused.}}
 
|-
 
|-
| 109 || 2 || {{no-left|'''Seconds''' of lap 7 finishing time.}}
+
| 108 || 6 || {{no-left|'''Lap 7 Split''' timestamp. <i>9:59:999</i> if lap split is unused.}}
 
|-
 
|-
| 111 || 3 || {{no-left|'''Milliseconds''' of lap 7 finishing time.}}
+
| - || colspan=2 {{Unknown-left|End of version 4 data.}}
 
|-
 
|-
| 114 || colspan=2 {{unknown|End of filename; ".dat" extension here.}}
+
| 100/102 (v1-3), 114 (v4) || colspan=2 {{unknown|End of filename; ".dat" extension here.}}
 
|}
 
|}
 
== Game Versions ==
 
Lap 4 and 5 finishing times are unused before version 4 of the game. It's unknown if these values are properly read or written to if modifying the lap count of an existing track. Lap 6 and 7 finishing times were only introduced in version 4 of the game. Before that, these values were absent from the filename entirely. Attempting to load Ghost Data from this version of the game in an earlier version will make the game unable to recognise the file. However, renaming the file by removing these extra values will make the Ghost Data load properly. Furthermore, Ghost Data created before v4 of the game is recognised in v4 (and beyond), even though the extra lap finishing times are missing.
 
 
This change is a direct result of the introduction of [[GCN Baby Park|<small>GCN</small> Baby Park]] in the second DLC pack, as it is the only track that has more than three laps.
 
  
 
== Effect In-Game ==
 
== Effect In-Game ==
Changing these values by renaming the file affects how a ghost is displayed. Changing any of the values will result in the game displaying the modified information on the ghost summary (the additional info accessed by pressing "+" on the controller). Furthermore, changing the '''Character ID''', '''Kart ID''', '''Wheels ID''', or '''Glider ID''' will result in the game using these during the ghost race itself, regardless of the values for these inside the file itself.
+
Changing these values by renaming the file affects how a ghost is displayed. Changing any of the values will result in the game displaying the modified information on the ghost summary (the additional info accessed by pressing "+" on the controller) that is shown before viewing the replay. Furthermore, changing the '''Character ID''', '''Kart ID''', '''Wheels ID''', or '''Glider ID''' will result in the game using these during the ghost race itself, regardless of the values for these inside the file itself. Doing so can break a character's animations or SFX. <!-- Again a showcase video would be nice -->
  
Furthermore, a character's animations can break if the Character ID in the filename does not match the one inside the file contents. <!-- Again a showcase video would be nice -->
+
If the Track Number and Track ID do not correspond to the same track, then the game will be unable to recognise the file.
  
If the Track Number and Track ID do not correspond to the same track, then the game will be unable to recognise the file.
+
The game will only show one staff ghost for each track even if multiple are present among the game files. In such cases, the game will choose a ghost in the following order until a difference is found:
 +
- The lowest finishing time
 +
- The lowest character ID
 +
- Other unverified choices
  
If multiple Ghost files for the same track are present in the game's files, then the game will only show one. It's unverified if it picks the fastest time, the one recorded earliest, or based on something else.
+
It is not possible to add or remove ghosts through [[CEMU]] graphic packs. Behaviour on real hardware through plugins like [[SDCaffiine]]is not verified.
  
 
= Player Ghost File Header =
 
= Player Ghost File Header =
Line 130: Line 124:
 
| 0x00 || 4 || "'''CTG0'''" in ASCII. Unknown abbreviation.
 
| 0x00 || 4 || "'''CTG0'''" in ASCII. Unknown abbreviation.
 
|-
 
|-
| 0x04 || 4 || {{Unknown-left|'''Unknown'''. Likely game version.}}
+
| 0x04 || 4 || '''Game Version'''. <i>04 01 00 04</i> for the latest update.
 
|-
 
|-
 
| 0x08 || 4 || '''File Size''' (in bytes).
 
| 0x08 || 4 || '''File Size''' (in bytes).
Line 136: Line 130:
 
| 0x0c || 44 || {{Unknown-left|Probably '''Padding''' (always 0)}}
 
| 0x0c || 44 || {{Unknown-left|Probably '''Padding''' (always 0)}}
 
|-
 
|-
| 0x38 || 4 || CRC-32 '''Checksum''' over all bytes after this header until the end of the file.  
+
| 0x38 || 4 || CRC-32 '''Checksum''' over all bytes after this header until the end of the file.
 
|-
 
|-
 
| 0x3c || 12 || {{Unknown-left|Probably '''Padding''' (always 0)}}
 
| 0x3c || 12 || {{Unknown-left|Probably '''Padding''' (always 0)}}
Line 144: Line 138:
  
 
= Data =
 
= Data =
The remaining offset values will assume that the additional 0x48 bytes of header data are '''not present''' in the ghost file, so if you're using ghost data that was either set in-game or downloaded in-game, then add an additional 0x48 to each of the offsets below.
+
The remaining offset values will assume that the additional 0x48 bytes of header data are '''not present''' in the ghost file, so add an additional 0x48 to each of the offsets below when working with ghost data set or downloaded in-game.
  
 
{| class="wikitable"
 
{| class="wikitable"
|+ General Information
+
|+ Body Header
 
|-
 
|-
 
! Offset
 
! Offset
Line 153: Line 147:
 
! Description
 
! Description
 
|-
 
|-
| 0x00 || 6 || {{Unknown-left|Likely '''file magic'''. The values are always <i>00 00 04 00 03 A0</i>}}
+
| 0x00 || 6 || '''File magic'''. Always <i>00 00 04 00 03 A0</i>.
 
|-
 
|-
| 0x06 || 2 || {{Unknown-left|'''Unknown'''. Possibly game version.}}
+
| 0x06 || 2 || '''Version Indicator'''. <i>00 01</i> for v1.0, <i>00 02</i> for v2.0, <i>00 03</i> for v3.0, <i>80 00</i> for v4.0 and v4.1.
 
|-
 
|-
| 0x08 || 4 || '''Size of payload''' (everything after the 0x48-byte header, if present).
+
| 0x08 || 4 || '''Size of payload''' (length of everything after this 0x48-byte header).
 
|}
 
|}
  
Line 188: Line 182:
 
These values do not actually seem to be used. Instead, this data is read from the ghost's filename.
 
These values do not actually seem to be used. Instead, this data is read from the ghost's filename.
  
Driver information consists of 12 identical data blocks (one for each driver) of length <i>0x1c</i>. The first driver slot represents the data of the recorded ghost. If the ghost was recorded while racing against another ghost, the data of this other ghost is stored in the second driver slot with a special CPU flag (see below). Furthermore, the third and fourth slot will in this case be occupied by two Mario's using the standard vehicle combination (Standard Kart, Standard Wheels, Super Glider) with a CPU-flag for unoccupied slots (see below). This could indicate that racing against multiple ghosts at the same time was a planned feature, just like in [[Mario Kart 7]] where up to 7 ghosts can be raced against at the same time. The 2nd through 4th slots are identical to the remainder 8 slots if the ghost was recorded without racing against another ghost. The fifth through 12th slots are always occupied with filler data (mostly FF-values) and the "unoccupied" CPU-flag.
+
Driver information consists of 12 identical data blocks (one for each driver) of length <i>0x1c</i>. The first driver slot represents the data of the recorded ghost. If the ghost was recorded while racing against another ghost, the data of this other ghost is stored in the second driver slot with a special CPU flag (see below).
 +
 
 +
For downloaded ghosts, the third and fourth slot will in such case be occupied by two "Marios" using the standard vehicle combination (Standard Kart, Standard Wheels, Super Glider) with a CPU-flag for unoccupied slots (see below). This could indicate that racing against multiple ghosts at the same time was a planned feature, just like in [[Mario Kart 7]] where up to 7 ghosts can be raced against at the same time.
 +
 
 +
The 2nd through 4th slots are identical to the remainder 8 slots if the ghost was recorded without racing against another ghost. The fifth through 12th slots are always occupied with filler data (mostly FF-values) and the "unoccupied" CPU-flag.
 +
 
 +
In [[Mario Kart 8 Deluxe]], the 2nd through 4th driver slots can sometimes also be filled with other valid combo data. The cause for this is currently unknown. So far, this has only been observed in a 200cc ghost for [[Wii U Big Blue|Big Blue]].
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 211: Line 211:
 
| 0x12 || 2 || '''Padding'''. Always 0.
 
| 0x12 || 2 || '''Padding'''. Always 0.
 
|-
 
|-
| 0x14 || 4 || '''CPU Flag'''. <i>0</i> for a human player, <i>1</i> for a CPU, <i>3</i> for the vs ghost in the second driver slot, <i>4</i> when unoccupied.
+
| 0x14 || 4 || '''CPU Flag'''. <i>0</i> for a human player, <i>1</i> for a CPU, <i>3</i> for the vs ghost in the second driver slot, <i>4</i> when the slot is unoccupied.
 
|-
 
|-
 
| 0x18 || 4 || '''Team Flag'''. <i>0</i> for red team, <i>1</i> for blue team, <i>2</i> for a solo team (always the case in Time Trials or during other solo races).
 
| 0x18 || 4 || '''Team Flag'''. <i>0</i> for red team, <i>1</i> for blue team, <i>2</i> for a solo team (always the case in Time Trials or during other solo races).
Line 252: Line 252:
 
=== Race Settings ===
 
=== Race Settings ===
 
Race settings store flags or other identifiers of a race. These are sometimes used in the UI for [[MKTV Replay (File Format)|MKTV Replays]].
 
Race settings store flags or other identifiers of a race. These are sometimes used in the UI for [[MKTV Replay (File Format)|MKTV Replays]].
+
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ Race Settings
 
|+ Race Settings
Line 274: Line 274:
 
| 0x194 || 1 || '''Mirror Flag'''. <i>0</i> for standard play, <i>1</i> for mirror mode.
 
| 0x194 || 1 || '''Mirror Flag'''. <i>0</i> for standard play, <i>1</i> for mirror mode.
 
|-
 
|-
| 0x195 || 1 || '''Team Flag'''. <i>0</i> for solo play, <i>1</i> for team play.
+
| 0x195 || 1 || '''Team Flag'''. <i>0</i> for solo play, <i>1</i> for team play. If set, drivers with a "Solo" team flag are shown on as if they were on the red team.
 
|-
 
|-
 
| 0x196 || 1 || {{Unknown-left|'''Unknown'''. Always <i>03</i>.}}
 
| 0x196 || 1 || {{Unknown-left|'''Unknown'''. Always <i>03</i>.}}
Line 282: Line 282:
 
| 0x198 || 16 || {{Unknown-left|'''Unknown'''.}}
 
| 0x198 || 16 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
|-
| 0x1a8 || 4 || '''Number of Drivers'''. Always <i>1</i> for Time Trials. Number is equal to the number of drivers with an "unoccupied" CPU slot (see driver data above).
+
| 0x1a8 || 4 || '''Number of Drivers'''. Number is equal to the number of drivers with a CPU flag for "human", "cpu", or "vs ghost" (see Driver Data above).
 
|}
 
|}
  
Line 306: Line 306:
 
=== Location ===
 
=== Location ===
 
This data is used to display the driver's flag at the end of a race when replaying a ghost.
 
This data is used to display the driver's flag at the end of a race when replaying a ghost.
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ Location
 
|+ Location
Line 324: Line 323:
 
| 0x2a9 || 1 || '''Sub-region ID''' repeat (purpose unknown).
 
| 0x2a9 || 1 || '''Sub-region ID''' repeat (purpose unknown).
 
|}
 
|}
 +
 +
[[File:Bcp-wave-3-staff-ghost-no-flag.jpg|thumb|The Dutch flag is missing from the 200cc staff ghost for [[Tour Merry Mountain]]]]
 +
In [[Mario Kart 8 Deluxe]], the staff ghosts of Wave III of the Booster Course Pass have this data zeroed out, meaning that no country flags show when completing a race against them. Staff ghosts of Wave I and II do have this data properly set.
 +
  
 
=== Player Info ===
 
=== Player Info ===
Line 333: Line 336:
 
! Description
 
! Description
 
|-
 
|-
| 0x304 || 20 || {{Unknown-left|'''Mii Name''' in UTF-16 big Endian. Purpose Unknown.}} <!-- This might be used to store the Mii name of the user profile in case they use a Mii that is stored on the system, but is not that of the user profile? -->
+
| 0x304 || 20 || {{Unknown-left|'''Mii Name''' in UTF-16 big Endian. Purpose Unknown.}}
 
|}
 
|}
  
Line 339: Line 342:
 
This data is on the overview at the end of a ghost replay. If a track does not have a lap, its lap time is set to 9:59:999 just like in the ghost filename. The exception to this are the lap splits for lap 6 and 7, which are instead 0:00:000 if left unused.
 
This data is on the overview at the end of a ghost replay. If a track does not have a lap, its lap time is set to 9:59:999 just like in the ghost filename. The exception to this are the lap splits for lap 6 and 7, which are instead 0:00:000 if left unused.
  
 +
Each timestamp has the same format:
 
{| class="wikitable"
 
{| class="wikitable"
|+ Total Time & Lap Splits
+
|+ Timestamp
 
|-
 
|-
 
! Offset
 
! Offset
Line 346: Line 350:
 
! Description
 
! Description
 
|-
 
|-
| colspan=3 {{unknown|Lap 1 Time}}
+
| 0x00 || 2 || '''Minutes'''.
 
|-
 
|-
| 0x330 || 2 || '''Minutes'''.
+
| 0x02 || 1 || '''Seconds'''.
 
|-
 
|-
| 0x332 || 1 || '''Seconds'''.
+
| 0x03 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
 
|-
 
|-
| 0x333 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 0x04 || 2 || '''Milliseconds'''.
 
|-
 
|-
| 0x334 || 2 || '''Milliseconds'''.
+
| 0x06 || 6 || {{Unknown-left|Probably '''Padding''' (always 0). Sometimes <i>08 00 00 00 00 00</i> for lap 6 split. Could be related to the ghost version in the Body Header.}}
 
|-
 
|-
| 0x336 || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 0x0c || colspan=2 {{unknown|End of timestamp.}}
 +
|}
 +
 
 +
The offsets above are relative to the following offsets:
 +
{| class="wikitable mw-collapsible mw-collapsed"
 +
|+ Total Time & Lap Splits
 
|-
 
|-
| colspan=3 {{unknown|Lap 2 Time}}
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| 0x33c || 2 || '''Minutes'''.
+
| 0x330 || 0x0c || '''Lap 1 Split'''.
 
|-
 
|-
| 0x33e || 1 || '''Seconds'''.
+
| 0x33c || 0x0c || '''Lap 2 Split'''.
 
|-
 
|-
| 0x33f || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 0x348 || 0x0c || '''Lap 3 Split'''.
 
|-
 
|-
| 0x340 || 2 || '''Milliseconds'''.
+
| 0x354 || 0x0c || '''Lap 4 Split'''.
 
|-
 
|-
| 0x342 || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 0x360 || 0x0c || '''Lap 5 Split'''.
 
|-
 
|-
| colspan=3 {{unknown|Lap 3 Time}}
+
| 0x36c || 0x0c || '''Finishing Time'''.
 
|-
 
|-
| 0x348 || 2 || '''Minutes'''.
+
| 0x378 || 0x0c || '''Lap 6 Split'''.
 
|-
 
|-
| 0x34a || 1 || '''Seconds'''.
+
| 0x384 || 0x0c || '''Lap 7 Split'''.
 
|-
 
|-
| 0x34b || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 0x390 || colspan=2 {{unknown|End of timestamps.}}
 +
|}
 +
 
 +
Additionally, (staff) ghosts recorded in v4 of the game store additional 9:59:999 data, which might be placeholders for laps 8, 9, and 10. In earlier versions of the game this data was always 0. It is unknown if this data is properly written to if the lap count of an existing track is increased. Likewise, the behaviour of the UI nor the ghost filename is known if this is done.
 +
 
 +
{| class="wikitable mw-collapsible mw-collapsed"
 +
|+ Possible Lap Split Placeholders
 
|-
 
|-
| 0x34c || 2 || '''Milliseconds'''.
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| 0x34e || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 0x390 || 0x0c || Possibly '''Padding''' or another lap split placeholder. Always 0.
 
|-
 
|-
| colspan=3 {{unknown|Lap 4 Time}}
+
| 0x33c || 0x0c || '''Lap 8 Split Placeholder'''.
 
|-
 
|-
| 0x354 || 2 || '''Minutes'''.
+
| 0x3a8 || 0x0c || '''Lap 9 Split Placeholder'''.
 
|-
 
|-
| 0x356 || 1 || '''Seconds'''.
+
| 0x3b4 || 0x0c || '''Lap 10 Split Placeholder'''.
 
|-
 
|-
| 0x357 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 0x3c0 || 0x40 || Possibly '''Padding''' and/or more lap split placeholders. Always 0.
 
|-
 
|-
| 0x358 || 2 || '''Milliseconds'''.
+
| 0x400 || colspan=2 {{unknown|End of possible lap split placeholders.}}
 +
|}
 +
 
 +
== Replay Infos ==
 +
This section contains all data needed to replay a ghost. It can be exchanged with that of another ghost file, making the game replay the ghost of the injected data (assuming all CRC-elements are fixed).
 +
 
 +
There are several Yaz0 sections at the end of the ghost file that represent the actual replay itself. In order to obtain this data, all Yaz0 sections need to be decompressed and concatenated. The decompressed and concatenated data of these yaz0 blocks are henceforth referenced to as simply "replay data". Each yaz0 block contains a compressed portion of the replay data of length exactly 0x8000, with the exception of the last block where it may be smaller.
 +
 
 +
All Yaz0 blocks are padded to be a multiple of 0x40. However, recompressing the replay data and not padding it will still allow the game to accept the ghost file and replay the ghost. At this point in time, there have not yet been fully successful attempts at recompressing and injecting the replay data back into the same ghost. Specifically, such a recompressed ghost properly replays the ghost until the last portion of the replay, after which the ghost will warp back in time until the replay ends. This likely indicates that some additional verification is located elsewhere.
 +
 
 +
=== Replay Header ===
 +
The replay header stores information regarding the yaz0 blocks at the end of the file, and the section data within them when uncompressed.
 +
 
 +
{| class="wikitable"
 +
|+ Replay Header
 
|-
 
|-
| 0x35a || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| colspan=3 {{unknown|Lap 5 Time}}
+
| 0x400 || 4 || CRC-32 '''Checksum''' over all bytes after this value until the first yaz0 section.
 
|-
 
|-
| 0x360 || 2 || '''Minutes'''.
+
| 0x404 || 4 || '''First Yaz0 Section Offset'''. Offset for the first yaz0 block, relative to the start of the replay infos.
 
|-
 
|-
| 0x362 || 1 || '''Seconds'''.
+
| 0x408 || 4 || {{Unknown-left|'''Unknown'''. Always <i>00 04 ab b8</i> for time trial ghosts.}}
 
|-
 
|-
| 0x363 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 0x40c || 4 || {{Unknown-left|'''Unknown'''. For time trial ghosts, always matches the value at 0x460.}}
 
|-
 
|-
| 0x364 || 2 || '''Milliseconds'''.
+
| 0x410 || 4 || '''Number of subsections in the replay data'''. Value depends on the number of wheels of the vehicle body. Will always be <i>15</i> (two wheels), <i>16</i> (three wheels) or <i>17</i> (four wheels).
 
|-
 
|-
| 0x366 || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 0x414 || 4 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
|-
| colspan=3 {{unknown|Total Time}}
+
| 0x418 || 8 || {{Unknown-left|'''Unknown'''. Always <i>00 00 00 8c 00 00 00 30</i> for time trial ghosts.}}
 
|-
 
|-
| 0x36c || 2 || '''Minutes'''.
+
| 0x420 || 8 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
|-
| 0x36e || 1 || '''Seconds'''.
+
| 0x428 || 4 || '''Number of subsections in the replay data (repeat)'''. Always identical to the number of subsections in the replay data for time trial ghosts. Purpose unknown.
 
|-
 
|-
| 0x36f || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 0x42c || 2c || {{Unknown-left|'''Unknown'''.}}
 
|-
 
|-
| 0x370 || 2 || '''Milliseconds'''.
+
| 0x458 || 4 || '''Size of decompressed Data''' plus the offset of the first yaz0 block.
 
|-
 
|-
| 0x372 || 10 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 0x45c || 4 || '''Number of sections in the replay data'''.
 
|-
 
|-
| 0x37c || 4 || {{Unknown-left|'''Unknown'''.}}
+
| 0x460 || 4 || {{Unknown-left|'''Unknown'''. For time trial ghosts, always matches the value at 0x40c.}}
 
|-
 
|-
| 0x380 || 4 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 0x464 || 4 || {{Unknown-left|'''Unknown'''. Always <i>7f 7f ff ff</i> for time trial ghosts.}}
 
|-
 
|-
| colspan=3 {{unknown|Lap 6 Time}}
+
| 0x468 || 4 || '''Number of yaz0 blocks''' at the end of the file.
 
|-
 
|-
| 0x384 || 2 || '''Minutes'''.
+
| 0x46c || 20 || {{Unknown-left|Probably '''Padding'''.}}
 
|-
 
|-
| 0x386 || 1 || '''Seconds'''.
+
| 0x48c || colspan=2 {{unknown|End of replay header.}}
 +
|}
 +
 
 +
=== Replay Header ===
 +
After the replay header, offsets to each replay data section (see below) and yaz0 block are located.
 +
{| class="wikitable"
 +
|+ Replay Header
 
|-
 
|-
| 0x387 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
! Offset
|-
+
! Size
| 0x388 || 2 || '''Milliseconds'''.
+
! Description
|-
 
| 0x38a || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
 
 
|-
 
|-
| colspan=3 {{unknown|Lap 7 Time}}
+
| 0x48c || 4 || '''First section offset''' in the replay data, relative to the start of the replay infos.
 
|-
 
|-
| 0x390 || 2 || '''Minutes'''.
+
| 0x490 || colspan=2 {{Unknown-left|Offsets to all other sections in the replay data follow. Number of sections is indicated earlier at offset 0x45c. }}
 
|-
 
|-
| 0x392 || 1 || '''Seconds'''.
+
| - || 4 || '''First yaz0 block offset''', relative to the start of the replay infos.
 
|-
 
|-
| 0x393 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| - || colspan=2 {{Unknown-left|Offsets to all other yaz0 blocks follow. Number of yaz0 blocks is indicated earlier at offset 0x468. }}
|-
 
| 0x394 || 2 || '''Milliseconds'''.
 
|-
 
| 0x396 || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
 
 
|}
 
|}
  
Additionally, (staff) ghosts recorded in v4 of the game store additional 9:59:999 data, which might be placeholders for laps 8, 9, and 10. In earlier versions of the game this data was always 0. It is unknown if this data is properly written to if the lap count of an existing track is increased. Likewise, the behaviour of the UI nor the ghost filename is known if this is done.
+
=== Unknown Data ===
 +
Some unknown data follows. When modifying the ghost and setting all this data to 0, the game still accepts the ghost, though the ghost no longer replays and warps below the track (like the coordinate origin). Coins and laps are also no longer properly counted.
 +
 
 +
=== Replay Data ===
 +
Replay data consists of a number of sections. Each of these sections is identical in structure, and represents a portion of the replay for some number of frames (likely 64 frames). These sections all consist of an equal number of subsections (indicated at offset 0x410), though some of these subsections can be absent.
  
 
{| class="wikitable"
 
{| class="wikitable"
|+ Total Time & Lap Splits
+
|+ Replay Data Section
 
|-
 
|-
 
! Offset
 
! Offset
Line 456: Line 495:
 
! Description
 
! Description
 
|-
 
|-
| colspan=3 {{unknown|Lap 8 Time Placeholder?}}
+
| 0x00 || 4 || CRC-32 '''Checksum''' over the data after this checksum until the end of the section.
 
|-
 
|-
| 0x39c || 2 || '''Minutes'''.
+
| 0x04 || 2 || '''Size of the first subsection''' in this section, or <i>0xff</i> if the subsection is absent.
 
|-
 
|-
| 0x39e || 1 || '''Seconds'''.
+
| 0x06 || colspan=2 {{Unknown-left|Sizes of all other subsections in this section follow.}}
 
|-
 
|-
| 0x39f || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| - || - || '''Data of the first subsection'''.
 
|-
 
|-
| 0x3a0 || 2 || '''Milliseconds'''.
+
| - || colspan=2 {{Unknown-left|Data of all other subsections in this section follows.}}
 +
|}
 +
 
 +
Each of these subsections contains data for a specific part of the replay for some number of frames. Note that the lengths of subsections at the same index of a section can have different lengths. For example, the first '''sub'''section of the first and second section in the replay data may have different lengths. The cause for this is currently unknown.
 +
 
 +
Each subsection is responsible for the following parts of a replay. The subsection indices below assume a 4-wheel vehicle was used.
 +
 
 +
{| class="wikitable"
 +
|+ Replay Data Subsections
 
|-
 
|-
| 0x3a2 || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
! Subsection Index
 +
! Description
 
|-
 
|-
| colspan=3 {{unknown|Lap 9 Time Placeholder?}}
+
| 0 || '''Coin & Lap Count'''. Coin and Lap values can occur more than once in a single subsection. Coin count is located at offset -1 (i.e., relative to the end of the section). Lap count at offset -10 from the first coin value.
 
|-
 
|-
| 0x3a8 || 2 || '''Minutes'''.
+
| 1 || {{Unknown-left|'''Unknown SFX'''. For example, includes the glider tunnel SFX (but not the glider SFX itself) in [[Wii U Big Blue|Big Blue]]}}
 
|-
 
|-
| 0x3aa || 1 || '''Seconds'''.
+
| 2 || '''Kart Position & Drift/Mushroom item VFX & Directional Controller Inputs'''.
 
|-
 
|-
| 0x3ab || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 3 || '''Driver rotation & Kart Scale & Glider Popup'''.
 
|-
 
|-
| 0x3ac || 2 || '''Milliseconds'''.
+
| 4 || {{Unknown-left|'''Unknown'''. Always absent entirely.}}
 
|-
 
|-
| 0x3ae || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 5 || '''Front-Left Wheel Position & Rotation'''.
 
|-
 
|-
| colspan=3 {{unknown|Lap 10 Time Placeholder?}}
+
| 6 || '''Front-Right Wheel Position & Rotation'''.
 
|-
 
|-
| 0x3b4 || 2 || '''Minutes'''.
+
| 7 || '''Back-Left Wheel Position & Rotation'''.
 
|-
 
|-
| 0x3b6 || 1 || '''Seconds'''.
+
| 8 || '''Back-Right Wheel Position & Rotation'''.
 
|-
 
|-
| 0x3b7 || 1 || {{Unknown-left|'''Padding''' (always 0).}}
+
| 9 || '''Item Slot UI & Various VFX'''. VFX includes things like items (E.g. the super horn), map objects (E.g. [[GBA Mario Circuit]] oil slicks), spin boosts, or bump/crash stars. VFX does not include kart drift, or the purple circle VFX when collecting coins on the F-zero tracks.
 
|-
 
|-
| 0x3b8 || 2 || '''Milliseconds'''.
+
| 10 || '''Driver Rotation & Scale'''. Possibly includes animations as well.
 
|-
 
|-
| 0x3ba || 6 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 11 || '''Camera'''. Influences the behaviour of the camera.
 
|-
 
|-
| 0x3c0 || 48 || {{Unknown-left|Probably '''Padding''' (always 0).}}
+
| 12 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
|-
| 0x400 || colspan=2 {{unknown|End of total time & lap splits.}}
+
| 13 || '''Item State''', like the shroom count. Does not control the UI.
|}
 
 
 
== Replay Data ==
 
There are several Yaz0 sections at the end of the ghost file that represent the drivers' movement. This section can be exchanged with that of another ghost file, making the game replay the ghost of the injected data (after fixing the CRC and file size elements in the ghost's header). It is currently unknown what they specifically store.
 
 
 
=== Replay Header ===
 
The replay header stores information regarding the yaz0 blocks, and the section data within them when uncompressed, at the end of the file.
 
 
 
{| class="wikitable"
 
|+ Replay Header
 
 
|-
 
|-
! Offset
+
| 14 || {{Unknown-left|'''Unknown'''.}}
! Size
 
! Description
 
 
|-
 
|-
| 0x400 || 4 || CRC-32 '''Checksum''' over all bytes after this value until the first yaz0 section.
+
| 15 || '''Kart SFX'''. SFX includes coin collection, tricks, and glider activation.
 
|-
 
|-
| 0x404 || 4 || '''First Yaz0 Section Offset'''. Offset for the first yaz0 section, relative to the start of the replay data.
+
| 16 || '''Driver SFX'''.
|-
 
| 0x408 || 8 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
| 0x408 || 4 || '''Number of subsections in the decompressed yaz0 sections'''. Always <i>17</i>.
 
|-
 
| 0x40c || 72 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
| 0x454 || 4 || '''Number of sections in the decompressed yaz0 sections'''.
 
|-
 
| 0x458 || 8 || {{Unknown-left|'''Unknown'''.}}
 
|-
 
| 0x460 || 4 || '''Number of yaz0''' sections at the end of the file.
 
|-
 
| 0x464 || 32 || {{Unknown-left|Probably '''Padding'''.}}
 
 
|}
 
|}
 
<!-- This is a WIP -->
 
 
=== Additional Data ===
 
The game must also store the following information, likely in the yaz0 sections:
 
* Player position
 
* Player rotation
 
* Player scale (E.g., when smashed by a thwomp)
 
* Drift usage
 
* Tricks performed
 
* Horn usage
 
* Item usage. When hacking in bullet bills or stars, the game properly displays this.
 
* Lakitu saves
 
  
 
= Tools =
 
= Tools =

Revision as of 16:05, 11 January 2023

Under Construction
This article is not finished. Help improve it by adding accurate information or correcting grammar and spelling.
Platform Notice
This article is about Mario Kart 8 for Wii U. Mario Kart 8 Deluxe uses a similar file format, but that is still a WIP and the offsets are different.

In Mario Kart 8, Ghost Data is stored in DAT-files. This includes player ghosts, staff ghosts, and downloaded ghosts ("time trial ghosts" in short). MKTV replays have a similar file format, and relics of such replays are thus present in time trial ghost data. Each ghost is stored in a separate DAT-file.

Player Ghosts, Downloaded Ghosts, and MKTV Replays are stored in the user's save folder. Staff Ghosts are stored among the game files.

Differences with Mario Kart Wii

In Mario Kart Wii, as well as earlier titles, ghost files most notably store controller inputs. When a ghost is viewed, the game replays these controller inputs. 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.

In Mario Kart 8, this is different. Ghost files also contain kart positions in some form in addition to controller inputs. In practise, this means that a ghost is always able to finish a race in the exact same way (give or take) as it was recorded in. This can be verified by replacing the file contents of a ghost file with that of another. When doing so, the ghost will ignore any collisions of the track (e.g. drive through walls) and follow the layout of the course it was initially recorded in.

As a result, the Wiggler Glitch cannot occur in Mario Kart 8.

The relation to Mario Kart 7 ghosts is currently unknown.

Filename

Some ghost data information is encoded into the filename of the ghost file. The first two characters indicate what type of ghost data is inside the file. The remaining characters should be interpreted as hexadecimal values. The tables below assumes the characters are parsed as hex values.

Timestamp

Several timestamps are encoded in a ghost's filename. These all have an identical format. These offsets are relative to the start of the timestamp data. Examples of timestamps are the total time and lap splits.

Timestamp
Offset Size Description
0 1 Minutes.
1 2 Seconds.
3 3 Milliseconds.
6 End of timestamp

A timestamp of 9:59:999 is thus represented as 9 3b 3e7 (spaces added for clarity).

Data

Ghost Data Filename
Offset Size Description
0 2 Ghost Type. "sg" for Staff Ghost, "gs" for Player Ghost (possibly a shorthand for "ghost save"), "dg" for Downloaded Ghost, "rp" for MKTV Replay.
2 2 Ghost Number. For staff ghosts and player ghosts this is simply the track ID minus 16.

For downloaded ghosts it is a value from 0x00-0x0f, representing one of the 16 available downloaded ghost slots. If the game detects multiple downloaded ghosts with the same ghost number (even if they're not for the same track), it will keep the ghost for the track with the lowest trackID and discard all others. This number also allows the game to differentiate between ghosts which have otherwise identical data in the filename.

4 2 Track ID. Each track has a unique value here. This does not correspond to the order in which the apear in the game's cups. E.g. Mario Circuit has a value of 16.
6 2 Character ID. E.g. 04 for Yoshi.
8 2 Character Variant ID. Only used for Yoshi, Shy Guy, and Mii (standard and Amiibo suits)
10 2 Mii Weight Class. Only used for Mii to signify whether it is a light (0x00), medium (0x01), or heavy (0x02) character. Defaults to 0x00 for all other characters.
12 2 Kart ID. E.g. 09 for the Buggybud.
14 2 Wheels ID. E.g. E.g. 06 for the Button Wheels.
16 2 Glider ID. E.g. 01 for the Cloud Glider.
18 6 Finishing Time timestamp.
24 6 Lap 1 Split timestamp.
30 6 Lap 2 Split timestamp.
36 6 Lap 3 Split timestamp.
42 6 Lap 4 Split timestamp. If this lap split goes unused (e.g., for tracks that only have three laps), then a placeholder lap split of 9:59:999 (i.e., 93b3e7) is used. This was always the case prior to the introduction of GCN Baby Park in the second DLC pack in version 4 of the game.

It is unknown what happens to this data when modifying the lap count of a track to be higher than 3 prior to version 4 of the game.

48 6 Lap 5 Split timestamp. Same restriction as the Lap 4 split.
54 40 Player Name in UTF-16 (big Endian).
94 2 Flag ID. E.g. 5e for the Dutch flag.
96 2 Motion Control Flag. 01 if motion controls are used, 00 otherwise.
98 2/4 Unknown. Probably padding (always 0). For some player ghosts prior to version 4 of the game, the length of this unknown data was sometimes 2 instead of 4. The cause for this is unknown.
- The following values are not present in the filename prior to version 4 of the game. The game will still accept ghosts that omit this data as of version 4 of the game. On the contrary, earlier versions of the game reject ghosts that include this data. Manually removing this part of the filename will make earlier versions of the game also accept the ghosts.
102 6 Lap 6 Split timestamp. 9:59:999 (i.e., 93b3e7) if lap split is unused.
108 6 Lap 7 Split timestamp. 9:59:999 if lap split is unused.
- End of version 4 data.
100/102 (v1-3), 114 (v4) End of filename; ".dat" extension here.

Effect In-Game

Changing these values by renaming the file affects how a ghost is displayed. Changing any of the values will result in the game displaying the modified information on the ghost summary (the additional info accessed by pressing "+" on the controller) that is shown before viewing the replay. Furthermore, changing the Character ID, Kart ID, Wheels ID, or Glider ID will result in the game using these during the ghost race itself, regardless of the values for these inside the file itself. Doing so can break a character's animations or SFX.

If the Track Number and Track ID do not correspond to the same track, then the game will be unable to recognise the file.

The game will only show one staff ghost for each track even if multiple are present among the game files. In such cases, the game will choose a ghost in the following order until a difference is found: - The lowest finishing time - The lowest character ID - Other unverified choices

It is not possible to add or remove ghosts through CEMU graphic packs. Behaviour on real hardware through plugins like SDCaffiineis not verified.

Player Ghost File Header

The following header is absent for Staff Ghosts. However, a Player or Downloaded Ghost can easily be converted into a Staff Ghost by removing this header and renaming the first two characters of the filename from "gs"/"dg" to "sg". This header is identical to the header of a save file. Ghosts downloaded through the Nintendo Clients package do not have this header.

Extra Ghost Header
Offset Size Description
0x00 4 "CTG0" in ASCII. Unknown abbreviation.
0x04 4 Game Version. 04 01 00 04 for the latest update.
0x08 4 File Size (in bytes).
0x0c 44 Probably Padding (always 0)
0x38 4 CRC-32 Checksum over all bytes after this header until the end of the file.
0x3c 12 Probably Padding (always 0)
0x48 End of extra ghost header

Data

The remaining offset values will assume that the additional 0x48 bytes of header data are not present in the ghost file, so add an additional 0x48 to each of the offsets below when working with ghost data set or downloaded in-game.

Body Header
Offset Size Description
0x00 6 File magic. Always 00 00 04 00 03 A0.
0x06 2 Version Indicator. 00 01 for v1.0, 00 02 for v2.0, 00 03 for v3.0, 80 00 for v4.0 and v4.1.
0x08 4 Size of payload (length of everything after this 0x48-byte header).

Timestamp

When a new ghost is created, the timestamp from the user's local time is used and included in the ghost data.

Timestamp
Offset Size Description
0x0c 4 Year.
0x10 4 Month.
0x14 4 Day.
0x18 4 Day of Week, with 0x00 being Sunday.
0x1c 4 Hour.
0x20 4 Minute.
0x24 4 Second.

Driver Data

These values do not actually seem to be used. Instead, this data is read from the ghost's filename.

Driver information consists of 12 identical data blocks (one for each driver) of length 0x1c. The first driver slot represents the data of the recorded ghost. If the ghost was recorded while racing against another ghost, the data of this other ghost is stored in the second driver slot with a special CPU flag (see below).

For downloaded ghosts, the third and fourth slot will in such case be occupied by two "Marios" using the standard vehicle combination (Standard Kart, Standard Wheels, Super Glider) with a CPU-flag for unoccupied slots (see below). This could indicate that racing against multiple ghosts at the same time was a planned feature, just like in Mario Kart 7 where up to 7 ghosts can be raced against at the same time.

The 2nd through 4th slots are identical to the remainder 8 slots if the ghost was recorded without racing against another ghost. The fifth through 12th slots are always occupied with filler data (mostly FF-values) and the "unoccupied" CPU-flag.

In Mario Kart 8 Deluxe, the 2nd through 4th driver slots can sometimes also be filled with other valid combo data. The cause for this is currently unknown. So far, this has only been observed in a 200cc ghost for Big Blue.

Individual Driver Data
Offset Size Description
0x00 4 Vehicle Body ID.
0x04 4 Tires ID.
0x08 4 Glider ID.
0x0c 4 Character ID.
0x10 1 Character Variant ID.
0x11 1 Mii Weight Class.
0x12 2 Padding. Always 0.
0x14 4 CPU Flag. 0 for a human player, 1 for a CPU, 3 for the vs ghost in the second driver slot, 4 when the slot is unoccupied.
0x18 4 Team Flag. 0 for red team, 1 for blue team, 2 for a solo team (always the case in Time Trials or during other solo races).
0x1c End of driver data.

The offsets above are relative to the following offets for each driver.

Driver Data
Offset Description
0x2c Player 1
0x48 Player 2
0x64 Player 3
0x80 Player 4
0x9c Player 5
0xb8 Player 6
0xd4 Player 7
0xf0 Player 8
0x10c Player 9
0x128 Player 10
0x144 Player 11
0x160 Player 12
0x17c End of driver data

Race Settings

Race settings store flags or other identifiers of a race. These are sometimes used in the UI for MKTV Replays.

Race Settings
Offset Size Description
0x17c 4 Track ID.
0x180 4 Online Mode. 0 for local play. 1 for online play.
0x184 4 Game Mode. 0 for Grand Prix, 1 for Time Trial, 2 for VS Race, 3 for Battle Mode.
0x188 4 Unknown. Always 00 00 00 02.
0x18c 4 Unknown. Always 00 00 00 00 or 00 00 00 01.
0x190 4 CC Mode. 0 for 50cc, 1 for 100cc, 2 for 150cc, 3 for 200cc.
0x194 1 Mirror Flag. 0 for standard play, 1 for mirror mode.
0x195 1 Team Flag. 0 for solo play, 1 for team play. If set, drivers with a "Solo" team flag are shown on as if they were on the red team.
0x196 1 Unknown. Always 03.
0x197 1 Unknown. Always 00.
0x198 16 Unknown.
0x1a8 4 Number of Drivers. Number is equal to the number of drivers with a CPU flag for "human", "cpu", or "vs ghost" (see Driver Data above).

Mii Info

In every single ghost file there is embedded Mii data so that the game can reconstruct the Mii in the case that a Mii was used in the run. Below is the start offset and size of the Mii data. If a Mii was not used during the race, this data will match the Mii of the user profile. Furthermore, this data is used to display the driver name when replaying a ghost.

Mii Info
Offset Size Description
0x244 92 Mii Data. See full description on 3dsbrew. Note that the embedded Mii name is in UTF-16 (little Endian).
0x2a0 2 Probably Padding.
0x2a2 2 CRC-16 XMODEM Checksum.
0x2a4 End of Mii data.

Location

This data is used to display the driver's flag at the end of a race when replaying a ghost.

Location
Offset Size Description
0x2a4 1 Country ID.
0x2a5 1 Sub-region ID.
0x2a6 2 Probably Padding (always 0).
0x2a8 1 Country ID repeat (purpose unknown).
0x2a9 1 Sub-region ID repeat (purpose unknown).
The Dutch flag is missing from the 200cc staff ghost for Tour Merry Mountain

In Mario Kart 8 Deluxe, the staff ghosts of Wave III of the Booster Course Pass have this data zeroed out, meaning that no country flags show when completing a race against them. Staff ghosts of Wave I and II do have this data properly set.


Player Info

Player Info
Offset Size Description
0x304 20 Mii Name in UTF-16 big Endian. Purpose Unknown.

Total Time & Lap Splits

This data is on the overview at the end of a ghost replay. If a track does not have a lap, its lap time is set to 9:59:999 just like in the ghost filename. The exception to this are the lap splits for lap 6 and 7, which are instead 0:00:000 if left unused.

Each timestamp has the same format:

Timestamp
Offset Size Description
0x00 2 Minutes.
0x02 1 Seconds.
0x03 1 Padding (always 0).
0x04 2 Milliseconds.
0x06 6 Probably Padding (always 0). Sometimes 08 00 00 00 00 00 for lap 6 split. Could be related to the ghost version in the Body Header.
0x0c End of timestamp.

The offsets above are relative to the following offsets:

Total Time & Lap Splits
Offset Size Description
0x330 0x0c Lap 1 Split.
0x33c 0x0c Lap 2 Split.
0x348 0x0c Lap 3 Split.
0x354 0x0c Lap 4 Split.
0x360 0x0c Lap 5 Split.
0x36c 0x0c Finishing Time.
0x378 0x0c Lap 6 Split.
0x384 0x0c Lap 7 Split.
0x390 End of timestamps.

Additionally, (staff) ghosts recorded in v4 of the game store additional 9:59:999 data, which might be placeholders for laps 8, 9, and 10. In earlier versions of the game this data was always 0. It is unknown if this data is properly written to if the lap count of an existing track is increased. Likewise, the behaviour of the UI nor the ghost filename is known if this is done.

Possible Lap Split Placeholders
Offset Size Description
0x390 0x0c Possibly Padding or another lap split placeholder. Always 0.
0x33c 0x0c Lap 8 Split Placeholder.
0x3a8 0x0c Lap 9 Split Placeholder.
0x3b4 0x0c Lap 10 Split Placeholder.
0x3c0 0x40 Possibly Padding and/or more lap split placeholders. Always 0.
0x400 End of possible lap split placeholders.

Replay Infos

This section contains all data needed to replay a ghost. It can be exchanged with that of another ghost file, making the game replay the ghost of the injected data (assuming all CRC-elements are fixed).

There are several Yaz0 sections at the end of the ghost file that represent the actual replay itself. In order to obtain this data, all Yaz0 sections need to be decompressed and concatenated. The decompressed and concatenated data of these yaz0 blocks are henceforth referenced to as simply "replay data". Each yaz0 block contains a compressed portion of the replay data of length exactly 0x8000, with the exception of the last block where it may be smaller.

All Yaz0 blocks are padded to be a multiple of 0x40. However, recompressing the replay data and not padding it will still allow the game to accept the ghost file and replay the ghost. At this point in time, there have not yet been fully successful attempts at recompressing and injecting the replay data back into the same ghost. Specifically, such a recompressed ghost properly replays the ghost until the last portion of the replay, after which the ghost will warp back in time until the replay ends. This likely indicates that some additional verification is located elsewhere.

Replay Header

The replay header stores information regarding the yaz0 blocks at the end of the file, and the section data within them when uncompressed.

Replay Header
Offset Size Description
0x400 4 CRC-32 Checksum over all bytes after this value until the first yaz0 section.
0x404 4 First Yaz0 Section Offset. Offset for the first yaz0 block, relative to the start of the replay infos.
0x408 4 Unknown. Always 00 04 ab b8 for time trial ghosts.
0x40c 4 Unknown. For time trial ghosts, always matches the value at 0x460.
0x410 4 Number of subsections in the replay data. Value depends on the number of wheels of the vehicle body. Will always be 15 (two wheels), 16 (three wheels) or 17 (four wheels).
0x414 4 Unknown.
0x418 8 Unknown. Always 00 00 00 8c 00 00 00 30 for time trial ghosts.
0x420 8 Unknown.
0x428 4 Number of subsections in the replay data (repeat). Always identical to the number of subsections in the replay data for time trial ghosts. Purpose unknown.
0x42c 2c Unknown.
0x458 4 Size of decompressed Data plus the offset of the first yaz0 block.
0x45c 4 Number of sections in the replay data.
0x460 4 Unknown. For time trial ghosts, always matches the value at 0x40c.
0x464 4 Unknown. Always 7f 7f ff ff for time trial ghosts.
0x468 4 Number of yaz0 blocks at the end of the file.
0x46c 20 Probably Padding.
0x48c End of replay header.

Replay Header

After the replay header, offsets to each replay data section (see below) and yaz0 block are located.

Replay Header
Offset Size Description
0x48c 4 First section offset in the replay data, relative to the start of the replay infos.
0x490 Offsets to all other sections in the replay data follow. Number of sections is indicated earlier at offset 0x45c.
- 4 First yaz0 block offset, relative to the start of the replay infos.
- Offsets to all other yaz0 blocks follow. Number of yaz0 blocks is indicated earlier at offset 0x468.

Unknown Data

Some unknown data follows. When modifying the ghost and setting all this data to 0, the game still accepts the ghost, though the ghost no longer replays and warps below the track (like the coordinate origin). Coins and laps are also no longer properly counted.

Replay Data

Replay data consists of a number of sections. Each of these sections is identical in structure, and represents a portion of the replay for some number of frames (likely 64 frames). These sections all consist of an equal number of subsections (indicated at offset 0x410), though some of these subsections can be absent.

Replay Data Section
Offset Size Description
0x00 4 CRC-32 Checksum over the data after this checksum until the end of the section.
0x04 2 Size of the first subsection in this section, or 0xff if the subsection is absent.
0x06 Sizes of all other subsections in this section follow.
- - Data of the first subsection.
- Data of all other subsections in this section follows.

Each of these subsections contains data for a specific part of the replay for some number of frames. Note that the lengths of subsections at the same index of a section can have different lengths. For example, the first subsection of the first and second section in the replay data may have different lengths. The cause for this is currently unknown.

Each subsection is responsible for the following parts of a replay. The subsection indices below assume a 4-wheel vehicle was used.

Replay Data Subsections
Subsection Index Description
0 Coin & Lap Count. Coin and Lap values can occur more than once in a single subsection. Coin count is located at offset -1 (i.e., relative to the end of the section). Lap count at offset -10 from the first coin value.
1 Unknown SFX. For example, includes the glider tunnel SFX (but not the glider SFX itself) in Big Blue
2 Kart Position & Drift/Mushroom item VFX & Directional Controller Inputs.
3 Driver rotation & Kart Scale & Glider Popup.
4 Unknown. Always absent entirely.
5 Front-Left Wheel Position & Rotation.
6 Front-Right Wheel Position & Rotation.
7 Back-Left Wheel Position & Rotation.
8 Back-Right Wheel Position & Rotation.
9 Item Slot UI & Various VFX. VFX includes things like items (E.g. the super horn), map objects (E.g. GBA Mario Circuit oil slicks), spin boosts, or bump/crash stars. VFX does not include kart drift, or the purple circle VFX when collecting coins on the F-zero tracks.
10 Driver Rotation & Scale. Possibly includes animations as well.
11 Camera. Influences the behaviour of the camera.
12 Unknown.
13 Item State, like the shroom count. Does not control the UI.
14 Unknown.
15 Kart SFX. SFX includes coin collection, tricks, and glider activation.
16 Driver SFX.

Tools

The following tools can handle Ghost Data (DAT) files:

  • MK8Leaderboards: Fetches and formats data from the time trial leaderboards. Includes a Discord bot.
  • Poltergust: A (staff) ghost visualisation, extraction, and conversion tool.