GBX

From TM Wiki

Jump to: navigation, search

GBX is the Nadeo Games File Format. It is used throughout the software to store different types of data.

Contents

GBX File Types

Any GBX file header starts with the string "GBX" followed by bytes 06 00, followed by the string "BUCR" (or very rarely "BUCE"). One exception are some very old Texture.Gbx files (dated 2003 and older) in TMN's Resource\Media\Texture\ folder, which use bytes 03 00 here, followed by "TUU9". This obsolete format has not been investigated further.

The next four bytes define the GBX file type. Here is a table of known values and file types:

00 90 03 09  AudioEnvironment (TMO/TMS/TMN)
00 30 00 24  Challenge (TMO/TMS/TMN/TMU)
00 30 04 03  Challenge (TMF)
00 80 03 24  ConstructionCampaign (TMO/TMS/TMU)
00 00 09 03  ConstructionCampaign (TMF)
00 C0 01 07  ControlEffectMaster (TMF only)
00 70 01 07  ControlStyle (TMF only)
00 D0 03 03  GameAdvertisement
00 60 02 01  FidCache
00 50 01 05  FuncShader (TMO/TMS/TMN)
00 00 09 03  GameCtnCampaign (TMF)
00 B0 01 24  Ghost (TMO/TMS/TMN/TMU)
00 20 09 03  Ghost (TMF)
00 E0 0E 03  LadderScores (TMF only)
00 20 02 06  LightMapCache
00 10 06 03  Manager (TMF only)
00 C0 01 09  Music
00 A0 04 24  Profile (TMO/TMS/TMN)
00 50 0B 24  Profile (TMU/TMF)
00 E0 07 24  Replay
00 F0 03 24  Replay (AutoSave; TMO/TMS/TMN/TMU)
00 30 09 03  Replay (AutoSave; TMF)
00 40 03 24  Scores (TMO/TMS/TMN/TMU)
00 D0 08 03  Scores (TMF)
00 70 06 01  Script (TMF only)
00 50 00 09  Solid
00 A0 01 09  Sound
00 40 06 09  Sound (TMS only)
00 E0 08 09  Sound (TMS only)
00 E0 08 09  SoundEngine (TMO/TMS only)
00 E0 05 09  SoundSurface (TMO/TMS only)
00 50 00 0B  SystemConfig
00 20 02 24  TMEDClassic (TMO/TMS only)
00 10 01 09  Texture
00 10 00 24  TrackMania (Dedicated)

The last byte appears to differentiate - with a few exceptions - between GBX categories like assets (sounds, music, textures, etc.) and game data (challenges, replays, profiles, etc.) with the preceding two bytes narrowing down the file type, so here is the table again sorted by those values from last to first byte:

