Skip to content

Instantly share code, notes, and snippets.

@Puyodead1
Last active July 11, 2023 20:27
Show Gist options
  • Save Puyodead1/ffc7fcf943d248c35be1fbcb2477355b to your computer and use it in GitHub Desktop.
Save Puyodead1/ffc7fcf943d248c35be1fbcb2477355b to your computer and use it in GitHub Desktop.
Unofficial Run8 V3 File Format Specifications

Notice

This is outdated, please see my Run8 V3 Reverse Engineering Repo for up-to-date specs, blender scripts, a POC C# library and more.

Overview

Run8 V3 is a train simulator that strives for realistic physics and operations. My intensions for doing any of this reverse engineering is soley for personal modding of the game, I am making it public only for others who wish to do the same.

All of the information is unofficial and may not be 100% correct. This has been a learning experience for me also as I really didn't know what I was doing, and I've learned a lot about 3d graphics from this.

My accomplishments so far:

  • convert tx8 to dds
  • convert dds to tx8
  • convert basic rn8 geometry to obj
  • convert basic tr4 geometry to obj
  • extract sounds from fmod bank

Todo:

  • converting obj to rn8
  • converting obj to tr4
  • converting avatar rn8 to obj
  • .tkb (form of DDS texture)
  • .veg
  • .r8
  • .ind industry configuration files
  • converting tr2 to obj
  • placing tr4 terrain vegetation into terrain tile
  • placing tr4 terrain props into terrain tile
  • correctly converting all objects in rn8 files with multiple objects
  • blender addon (maybe)

notes on other file formats:

  • .xwb - XACT wave bank
  • .xsb - XML Schema Binary
  • .wx - Microsoft Flight Simulator Weather Format
  • .tr* - has nothing to do with Tomb Raider

just know that i spent a lot of time on this

Other stuff

  • Edit 5/6/2022: I started working on a new project that I'm calling RICE (totally 100% did not come up with that as I started writing this), Run8 Industry Configuration Editor. Windows application that allows for viewing and editing .ind files. You can find the project repository at https://github.com/Puyodead1/Run8IndustryConfigEditor

Contact

Questions, comments, concerns:

A note to Run8 Studios

Why do you not allow your community to mod the game? wtf, your license says users cannot even retexture models... every other train simulator in existance allows modding: MSTS, Trainz, OpenRails, OpenBVE, RailWorks, hell even TSW! The games graphics are straight out of 2007, don't get me wrong, the game in general is fantastic, but the graphics make me weep...

Run8 V3 requires DirectX11-capable Hardware, which has been industry-standard for many years now. Please join the 21st Century ;)

Uno Reverse

DirectX 11 is fukin ancient, 2009.... please join the 21st century and update ur shit

Thank you for coming to my ted talk

  • 5/6/2022:

    • Added industry configurations to TODO list
    • Added note about TR* files
    • Added note about RICE
  • 7/10/2023:

    • Add deprecation notice and note about new repo
    • Add a small message to Run8 Studios
