worldDir - themeldingwars/Documentation GitHub Wiki
These files are a listing of the worldMap tiles that make up the mini map / world map of a
zone. They live next to the zone files as <zoneId>.worldDir.
Little endian. Strings are stored as a uint32 length including the null terminator,
followed by the characters and that terminator.
| Field | Type | Notes |
|---|---|---|
unkZero |
uint32 |
Always 0
|
headerLength |
uint32 |
Size of the header, not counting these first 8 bytes |
magic |
char[4] |
WMAP |
version |
int32 |
3 in the files we have |
numTiles |
int32 |
Number of tiles that follow |
isDataEmbedded |
uint8 |
See Embedded tile data |
path |
string |
Build machine path the map was baked from, e.g. \\s-us-nfs-3\ToolsData\Environments\stabilization\BakedData\all_users\world
|
fileSize |
uint32 |
Size of the header plus all tile records, i.e. where the embedded data starts |
Older descriptions of this file read numTiles as a single byte followed by an unknown
int32. That happens to produce the right tile count for small maps because the count is
little endian, but it is wrong, and it hides isDataEmbedded.
| Field | Type | Notes |
|---|---|---|
unk1 |
uint32 |
100 in every file looked at so far |
tileLen |
uint32 |
Size of the rest of this tile record, 61 + len(fileName)
|
fileName |
string |
e.g. 5_10_0000259802_opt.worldMap
|
dataOffset |
uint32 |
Offset of this tile's worldMap data, 0 when not embedded |
dataLength |
uint32 |
Length of that data |
cubemapId |
uint32 |
Cube face, the first part of the file name |
zoomLvl |
uint32 |
Zoom level, the second part of the file name |
entryId |
uint32 |
The third part of the file name |
corners |
float[9] |
Three vectors, the same three that appear in the worldMap header |
The three ids reproduce the file name exactly:
`${cubemapId}_${String(zoomLvl).padStart(2, '0')}_${String(entryId).padStart(10, '0')}_opt.worldMap`so a .worldDir can be converted between the embedded and non-embedded forms without
inventing names.
The corners are three float[3] vectors. In practice they look like a bounding box plus a
size vector, for example for a 1024 unit tile:
(-512, -512, 0) (512, 512, 0) (-512, -512, 1024)
The third vector is not a third corner of that box, so treating all nine floats as an opaque transform is safer than assuming a meaning for each one.
When isDataEmbedded is non-zero, the worldMap tiles are not separate files on disk.
They are appended to the .worldDir itself, starting at fileSize, and each tile's
dataOffset and dataLength slice its data out of the same buffer. Each slice is a complete
GTNO worldMap node, byte for byte identical to what the standalone file would contain.
When isDataEmbedded is zero, dataOffset is 0 and the tiles are loaded from the
fileName next to the .worldDir.
From an older tool, reading 12.worldDir (field names as that tool printed them):
Header: Unknown: 0.00
Unknown2: 97.00
Magic: WMAP
Version: 3.00
NumChunkDefs: 5.00
Unknown4: 0.00
path: \\s-us-nfs-3\ToolsData\Environments\stabilization\BakedData\all_users\world
Unknown5: 590.00
ChunkDef: Pos: (x: 100, y: 89)
ChunkName: 5_10_0000259802_opt.worldMap
Unknown: 0.00 Unknown2: 11,822.00
ChunkName1: 5.00
ChunkName2: 10.00
ChunkName3: 259,802.00
x2: -256.00 y2: -256.00 z2: 0.00
x3: 256.00 y3: 256.00 z3: 0.00
x4: -256.00 y4: -256.00 z4: 512.00
Mapping that onto the fields above: Unknown2: 97 is headerLength, NumChunkDefs plus
Unknown4 are numTiles and isDataEmbedded, Unknown5: 590 is fileSize, x: 100 and
y: 89 are unk1 and tileLen, and ChunkName1/2/3 are cubemapId, zoomLvl and
entryId.