Earth 2150 MSH file format - Henkoglobin/kfr-reader GitHub Wiki

What we know so far

Note: For the sake of wording, every paragraph will introduce a name for the values described. These names are not be taken at face value; they are really only there in order to simplify talking about values.

Note: A quick note on notation: When talking about addresses, the values are formatted in big endian; so 0x00000004 equals the fourth address of the fourth byte. This is due to the fact that hex editors generally use this notation. When talking about values, however, the notation is in little endian (0x04000000 equals the integer value 4) because that's the way the files are laid out in memory. Let's hope this doesn't get too confusing.

  • There are 1149 files in a standard Meshes.wd file (taken from the Steam version of TMP)
  • TMP and LS (at least the Steam versions) ship with the same Meshes.wd
    • If anyone has a non-Steam wd file, I'd be interested in seeing if there are any differences. Does Steam ship with ReBa?

Binary File Layout

Every MSH file has a 4-byte prefix at address 0x00000000:

For lack of a better name, we'll call the files with the prefix 0xFFA1D020 'model files' from now on, while the files with the prefix 0xFFA1D030 will be called 'effect files'. All "interesting" files (i.e. Unit/Weapon/Building meshes) seem to have the 0xFFA1D020 prefix.

The four bytes following the prefix seem to be an index (starting at address 0x00000004). It's counting up for some models (LCUFG1.msh has 0x2c as the first byte of the index, LCUFG2.msh has 0x2d, LCUFG3.msh has 0x2e). All effect files have the index 0x01 0x00 0x00 0x00, while all model files have unique values.

The next 12 bytes are not clear yet; they might still belong to the index (possibly making it a GUID), but it could also be some kind of configuration. We'll call them unknown values for now (address 0x00000008). For effect files, there are no two files sharing the same unknown value. For model files, on the other hand, the situation is less clear: Most model files share a couple of values (listed below), but there are also some model files that have unique unknown values.

Known unknown values (for model files):

  • 827bd311 a68300a0 c9df5907 - 623 files
  • 3a62d411 ab0000a0 c96683e9 - 141 files
  • 9ccdd311 aafb00a0 c96683e9 - 93 files
  • 6473d411 ab0000a0 c96683e9 - 26 files
  • (Some other values with 7 or less files each)

Following on, all model files have the sequence 4d455348 (at address 0x00000014), which, when encoded in ANSI, reads "MESH". We call this the type. All effect files, on the other hand, have either c9df5907 (186 files) or c96683e9 (8 files) at this position. However, effect files have the "MESH" sequence in the following four bytes (starting at 0x00000018).

The next four bytes (at address 0x00000018) are either 0x01000000 for model files or "MESH" (4d455348) for effect files. We'll call this the subtype.

The files are in Little Endian format, which is the native format for Windows. This allows us to use BitConverter.ToInt32() to convert bytes to integers. The BitConverter class also has methods to interpret byte arrays as floats, which will come in handy later.

The Endianness can be observed when looking for the textures used in a mesh. For example, LCUFG1.msh (the LC Fat Girl c2) specifies the texture Textures\SIDECOLOR.tex, a 22-character string (found at address 0x0046af of the file). The four bytes immediately before that specify the length of that string: 0x16 0x00 0x00 0x00, which, in little-endian, is equal to 22.