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 .

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 . ↩

6. Unlike positions, scales are stored as x , y , z . ↩

7. Rotations are stored as x , z , y , w . ↩