GTA III's RenderWare Engine
Kevin Wijsenbach
RenderWare is a graphics engine by Criterion Software that was used by Rockstar for their titles Manhunt, Bully, GTA III, Vice City and San Andreas. GTA's portable successors Liberty City Stories and Vice City Stories use a clone of the original RenderWare engine (called Rockstar Leeds), which was already influenced by Rockstar's next-gen RAGE engine.
The biggest challenge was finding out what to load, and how. I used the website GTAModding as a reference. Second was to figure out how GTA III's data translates to Unity.
Loading the game world goes as follows:
1. Load the models/gta3.img archive file
Process the model files Process the texture archives
2. Load the data/default.dat map listing 3. Load the data/gta3.dat map listing 4. Iterate the item placement instances
Tools I've Used
Name Description Website
RW Analyze Viewer for RenderWare binary stream files Steve's GTA Page
IMG Tool IMG archive editor GTAForums
Hex Fiend Hex editor ridiculous_fish
Archive File
To improve I/O speed, archive files reflect sectors of CD-ROM's. The directory and the raw binary files are stored in separate files, the directory entries are stored in a .dir and the content pointed by the directory in the .img itself.
The directory archive ( .dir ) must have the same name as the .img archive. The directory archive contains no header, just the following structure repeated until the end of the file. Directory Entry
Format Description
uint Offset (in sectors 1)
uint Size (in sectors)
char[24] Name of the file
The .img file itself has no special structure or header, just all the raw binary files pointed by the directory archive.
RenderWare binary stream
RenderWare binary stream files are hierarchically structured binary data files. GTA III's model files use the file extension .dff and texture archives use .txd .
The streams are split up into chunks. Each section has a 12 byte header and can either be empty, contain data or more child chunks. The content depends on the type and parent chunks.
Chunk
Format Description
uint Section type
uint Size
uint Version
Model File ( .dff )
Clump
Chunk Frame List
Chunk Frame
Chunk
Extension
Chunk Geometry List
Chunk Geometry
Chunk Material List
Chunk Material
Chunk Texture (optional)
Chunk String (texture name) Chunk
String (alpha name) Chunk
Extension
Chunk
Atomic
Chunk
Clump
Format Description
uint Atomic count
Frame List
Format Description
uint Frame count
Frame Format Description
Matrix3x3 Rotation matrix
Vector3 Position 2
uint Parent frame index
uint Unknown
Frame List Extension
A frame list may have an extension section. For this section the extension can appear multiple times. The amount of extensions may not match the number of frames, but usually does since the extensions are holding the names of the single frames.
Geometry List
Format Description
uint Geometry count
Geometry Format Description
uint Flags
uint Triangle count
uint Vertex count
uint Morph target count (always 1 )
float Ambient
float Specular
float Diffuse
Color[vertexCount] Vertex colors (only exists if HasColors flag is set)
Texture coordinates (only exists if HasTexCoords flag is Vector2[vertexCount] set)
ushort[triangleCount * 3] Indices 3
Vector4 Bounding sphere
bool Geometry has vertices
bool Geometry has normals
Vector3[vertexCount] Vertices
Vector3[vertexCount] Normals (only if HasNormals flag is set)
Material List
Format Description
uint Material count
uint[materialCount] Instance indices 4
Material Format Description
uint Flags
Color Color
uint Unknown
bool Material is textured
float Ambient
float Specular
float Diffuse
Texture
Format Description
byte Texture filtering
byte Texture wrap
ushort Padding
Geometry Extension
The extension of an geometry can hold a Bin Mesh plugin chunk. A Bin Mesh is an optimized representation of the model topology. Triangles are grouped together into Meshes by their Material.
Format Description
uint Type
uint Mesh count
uint Index count (total)
Bin Mesh Format Description
uint Index count
uint Material index
uint[indexCount] Indices (in reverse order)
Atomic
An atomic section can associate a Frame with a Geometry. They are transformed from object-space based on the transformation rules that are set for the Frame.
Format Description
uint Frame index
uint Geometry index
uint Unknown
uint Unknown
Texture Archive ( .txd )
Texture Dictionary
Texture Native
Texture Dictionary
Format Description
ushort Texture count
ushort Platform ID 5
Texture Native Format Description
uint Platform ID
byte Texture filtering
byte Texture wrap
ushort Padding
char[32] Texture name
char[32] Alpha name
uint Raster format
bool Texture has alpha
ushort Width
ushort Height
byte Bits per pixel
byte Mip map count
byte Raster type
byte Compression
Color[256] Color palette (only exists if the PAL8 raster format flag is set)
uint Amount of bytes to read next
One of two things can happen next:
1. If the PAL8 flag is set, read using the color palette. Each pixel is a byte, which is the palette index. 2. Just read the amount of bytes, and repeat for each mip map.
Map Listing ( .dat )
A .dat file lists which files define the game map.
Each line links to a map file, unless it's empty or starts with # (comment). There are different types of files, so a identifier specifies the filetype. Identifier Filetype
IDE Item definition
TEXDICTION Texture archive
MODELFILE Model file
COLFILE Collision file
IPL Item placement
Item Definition ( .ide )
Item definition files are stored in plain text, and split up into sections.
Each section starts with a four-character identifier. The identifier is followed by the definition entries. Each entry takes one line and every line follows certain rules. Lines can also be empty or commented. The end of a section is terminated by end .
Lines itself are always formatted in the same way differing only in the number of parameters. Parameters are usually separated by , .
Sections
Identifier Description
objs Objects
Timed objects (similar to objs , but also defines the time range the object can be tobj rendered)
hier Cutscene objects
cars Vehicles
peds Pedestrians
path Waypoints for NPC spawns
Object Format Description
int Object ID
string Model name
string Texture name
int Mesh count
int[3] Draw distances
int Object flags
int Time on (if timed object)
int Time off (if timed object)
Vehicle
Format Description
int Object ID
string Model name
string Texture name
string Vehicle type
string Handling ID
string Vehicle class
int Spawn frequency
int Unknown
string Component rules
Pedestrian Format Description
int Object ID
string Model name
string Texture name
string Pedestrian type
string Behaviour
string Animation group
string Cars pedestrian will drive
Collision File ( .col )
Unlike the graphical models, collision models are not only comprised of triangles, but also spheres and boxes. Collision files are stored binary. Format Description
uint Magic ( COLL )
uint Size
char[22] Name
float Bounding sphere radius
Vector3 Bounding sphere center
Vector3 Bounds min
Vector3 Bounds max
uint Collision sphere count
Sphere[sphereCount] Collision spheres
uint Unknown
uint Collision box count
Box[boxCount] Collision boxes
uint Vertex count
Vector3[vertexCount] Vertices
uint Face count
Face[faceCount] Faces
Collision Surface
Format Description
byte Material
byte Flag
byte Brightness
byte Light
Collision Sphere Format Description
float Radius
Vector3 Center
Surface Collision surface
Collision Box
Format Description
Vector3 Min
Vector3 Max
Surface Collision surface
Face
Format Description
uint[3] Triangle indices
Surface Collision surface
Item Placement ( .ipl )
Item placement files are used to create and place different objects, zones of special behaviour or paths in the world. The files are stored in plain text. The structure and format is similar item definition files.
Sections
Identifier Description
inst Instances
zone Ingame zones
cull Zones with special behaviour
pick Weapon pickups
Instance Format Description
int Model ID
string Model name
Vector3 Position
Vector3 Scale 6
Quaternion Rotation 7
Zone
Format Description
string Name
int Type
Vector3 Area min
Vector3 Area max
int Island
string .gtx text file
Screenshots
Types
Section Type public enum SectionType { None = 0, Struct = 1, String = 2, Extension = 3, Texture = 6, Material = 7, MaterialList = 8, FrameList = 14, Geometry = 15, Clump = 16, Atomic = 20, TextureNative = 21, TextureDictionary = 22, GeometryList = 26, MorphPlugin = 261, SkinPlugin = 278, ParticlesPlugin = 280, UVAnimationPlugin = 309, BinMeshPlugin = 1294, Frame = 39056126 }
Geometry Flags
[System.Flags] public enum GeometryFlags { IsTriangleStrip = 1 << 0, HasTranslation = 1 << 1, HasTexCoords = 1 << 2, HasColors = 1 << 3, HasNormals = 1 << 4, IsLit = 1 << 5, ModulateMaterialColor = 1 << 6, HasMultipleTexCoords = 1 << 7, Native = 1 << 24 }
Bin Mesh Type public enum BinMeshType { TriangleList = 0, TriangleStrip = 1 }
Texture Filtering
public enum TextureFiltering { None = 0, Nearest = 1, Linear = 2, MipNearest = 3, MipLinear = 4, LinearMipNearest = 5, LinearMipLinear = 6 }
Raster Format
[System.Flags] public enum RasterFormat { ARGB1555 = 0x0100, RGB565 = 0x0200, RGBA4444 = 0x0300, LUM8 = 0x0400, RGBA32 = 0x0500, RGB24 = 0x0600, RGB555 = 0x0a00, AutoMipMap = 0x1000, PAL8 = 0x2000, PAL4 = 0x4000, MipMap = 0x8000 }
Object Flags [System.Flags] public enum ObjectFlags { Wet = 1 << 0, TimeObjectNight = 1 << 1, AlphaTransparency1 = 1 << 2, AlphaTransparency2 = 1 << 3, TimeObjectDay = 1 << 4, InteriorObject = 1 << 5, Shadows = 1 << 6 }
Vehicle Type
switch (type) { case "car": return Vehicle.Type.Car;
case "boat": return Vehicle.Type.Boat;
case "train": return Vehicle.Type.Train;
case "heli": return Vehicle.Type.Helicopter;
case "plane": return Vehicle.Type.Plane;
default: throw new System.IndexOutOfRangeException(); }
Vehicle Class switch (type) { case "ignore": return (Vehicle.Class)0;
case "normal": return Vehicle.Class.Normal;
case "poorfamily": return Vehicle.Class.PoorFamily;
case "richfamily": return Vehicle.Class.RichFamily;
case "executive": return Vehicle.Class.Executive;
case "worker": return Vehicle.Class.Worker;
case "big": return Vehicle.Class.Big;
case "taxi": return Vehicle.Class.Taxi;
case "special": return Vehicle.Class.Special;
default: throw new System.IndexOutOfRangeException(); }
Pedestrian Type
switch (type) { case "PLAYER1": return Pedestrian.Type.Player1;
case "PLAYER2": return Pedestrian.Type.Player2;
case "PLAYER3": return Pedestrian.Type.Player3; case "PLAYER4": return Pedestrian.Type.Player4; case "CIVMALE": return Pedestrian.Type.MaleCivilian; case "CIVFEMALE": return Pedestrian.Type.FemaleCivilian; case "COP": return Pedestrian.Type.Cop; case "GANG1": return Pedestrian.Type.Gang1; case "GANG2": return Pedestrian.Type.Gang2; case "GANG3": return Pedestrian.Type.Gang3; case "GANG4": return Pedestrian.Type.Gang4; case "GANG5": return Pedestrian.Type.Gang5; case "GANG6": return Pedestrian.Type.Gang6; case "GANG7": return Pedestrian.Type.Gang7; case "GANG8": return Pedestrian.Type.Gang8; case "GANG9": return Pedestrian.Type.Gang9; case "EMERGENCY": return Pedestrian.Type.Emergency; case "FIREMAN": return Pedestrian.Type.Fireman; case "CRIMINAL": return Pedestrian.Type.Criminal; case "_UNNAMED": return Pedestrian.Type.Unnamed;
case "PROSTITUTE": return Pedestrian.Type.Prostitute;
case "SPECIAL": return Pedestrian.Type.Special;
default: throw new System.IndexOutOfRangeException(); }
1. Every file contained in the img archive is aligned, where each sector is 2048 bytes, so values for offset and size have to be multiplied by 2048. This means that even smaller files will take up 2048 bytes. ↩
2. Positions are stored as x , z , y . ↩
3. Stored as an array of triangles ( ushort vertex2, ushort vertex1, ushort material ID, ushort vertex3). ↩
4. If the material is an instance of a previously defined material, the index equals the base materials one (otherwise it's -1 ). ↩
5. 1 for D3D8, 2 for D3D9, 6 for PlayStation 2, 8 for XBOX. ↩
6. Unlike positions, scales are stored as x , y , z . ↩
7. Rotations are stored as x , z , y , w . ↩