RN8 files are 3d geometry files, there seems to be a few "formats" of rn8
Note: avatar models do not seem to follow any of these formats
Note: Stuff related to what kind of truck to use, wheels, etc are hardcoded and are determined based on the name of the file. I may add a lookup table at some point
format 1 (-969696):
int32 - unknown int (looks like its used to determine the "format")
int32 - number of objects
string - object name
string - parent object name
float - position X offset
float - position Y offset
float - position Z offset
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
float - rotation matrix yaw (degrees)
float - rotation matrix pitch (degrees)
float - rotation matrix roll (degrees)
float - scale matrix x (unused)
float - scale matrix y (unused)
float - scale matrix z (unused)
float - rotation matrix yaw (degrees) (unused)
float - rotation matrix pitch (degrees) (unused)
float - rotation matrix roll (degrees) (unused)
float - rotation matrix yaw (degrees) (unused)
float - rotation matrix pitch (degrees) (unused)
float - rotation matrix roll (degrees) (unused)
float - translation vector X
float - translation vector Y
float - translation vector Z
float - rotation matrix yaw (degrees)
float - rotation matrix pitch (degrees)
float - rotation matrix roll (degrees)
float - scale matrix x (unused)
float - scale matrix y (unused)
float - scale matrix z (unused)
int32 - number of matrices
float - matrix 1
float - matrix 2
float - matrix 3
float - matrix 4
float - matrix 5
float - matrix 6
float - matrix 7
float - matrix 8
float - matrix 9
float - matrix 10
float - matrix 11
float - matrix 12
float - matrix 13
float - matrix 14
float - matrix 15
float - matrix 16
int32 - number of matrices
float - matrix 1
float - matrix 2
float - matrix 3
float - matrix 4
float - matrix 5
float - matrix 6
float - matrix 7
float - matrix 8
float - matrix 9
float - matrix 10
float - matrix 11
float - matrix 12
float - matrix 13
float - matrix 14
float - matrix 15
float - matrix 16
int32 - number of vertices (divide by 7)
vertice:
float - unknown float (unused)
float - position X (* 63.7f - positionOffset.X)
float - normal Y ( / -1.732f)
float - position Z (/ 16f - positionOffset.Z)
float - texture coordinate X (/ 4.8f)
float - normal X (/ 10.962f)
float - unknown float (unused)
float - normal Z (/ 11.432f)
float - texture coordinate Y (/ 9.6f)
float - position Y (* 6f - positionOffset.Y)
int32 - number of textures
texture:
string - texture name
bool - true if index buffer is ushort, false if int32
int32 - number of indecies
indecie:
int32 - indecie (convert to ushort if needed)
int32 - unknown int (- 9) (seems to be number of textures again)
unknown:
float - unknown float (unused)
int32 - texture name index
int32 - index count
int32 - index start location
int32 - base vertex location
format 2 (-969697):
int32 - unknown int (looks like its used to determine the "format")
int32 - number of objects
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
string - object name
string - parent object name
float - position X offset
float - position Y offset
float - position Z offset
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
float - rotation matrix yaw (degrees)
float - rotation matrix pitch (degrees)
float - rotation matrix roll (degrees)
float - scale matrix x (unused)
float - scale matrix y (unused)
float - scale matrix z (unused)
float - rotation matrix yaw (degrees) (unused)
float - rotation matrix pitch (degrees) (unused)
float - rotation matrix roll (degrees) (unused)
float - rotation matrix yaw (degrees) (unused)
float - rotation matrix pitch (degrees) (unused)
float - rotation matrix roll (degrees) (unused)
float - translation vector X
float - translation vector Y
float - translation vector Z
float - rotation matrix yaw (degrees)
float - rotation matrix pitch (degrees)
float - rotation matrix roll (degrees)
float - scale matrix x (unused)
float - scale matrix y (unused)
float - scale matrix z (unused)
int32 - number of matrices
float - matrix 1
float - matrix 2
float - matrix 3
float - matrix 4
float - matrix 5
float - matrix 6
float - matrix 7
float - matrix 8
float - matrix 9
float - matrix 10
float - matrix 11
float - matrix 12
float - matrix 13
float - matrix 14
float - matrix 15
float - matrix 16
int32 - number of matrices
float - matrix 1
float - matrix 2
float - matrix 3
float - matrix 4
float - matrix 5
float - matrix 6
float - matrix 7
float - matrix 8
float - matrix 9
float - matrix 10
float - matrix 11
float - matrix 12
float - matrix 13
float - matrix 14
float - matrix 15
float - matrix 16
int32 - number of vertices (divide by 7)
vertice:
float - unknown float (unused)
float - position X (* 63.7f - positionOffset.X)
float - normal Y ( / -1.732f)
float - position Z (/ 16f - positionOffset.Z)
float - texture coordinate X (/ 4.8f)
float - normal X (/ 10.962f)
float - unknown float (unused)
float - normal Z (/ 11.432f)
float - texture coordinate Y (/ 9.6f)
float - position Y (* 6f - positionOffset.Y)
int32 - number of textures
texture:
string - texture name
bool - true if index buffer is ushort, false if int32
int32 - number of indecies
indecie:
int32 - indecie (convert to ushort if needed)
int32 - unknown int (- 9) (seems to be number of textures again)
unknown:
float - unknown float (unused)
int32 - texture name index
int32 - index count
int32 - index start location
int32 - base vertex location
format 3:
int32 - unknown int (looks like its used to determine the "format")
int32 - number of vertices (divide by 7)
vertice:
float - unknown float (unused)
float - position X (* 63.7f - positionOffset.X)
float - normal Y ( / -1.732f)
float - position Z (/ 16f - positionOffset.Z)
float - texture coordinate X (/ 4.8f)
float - normal X (/ 10.962f)
float - unknown float (unused)
float - normal Z (/ 11.432f)
float - texture coordinate Y (/ 9.6f)
float - position Y (* 6f - positionOffset.Y)
int32 - number of textures
texture:
string - texture name
bool - true if index buffer is ushort, false if int32
int32 - number of indecies
indecie:
int32 - indecie (convert to ushort if needed)
int32 - unknown int (- 9) (seems to be number of textures again)
unknown:
float - unknown float (unused)
int32 - texture name index
int32 - index count
int32 - index start location
int32 - base vertex location
TR4 files are terrain tiles that are compressed with Deflate
string - Texture0 texture name
string - Texture1 texture name
string - Texture2 texture name
string - Texture3 texture name
625 points (25x25 tile)
point:
short - number of vertecies in point
float - V1 X
float - V1 Y
float - V1 Z
float - V2 X
float - V2 Y
float - V2 Z
float - V3 X
float - V3 Y
float - V3 Z
float - Atmosphere Color Z Lat
float - Atmosphere Color Z Long
float - Atmosphere Color X Lat
float - Atmosphere Color X Long
string - Vegetation Texture name (NoProcVeg if none)
int32 - Number of tile props
tile prop:
int32 - number of unknown
unknown:
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
int32 - number of unknown
unknown:
int32 - unknown int
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
float - unknown float
string - unknown string
bool - unknown
string - model name
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
float - unknown vector X
float - unknown vector Y
float - unknown vector Z
int - tile X
int - tile Y
int32 - number of vegetation
vegetation prop:
float - vector position X
float - vector position Y
float - vector position Z
int32 - number of unknown (currently unused)
byte - unknown (looks to be used to create a texture2d)

TX8 files are textures that are "encrypted" DDS files so there isn't really a format for it

the last 32 bytes are an MD5 hash of the file, the rest is the dds image

you need to run a subtract hex operation on both the md5 bytes and the texture bytes (my understanding is that you add/subtract 96 to each byte)

most of this information was obtained from https://www.mediafire.com/file/fea24g6c6m6togs/R8v2_Converter_Suite.zip/file and I didn't do a whole lot of reverse engineering for textures other than the MD5 hash for converting dds back to tx8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment