Grub bundles
A Grub bundle is the general container of ForzaTech: a header, a table of typed blobs, and for each blob a list
of small metadata records. The same container holds .modelbin models, .materialbin materials, .pb and
.swatchbin textures, .shaderbin shader data, .crowdbin crowds and the car colour lists
(ManufacturerColors.bin); what a bundle is for is decided by its blob tags. Proven Over the install, every entry
whose first four bytes are burG has one of those seven extensions, and every .modelbin, .pb, .swatchbin,
.materialbin and .shaderbin is a bundle. Proven
A bundle can sit inside a blob of another: a model’s MatI blobs are material-instance bundles, and a crowd’s ClsL,
Clas, Mdls, Modl, MtlI and Skls blobs are bundles, some of them holding bundles in turn. Proven
Every statement on this page marked Proven · FH6 holds on every bundle of the Steam build’s install, the
nested ones included: the 526,129 bundles of the Tokyo track’s GeoChunks and the zips under media (196,620
models, 191,602 .pb and 126,527 .swatchbin textures, 9,707 materials, 987 shaders, 682 car colour lists and 4
crowds) and the 1,526,529 bundles nested in their blobs. A reader that refuses any value or byte the layout below does not account for reads all
of them, and Doliman100’s reader gives the same blobs, metadata records and payloads on every one.
A tag is a u32 whose big-endian bytes spell its name: Modl is stored as the bytes ldoM, and the bundle’s own tag
Grub as the bytes burG. Proven Names below are written the way the tag reads, not the way the bytes run.
Header
Section titled “Header”Little-endian. Version 1.1 in every bundle.
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 4 | u32 = Grub (bytes burG) | tag | Proven | |
| 0x4 | 1 | u8 = 1 | version major | Proven | |
| 0x5 | 1 | u8 = 1 | version minor | Proven | |
| 0x6 | 2 | u16 = 0 | reserved | Unknown | 0 in every bundle; readers of older versions take a u16 blob count here |
| 0x8 | 4 | u32 | header size | Proven | where the first blob's data starts |
| 0xC | 4 | u32 | total size | Proven | the bundle's length |
| 0x10 | 4 | u32 | blob count | Proven |
The blob records follow at 20, 24 bytes each. Proven
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 4 | u32 | tag | Proven | |
| 0x4 | 1 | u8 | version major | Proven | |
| 0x5 | 1 | u8 | version minor | Proven | |
| 0x6 | 2 | u16 | metadata count | Proven | 8-byte metadata records |
| 0x8 | 4 | u32 | metadata offset | Proven | from the bundle's start |
| 0xC | 4 | u32 | data offset | Proven | from the bundle's start |
| 0x10 | 4 | u32 | data size | Proven | |
| 0x14 | 4 | u32 | data size again | Unknown | equal to the data size in every blob |
A blob's records sit one after another at its metadata offset.
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 4 | u32 | tag | Proven | Name, Id, BBox, TXCH, ATST, XTRA, ... |
| 0x4 | 2 | u16 | size and version | Proven | payload size = value >> 4 (0xFFF: see below), version = value & 0xF |
| 0x6 | 2 | u16 | payload offset | Proven | from this record's own start |
A payload of 0xFFF bytes or more has 0xFFF in its size field and its true size in a u32 just before it; the record’s
offset points past that u32. Proven Only 16 VDCL records of shader bundles are that large. Proven A reader that takes the 12-bit field as the size reads the first 0xFFF bytes of such a payload and, if it
packs payloads itself, misplaces the records after it.
Arrangement
Section titled “Arrangement”The parts follow one another with no byte unaccounted for. Proven
- The header and the blob records.
- For each blob in record order: its metadata records, then their payloads in record order, packed with no gaps. A blob without metadata has its metadata offset where the next blob’s records would start.
- The header ends where the metadata ends, rounded up to 4 with zero bytes, except in 11
.swatchbintextures whose header ends unaligned where the metadata does, so that their first blob’s data starts unaligned. Proven The install’s 11TXCBblobs of version 2.0 are rain masks in the weather textures; that they are those same 11 is Observed on the bundles inspected. - Each blob’s data in record order: the first at the header size, each next one at the previous one’s end rounded up to 4, the gap zero.
- The bundle ends where the last blob’s data ends, rounded up to 4 with zeros, except in 8,418
.swatchbintextures, which end where the data does, 1 to 3 bytes short of that. Proven
A metadata Name payload is a string without a terminator and can be empty. Proven
Blob tags
Section titled “Blob tags”| Tag | Used in | Holds | Confidence |
|---|---|---|---|
Modl |
model | counts, LOD range, material variant table (Models) | Observed |
Mesh |
model | per-mesh draw record | Observed |
VLay, ILay |
model | vertex layout; ILay only in crowd models |
Observed |
IndB, VerB |
model | index and vertex buffers | Observed |
MBuf |
model | morph target deltas | Observed |
Skel, Skin |
model | skeleton and skin weights; every model has a Skel |
Observed |
Mrph |
cars | names of morph weight slots | Observed |
MatI |
model | a material instance: a nested bundle holding a MATI blob (the material it derives from) and an MTPR blob |
Observed |
MATL, MTPR, MTUD |
material (.materialbin) |
the material, its shader parameters (Materials) | Observed |
PARM, VARS, CBMP, TXMP, SPMP, CBEX, DFPR, LSCE, DBLS, TRGT, TXRF, VERS, VERT, SHUD |
shader | parameter names, variants, register maps and programs (Shader containers) | Observed |
TXCB with TXCH metadata |
texture | mip chain and its header (Swatch textures) | Observed |
MNCL |
car colour list | factory paints (Cars) | Observed |
ClsL, Clas, Mdls, Skls, Anim, MdMt, ExtI, MtlI, RigI, MtOv |
crowd | crowd classes, models, skeletons and animations, as nested bundles | Observed |
The blob versions over the install, nested bundles included: Anim 1.0, CBEX 1.0, CBMP 3.1, Clas 3.0, ClsL
1.0, DBLS 1.10, DFPR 2.1, ExtI 1.0, ILay 1.1, IndB 1.0, LSCE 1.10, MATI 1.0, MATL 1.2, MBuf 1.1,
MNCL 2.0, MTPR 2.0, MTUD 1.0, MatI 1.0, MdMt 1.0, Mdls 1.0, Mesh 1.12 and 1.13, Modl 1.0 (crowds), 1.4
and 1.5, Mrph 0.0, MtOv 0.0, MtlI 1.0, PARM 1.2, RigI 1.0, SHUD 1.0, SPMP 3.1, Skel 1.0, Skin 1.1,
Skls 1.0, TRGT 1.1, TXCB 0.0 and 2.0, TXMP 3.1, TXRF 1.1, VARS 1.8, VERS 1.2, VERT 1.1, VLay 1.1,
VerB 1.1. Proven