00 60 02 01  FidCache
00 70 06 01  Script (TMF only)
00 D0 03 03  GameAdvertisement
00 30 04 03  Challenge (TMF)
00 10 06 03  Manager (TMF only)
00 D0 08 03  Scores (TMF)
00 00 09 03  ConstructionCampaign (TMF)
00 00 09 03  GameCtnCampaign (TMF
00 20 09 03  Ghost (TMF)
00 30 09 03  Replay (AutoSave; TMF)
00 E0 0E 03  LadderScores (TMF only)
00 50 01 05  FuncShader (TMO/TMS/TMN)
00 20 02 06  LightMapCache
00 70 01 07  ControlStyle (TMF only)
00 C0 01 07  ControlEffectMaster (TMF only)
00 50 00 09  Solid
00 A0 01 09  Sound
00 C0 01 09  Music
00 10 01 09  Texture
00 90 03 09  AudioEnvironment (TMO/TMS/TMN)
00 E0 05 09  SoundSurface (TMO/TMS only)
00 40 06 09  Sound (TMS only)
00 E0 08 09  Sound (TMS only)
00 E0 08 09  SoundEngine (TMO/TMS only)
00 50 00 0B  SystemConfig
00 10 00 24  TrackMania (Dedicated)
00 30 00 24  Challenge (TMO/TMS/TMN/TMU)
00 B0 01 24  Ghost (TMO/TMS/TMN/TMU)
00 20 02 24  TMEDClassic (TMO/TMS only)
00 40 03 24  Scores (TMO/TMS/TMN/TMU)
00 80 03 24  ConstructionCampaign (TMO/TMS/TMU)
00 F0 03 24  Replay (AutoSave; TMO/TMS/TMN/TMU)
00 E0 07 24  Replay
00 A0 04 24  Profile (TMO/TMS/TMN)
00 50 0B 24  Profile (TMU/TMF)

Note that in TMS, one byte string (00 E0 08 09) is used for two file types, and the Sound file type is represented by three different byte strings. Possibly these are mix-ups from the early development of that game. A handful of other GBX types appear to exist, such as TMDecoration, TMEDClip, TMEDFlat, TMEDPylon, TMEDRectAsym, TMEDRoad, TMZoneFlat and Scene3d, but no non-empty files are available for them so their type byte string cannot be determined.

Only the Challenge and Replay formats have been researched in more detail here.

GBX Challenge Format

There are two main blocks (Header and Data) in the Challenge file format, the XML block in all versions except TM and TM PowerUp, and a TMU/TMF-only block:

  • The Header block
  • The XML block
  • The Thumbnail/Comment block (TMU/TMF)
  • The Data block

This section describes how to extract each of the blocks, as well as how to decode the Header block.

The Header Block

We've reversed engineered most of the headers of the Challenge GBX format. All integers in the file are in "Intel Byte Order" (little-endian). This is initially based on TrackMania Nations ESWC and TrackMania United, with additional notes on TrackMania Original and TrackMania Sunrise merged in with later revisions of this section, and finally notes on TrackMania Forever. Some offsets may be different, as strings can be any length... these are marked with +len. Offsets that aren't fixed (ie. they move based on the length of preceding strings) are prepended with a star.

If you are looking for easy solutions, see Applications and Libraries that can inspect the file format.

0000 - 0002: STR: "GBX", the header magic.
0003 - 0004: STR: 06 00.  Not sure if it's part of the magic, but it probably is.
0005 - 0008: STR: usually "BUCR", very rarely "BUCE"; more header magic?
0009 - 000C: GBX type: Challenge (00 30 00 24 before TMF; 00 30 04 03 in TMF)
000D - 0010: INT32: Header size, including XML block etc. (= offset to Data block)
Index Block - types and lengths of other blocks between Index and Data blocks:
0011 - 0014: INT32: Challenge version, ie. count of marker/length pairs in the following table:
             2 in TM; 3 in TM PowerUp; 4 in TMO (aka. TM LevelUp) and TMS/TMN; 5 in TMU/TMF.
0015 - 0018: Marker 1 (02 30 00 24 before TMF; 02 30 04 03 in TMF)
0019 - 001C: INT32: Length 1, "Times/info" block:
             0x15 for version 2
             0x19 for version 3, exever="0.1.2.0-5"
             0x21 for version 3, exever="0.1.3.0-2" & version 4, exever="0.1.3.3-0.1.4.1"
             0x25 for version 4, exever="0.1.4.3-6"
             0x29 for version 4, exever>="0.1.4.8" and version 5, exever<="2.11.4"
             0x2D for version 5, exever>="2.11.5"
001D - 0020: Marker 2 (03 30 00 24 before TMF; 03 30 04 03 in TMF)
0021 - 0024: INT32: Length 2, Strings block
(The next pair is present only in versions >= 3)
0025 - 0028: Marker 3 (04 30 00 24 before TMF; 04 30 04 03 in TMF)
0029 - 002C: INT32: Length 3, Version? block (always 0x04)
(The next pair is present only in versions >= 4)
002D - 0030: Marker 4 (05 30 00 24 before TMF; 05 30 04 03 in TMF)
0031 - 0034: INT32: Length 4, XML block (high-bit set in v5)
(The next pair is present only in versions >= 5)
0035 - 0038: Marker 5 (07 30 00 24 before TMF; 07 30 04 03 in TMF)
0039 - 003C: INT32: Length 5, Thumbnail/Comments block (high-bit set)
(Note that the last three bytes in all markers are identical to those in the GBX type.)
(Further addresses are shown to illustrate version 4, exever>="0.1.4.8" only, and vary for other versions)
Start of "Times/info" block:
0035 - 0035: INT8: count of "Times/info" INT32s (well... sorta):
             3 in version 2 (actual INT32s count is 5)
             4 in version 3, exever="0.1.2.0-5" (actual count is 6)
             6 in version 3, exever="0.1.3.0-2" (actual count is 8)
             7 in version 4, exever="0.1.3.3-0.1.4.0" (actual count is 8)
             8 in version 4, exever="0.1.4.1" (no unknown2 & author score)
             9 in version 4, exever="0.1.4.3-6" (no author score)
             10 in version 4, exever>="0.1.4.8", and version 5, exever<="2.11.4"
             11 in version 5, exever>="2.11.5"
0036 - 0039: INT32: Unknown1 (always 0)
003A - 003D: INT32: Bronze Medal time, in milliseconds, or Bronze Stunts score.
003E - 0041: INT32: Silver Medal time, in milliseconds, or Silver Stunts score.
0042 - 0045: INT32: Gold Medal time, in milliseconds, or Gold Stunts score.
0046 - 0049: INT32: Author's best time, in milliseconds.
(The next field is present only in versions >= 3)
004A - 004D: INT32: Price of the challenge in coppers.
(The next two fields are present only in version 3, exever>="0.1.3.0" & versions >= 4)
004E - 0051: INT32: Multilap flag: 0 if nblaps="0", otherwise 1.
0052 - 0055: INT32: Track type: 0 (Race), 1 (Platform), 2 (Puzzle), 3 (Crazy), 5 (Stunts)
(The next field is present only in versions >= 4, exever>="0.1.4.3")
0056 - 0059: INT32: Unknown2 (always 0 in v4; sometimes >0 in v5, e.g. 9, 12, 15, 16)
(The next field is present only in versions >= 4, exever>="0.1.4.8")
005A - 005D: INT32: Author score/time, or Author Stunts Score.
(The next field is present only in versions >= 5, exever>="2.11.5")
005E - 0061: INT32: Unknown3
(As before, further addresses are shown to illustrate version 4, exever>="0.1.4.8" only, and vary for other versions)
Start of Strings block (version 2):
Start of Version? block (versions >= 3):
005E - 0061: INT32: 0x0300 for version 2
                    0x0301 for version 3 & version 4, exever="0.1.3.3-0.1.4.0"
                    0x0302 for version 4, exever="0.1.4.1-6"
                    0x0303 for version 4, exever="0.1.4.8" (rare)
                    0x0304 for version 4, exever>="0.1.4.8"
                    0x0305 for version 5
GBX Strings are always length immediately followed by the string data, with no terminating character.
Length can be 0, in which case there's no string data behind it.
Start of Strings block (versions >= 3):
0062 - 0062: single Byte (always 00)
0063 - 0066: Unknown (00 00 00 80)
0067 - 006A: INT32: The length of the track's UID (usually 27, sometimes 26).
006B - 0085: STR: The track's UID.
*0086 - 0089: Unknown (00 00 00 40)
*008A - 008D: INT32: The length of the track's location/environment.
*008E - +len: STR: The track's location/environment.
*0095 - 0098: Unknown (00 00 00 [40|80])
*0099 - 009C: INT32: The length of the author's name.
*009D - +len: STR: The author's name.
*00A5 - 00A8: INT32: The length of the track name.
*00A9 - +len: STR: The name of the track.
*00BA - 00BA: single Byte (almost always 08)
(The following strings are present only in versions >= 3)
*00BB - 00BE: Unknown (varies... a lot)
(The following string is always empty in version >= 5, exever>="2.11.2")
*00BF - 00C2: INT32: The length of the obfuscated password.
*00C3 - +len: STR: The obfuscated password.
(The following strings are present only in versions >= 4, exever>="0.1.4.1")
*00CC - 00CF: Unknown (00 00 00 40)
*00D0 - 00D3: INT32: The length of the track "mood".
*00D4 - +len: STR: The track "mood".
*00D7 - 00DA: Unknown (02 00 00 40)
*00DB - 00DE: Publisher flag: 03 00 00 40 if no publisher field, otherwise 00 00 00 40
*00DF - 00E2: INT32: The length of the name of the game publisher.
*00E3 - +len: STR: The name of the game publisher.  Always "Nadeo" (but often missing on Nadeo's own tracks).

The Strings block is followed by a varying number of INT32s (none in version 2). It is possible to get to the end of the Header block in versions >= 3 by reading INT32s until you get the number 2 (in version 3), 3 (version 4, exever="0.1.3.0-3"), 4 (version 4, exever="0.1.3.4-0.1.4.1"), 5 (version 4, exever>="0.1.4.3") or 6 (version 5). Really. Therefore this is not recommended.

So, the only correct way to get to the start of the next block in any Challenge version - the Data block in versions 2 & 3, or the XML block in versions 4 & 5 - is to add Length 2 to the start of the Strings block.

The XML Block

Challenge version 4 & 5 files contain an XML block, reached as described above. To extract it, there will be the following variables:

INT32: The length of the track's XML block.
STR: XML block describing the track metadata.

The XML block can also be parsed by manually searching for the XML tag called "header", however this is unreliable as it is possible to create "false" XML blocks for your program to encounter. It isn't recommended, though some programs use this method.

The XML block contains everything the Header block does, except for the password. Unlike the Header block, however, it also contains the list of dependencies for the track (images, mods, music, etc.), as well as the version number of the software that created the track, the actual number of laps, and an optional Mod name.

The Thumbnail/Comments Block

Challenge version 5 files (TMU/TMF) contain a block with a thumbnail image and an optional comment, starting right after the XML block. The format is:

INT32: 01 00 00 00
INT32: Length of Thumbnail data
STR: "<Thumbnail.jpg>"
STR: Thumbnail data
STR: "</Thumbnail.jpg>"
STR: "<Comments>"
INT32: Length of Comments data
STR: Comments data
STR: "</Comments>"

The combined length of all these fields matches Length 5 in the Header block.

The thumbnail image itself is stored upside-down, and is always 256x256 pixels.

The Data Block

You should read three INT32s after reading the Header, optional XML and optional Thumbnail/Comments blocks. Don't know what they are either, but the second one is always 0. Your pointer in the file should then be up to the track Data block contents.

Alternatively, add 0x11 to the Data block offset to get to the start of the Data block, then read the three INT32s.

This block contains opcodes that describe the track, as well as all the locator URLs, and basically all the data previously described in the Header and XML blocks. To extract the Data block contents:

INT32: The length of the track's Data block contents.
STR: The track Data block contents.

Very little is known about the format of the Data block contents, and it is best avoided. After the Data block, the Challenge file ends.

Password Obfuscation Algorithm

The obfuscation algorithm uses XOR. It is very simple to decode, however we will not explain it here. The long and short of it is that you are quite easily able to decode the password into plaintext, anyone can do it, so don't store your login password as the track's password.

GBX Replay Format

There are two main blocks (Header and Data) in the Replay file format, and the XML block in version 2:

  • The Header block
  • The XML block
  • The Data block

This section describes how to extract each of the blocks, as well as how to decode the Header block.

The Header Block

We've reversed engineered most of the headers of the Replay GBX format. All integers in the file are in "Intel Byte Order" (little-endian). Some offsets may be different, as strings can be any length... these are marked with +len. Offsets that aren't fixed (ie. they move based on the length of preceding strings) are prepended with a star.

Again, if you are looking for easy solutions, see Applications and Libraries that can inspect the file format.

0000 - 0002: STR: "GBX", the header magic.
0003 - 0004: STR: 06 00.  Not sure if it's part of the magic, but it probably is.
0005 - 0008: STR: usually "BUCR", very rarely "BUCE"; more header magic?
0009 - 000C: GBX type: Replay (00 E0 07 24; 00 F0 03 24 AutoSave before TMF; 00 30 09 03 AutoSave in TMF)
000D - 0010: INT32: Header size, including XML block etc. (= offset to Data block)
Index Block - types and lengths of other blocks between Index and Data blocks:
0011 - 0014: INT32: Replay version, ie. count of marker/length pairs in the following table:
             1 in TM; 2 in all other games
0015 - 0018: Marker 1 (00 F0 03 24 before TMF; 00 30 09 03 in TMF)
0019 - 001C: INT32: Length 1, Strings block (always 0x04 in version 1)
(The next pair is present only in version 2)
001D - 0020: Marker 2 (01 F0 03 24 before TMF; 01 30 09 03 in TMF)
0021 - 0024: INT32: Length 2, XML block
(Note that the last three bytes in all markers are identical to those in the GBX type - AutoSave)
(Further addresses are shown to illustrate version 2 only, and vary for other versions)
GBX Strings are always length immediately followed by the string data, with no terminating character.
Length can be 0, in which case there's no string data behind it.
Start of Strings block:
0025 - 0028: INT32: Strings type:
             1 -> no strings present
             3 -> all strings excluding login field (TMS, exever<"0.1.4.5")
             4 -> all strings excluding login field (TMO/TMS/TMN, exever="0.1.4.5"-"0.1.8.0")
             5 -> all strings excluding login field (TMU beta, exever="0.1.8.6")
             6 -> all strings including login field (TMU, exever="0.1.9.0"-"0.2.1.1")
             7 -> all strings including login field (TMF, exever>="2.11.0")
0029 - 002C: Unknown (03 00 00 00)
002D - 0030: Unknown (00 00 00 80)
0031 - 0034: INT32: The length of the track's UID (usually 27, sometimes 26).
0035 - 004F: STR: The track's UID.
*0050 - 0053: Unknown (00 00 00 40)
*0054 - 0057: INT32: The length of the track's location/environment.
*0058 - +len: STR: The track's location/environment.
*005F - 0062: Unknown (00 00 00 [40|80])
*0063 - 0066: INT32: The length of the author's name.
*0067 - +len: STR: The author's name.
*006C - 006F: INT32: The replay time.
*0070 - 0073: INT32: The length of the driver's nickname.
*0074 - +len: STR: The nickname of the driver.
(The remaining string is present only in TMU/TMF, exever>="0.1.9.0")
*0079 - 007C: INT32: The length of the driver's login.
*007D - +len: STR: The login of the driver.

The Strings block is not followed by INT32s like in the Challenge file, so it's not necessary to read any INT32s to get to the end of the Header block.

However, the only correct way to get to the start of the next block in any Replay version - the Data block in version 1, or the XML block in version 2 - is to add Length 1 to the start of the Strings block.

The XML Block

Replay version 2 files contain an XML block, reached as described above. To extract it, there will be the following variables:

INT32: The length of the replay's XML block.
STR: XML block describing the replay metadata.

The XML block can also be parsed by manually searching for the XML tag called "header", however this is unreliable as it may be possible to create "false" XML blocks for your program to encounter, so this isn't recommended.

The XML block contains the UID and replay ("best") time like the Header block. It also contains the version number of the software that created the replay; optionally the respawns count (can be -1 or larger), the Stunts score, and a validable flag; and in recent versions occasionally two checkpoints fields.

The Data Block

You should read three INT32s after reading the Header and optional XML block. Don't know what they are either, but the second one is always 0. Your pointer in the file should then be up to the replay Data block contents.

Alternatively, add 0x11 to the Data block offset to get to the start of the Data block, then read the three INT32s.

This block contains opcodes that describe the replay, and basically all the data previously described in the Header and XML blocks. To extract the Data block contents:

INT32: The length of the replay's Data block contents.
STR: The replay Data block contents.

Very little is known about the format of the Data block contents, and it is best avoided. After the Data block, the Replay file ends.

Other GBX Formats

Many other types of GBX files follow the same basic structure as the Challenge and Replay types above, but don't even have a Header block. Thus, their general layout is as follows:

0000 - 0002: STR: "GBX", the header magic.
0003 - 0004: STR: 06 00.  Not sure if it's part of the magic, but it probably is.
0005 - 0008: STR: usually "BUCR", very rarely "BUCE"; more header magic?
0009 - 000C: GBX type: see section 1
000D - 0010: INT32: Offset to Data block (00 00 00 00)
0011 - 0014: INT32: Unknown (varies)
0015 - 0018: INT32: Unknown (00 00 00 00)
0019 - 001C: INT32: Unknown (varies)
001D - 0020: INT32: The length of the Data block contents.
0021 - +len: STR: The Data block contents.

As before, nothing is known about the format of the Data block contents, and after the Data block the GBX file ends.

Applications and Libraries that can inspect the file format

  • Extract GBX data - a PHP script to extract useful data from all .Challenge.Gbx files (including the thumbnail image), and from .Replay.Gbx files.
  • Tally GBX versions - a PHP script to tally version data from all .Challenge.Gbx files (including sample challenges in all known versions).
  • GBX Data Fetcher - two PHP classes to extract useful data from all .Challenge.Gbx files (including the thumbnail image) and from .Replay.Gbx files, and parse their XML blocks.
  • Replay Parser - a PHP class to extract useful data from Replay data strings (from the GetValidationReplay method), and parse their XML blocks.
  • Blockmix tools - challenge editing tools (Recompressor, ChallengeEdit, GBX-Master)
  • Easy TM
  • Trackmania Disassembler - includes a library allowing you to write your own applications that can read the format.

To do ... translate...

Personal tools
In other languages