gtChunk - themeldingwars/Documentation GitHub Wiki
.gtchunk files are used along with zone / gtzone and worldDir files.
They represent chunks, a playable piece of the game world.
They contain a version that must match the version the game is expecting.
A Chunk is made up of node layers and those nodes can have sub layers. Some nodes are compressed as well.
- Importing chunk from serialized data...
- Imported file does not appear to be a world file
- You need to use a more current version of the software. Try SVN update with appropriate Loading chunk file v. (code built for v.)
- Invalid number of physics material ids
- Failed to read world chunk data
- Error while loading MOPP data:
- ...chunk loading succeeded.
The chunk format contains a small index of data at the top followed by several compressed blocks of data.
The index is parsed on map load, and the offsets of the compressed blocks of data are stored.
The compressed blocks represent chunk data at different levels of detail, and are loaded and unloaded on demand.
The chunks all store the data in the following order, with offsets included in the index:
| Data |
|---|
| Root/Index |
| LOD-0 Shared Data |
| LOD-0 SubChunk 0x0 Data |
| LOD-1 Shared Data |
| LOD-1 SubChunk 0x0 Data |
| LOD-2 Shared Data |
| LOD-2 SubChunk 0x0 Data |
| LOD-2 SubChunk 1x0 Data |
| LOD-2 SubChunk 0x1 Data |
| LOD-2 SubChunk 1x1 Data |
| LOD-3 SubChunk 0x0 Data |
| LOD-3 SubChunk 1x0 Data |
| LOD-3 SubChunk 2x0 Data |
| LOD-3 SubChunk 3x0 Data |
| LOD-3 SubChunk 0x1 Data |
| LOD-3 SubChunk 1x1 Data |
| LOD-3 SubChunk 2x1 Data |
| LOD-3 SubChunk 3x1 Data |
| LOD-3 SubChunk 0x2 Data |
| LOD-3 SubChunk 1x2 Data |
| LOD-3 SubChunk 2x2 Data |
| LOD-3 SubChunk 3x2 Data |
| LOD-3 SubChunk 0x3 Data |
| LOD-3 SubChunk 1x3 Data |
| LOD-3 SubChunk 2x3 Data |
| LOD-3 SubChunk 3x3 Data |
| LOD-4 Shared Data |
| LOD-4 SubChunk 0x0 Data |
| LOD-4 SubChunk 1x0 Data |
| LOD-4 SubChunk 2x0 Data |
| LOD-4 SubChunk 3x0 Data |
| LOD-4 SubChunk 4x0 Data |
| LOD-4 SubChunk 5x0 Data |
| LOD-4 SubChunk 6x0 Data |
| LOD-4 SubChunk 7x0 Data |
| LOD-4 SubChunk 0x1 Data |
| LOD-4 SubChunk 1x1 Data |
| LOD-4 SubChunk 2x1 Data |
| LOD-4 SubChunk 3x1 Data |
| LOD-4 SubChunk 4x1 Data |
| LOD-4 SubChunk 5x1 Data |
| LOD-4 SubChunk 6x1 Data |
| LOD-4 SubChunk 7x1 Data |
| LOD-4 SubChunk 0x2 Data |
| LOD-4 SubChunk 1x2 Data |
| LOD-4 SubChunk 2x2 Data |
| LOD-4 SubChunk 3x2 Data |
| LOD-4 SubChunk 4x2 Data |
| LOD-4 SubChunk 5x2 Data |
| LOD-4 SubChunk 6x2 Data |
| LOD-4 SubChunk 7x2 Data |
| LOD-4 SubChunk 0x3 Data |
| LOD-4 SubChunk 1x3 Data |
| LOD-4 SubChunk 2x3 Data |
| LOD-4 SubChunk 3x3 Data |
| LOD-4 SubChunk 4x3 Data |
| LOD-4 SubChunk 5x3 Data |
| LOD-4 SubChunk 6x3 Data |
| LOD-4 SubChunk 7x3 Data |
| LOD-4 SubChunk 0x4 Data |
| LOD-4 SubChunk 1x4 Data |
| LOD-4 SubChunk 2x4 Data |
| LOD-4 SubChunk 3x4 Data |
| LOD-4 SubChunk 4x4 Data |
| LOD-4 SubChunk 5x4 Data |
| LOD-4 SubChunk 6x4 Data |
| LOD-4 SubChunk 7x4 Data |
| LOD-4 SubChunk 0x5 Data |
| LOD-4 SubChunk 1x5 Data |
| LOD-4 SubChunk 2x5 Data |
| LOD-4 SubChunk 3x5 Data |
| LOD-4 SubChunk 4x5 Data |
| LOD-4 SubChunk 5x5 Data |
| LOD-4 SubChunk 6x5 Data |
| LOD-4 SubChunk 7x5 Data |
| LOD-4 SubChunk 0x6 Data |
| LOD-4 SubChunk 1x6 Data |
| LOD-4 SubChunk 2x6 Data |
| LOD-4 SubChunk 3x6 Data |
| LOD-4 SubChunk 4x6 Data |
| LOD-4 SubChunk 5x6 Data |
| LOD-4 SubChunk 6x6 Data |
| LOD-4 SubChunk 7x6 Data |
| LOD-4 SubChunk 0x7 Data |
| LOD-4 SubChunk 1x7 Data |
| LOD-4 SubChunk 2x7 Data |
| LOD-4 SubChunk 3x7 Data |
| LOD-4 SubChunk 4x7 Data |
| LOD-4 SubChunk 5x7 Data |
| LOD-4 SubChunk 6x7 Data |
| LOD-4 SubChunk 7x7 Data |
Chunks have 5 levels of detail. The levels of detail range from 0 to 4 with 0 being the lowest and 4 being the highest.
For each level of detail, the chunk format contains 1 "Shared" block of data, and 1 to several "SubChunks". At the highest level of detail, the chunk is segmented into 64 separate parts, while at the lowest level of detail, it is not segmented and the whole chunk is just 1 piece.
The level of detail partitions are as follows:
| LOD | SubChunks |
|---|---|
| 0 | 1 |
| 1 | 1 |
| 2 | 4 |
| 3 | 16 |
| 4 | 64 |
As you traverse the game world, the game will dynamically load and replace chunks and SubChunks based on your distance and their bounding boxes.
At LOD 4, SubChunks are referred to in the following way in-game, with 0x0 representing the bottom left corner:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
|---|---|---|---|---|---|---|---|---|
| 7 | 0x7 | 1x7 | 2x7 | 3x7 | 4x7 | 5x7 | 6x7 | 7x7 |
| 6 | 0x6 | 1x6 | 2x6 | 3x6 | 4x6 | 5x6 | 6x6 | 7x6 |
| 5 | 0x5 | 1x5 | 2x5 | 3x5 | 4x5 | 5x5 | 6x5 | 7x5 |
| 4 | 0x4 | 1x4 | 2x4 | 3x4 | 4x4 | 5x4 | 6x4 | 7x4 |
| 3 | 0x3 | 1x3 | 2x3 | 3x3 | 4x3 | 5x3 | 6x3 | 7x3 |
| 2 | 0x2 | 1x2 | 2x2 | 3x2 | 4x2 | 5x2 | 6x2 | 7x2 |
| 1 | 0x1 | 1x1 | 2x1 | 3x1 | 4x1 | 5x1 | 6x1 | 7x1 |
| 0 | 0x0 | 1x0 | 2x0 | 3x0 | 4x0 | 5x0 | 6x0 | 7x0 |
Every node starts with the layer header described on the zone page: the marker 0x12ED5A12ED5B12ED, a uint32 id and a uint32 length.
The fields below follow that header.
CHUNK, the root node:
| Field | Type | Notes |
|---|---|---|
version |
uint32 |
8 in 1962 |
timestamp |
uint64 |
Unix time in milliseconds |
numLods |
uint32 |
5 |
lods |
CHUNK_LOD[numLods] |
CHUNK_LOD:
| Field | Type | Notes |
|---|---|---|
lodIdx |
uint32 |
|
subChunkExponent |
int32 |
The number of SubChunks is 4 to the power of this, 1 << 2 * subChunkExponent
|
dataOffset |
uint32 |
Offset of the shared data block |
compressedSize |
int32 |
Size of the block, including its id |
uncompressedSize |
int32 |
|
subChunks |
CHUNK_SUBCHUNK[] |
One per SubChunk |
CHUNK_SUBCHUNK:
| Field | Type | Notes |
|---|---|---|
dataOffset |
uint32 |
Offset of the SubChunk data block |
compressedSize |
int32 |
Size of the block, including its id and the LZMA properties |
uncompressedSize |
int32 |
|
boundsMin |
float[3] |
|
boundsMax |
float[3] |
Note that the data offsets are relative to the end of the root node, i.e. 16 bytes of header plus the root node's length, not to the start of the file.
The data blocks are compressed, in 1962 the shared blocks use zlib and the SubChunk blocks LZMA. The id at the start of each block tells which one it is, so pick the decompressor by the id and not by the position of the block:
| Id | Layout |
|---|---|
DATA |
char[4] id, then a zlib stream (2 byte header, deflate, Adler-32) |
DAT2 |
char[4] id, byte[5] LZMA properties, then a raw LZMA stream |
The LZMA stream has no size in front of it, it decodes to the uncompressedSize of the index node.
Within the data blocks are layer/nodes parsed in the same manner as the root/index and zone layer, described in the next section.
The following nodes only occur at the top of the file and describe where to find the rest of the data.
| Name | ID | Parent | Description |
|---|---|---|---|
| CHUNK |
0x40000 (262144) |
Root node of the index. | |
| CHUNK_LOD |
0x40001 (262145) |
CHUNK | Represents a LOD, contains offset and size for Shared Data. |
| CHUNK_SUBCHUNK |
0x40002 (262146) |
CHUNK_LOD | Represents a SubChunk, contains its offset, size and bounds. |
The following nodes occur as part of the data blocks.
| Name | ID | Description |
|---|---|---|
| CHUNK_TERRAIN |
0x040100 (262400) |
Contains child nodes for the visual representation of the base terrain. |
| CHUNK_COLLISION1 |
0x040101 (262401) |
Static geometry collision. Only appears on LOD 3. Collision data for terrain and static objects. One node per SubChunk. |
| CHUNK_SUBZONEGRID |
0x040102 (262402) |
Sub zone grid |
| CHUNK_COLLISION3 |
0x040103 (262403) |
Movement blocker collision. Only appears on LOD 3. Additional collision data, possibly for invisible blockers. |
| CHUNK_PROP_ENCOUNTER_NAME_REGISTRY2 |
0x040104 (262404) |
Encounter name registry |
| CHUNK_COLLISION2 |
0x040105 (262405) |
Water collision. Only appears on LOD 3. Additional collision data, for water volumes and maybe more. |
| CHUNK_PROP |
0x040200 (262656) |
Contains child nodes for additional elements to add such as lights, particle effects, audio, statically placed monster models, etc. |
| CHUNK_PROP_ENCOUNTER_NAME_REGISTRY |
0x040204 (262660) |
Prop encounter name registry |
| CHUNK_VEGETATION |
0x040205 (262661) |
Vegetation |
| CHUNK_OVERLAY |
0x040206 (262662) |
Overlay |
| CHUNK_SECTORS |
0x040207 (262663) |
Sectors, the children are 0x50013 sector layers |
| CHUNK_WATER |
0x040208 (262664) |
Visual representation of certain water elements local to the chunk. |
| CHUNK_VEGETATION2 |
0x040209 (262665) |
Vegetation, second variant |
| CHUNK_GEOMETRY |
0x040210 (262672) |
Visual representation of static objects. Data within the nodes is split into 64 segments representing the full chunk area. At low LOD a single node will contain all segments while at higher LOD the nodes are split out over the SubChunks only containing their respective segments. |
| CHUNK_GEOMETRY2 |
0x40203 (262659) |
Like CHUNK_GEOMETRY with some minor differences |
- Reader and Writer have been implemented in FauFau: GtChunk.cs. Its
GtLayerreads the node tree of the decompressed blocks.