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.
- FauFau reads it
Little endian. Strings are stored as a uint32 length including the null terminator,
followed by the characters and that terminator.
The header and every tile are layers like the ones of the zone, without the marker: a
uint32 layer id and a uint32 length. The header is layer 0, a tile is layer 100.
| Field | Type | Notes |
|---|---|---|
layerId |
uint32 |
0, the header layer |
headerLength |
uint32 |
Layer length, the 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 |
|---|---|---|
layerId |
uint32 |
100, the tile layer |
tileLen |
uint32 |
Layer length, the 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 |
boundsMin |
float[3] |
|
boundsMax |
float[3] |
|
originX |
float |
X of the tile's corner |
originY |
float |
Y of the tile's corner |
size |
float |
Edge length of the tile |
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 nine floats are the bounds of the tile, then its origin and size, for example for a 1024 unit tile:
boundsMin (-512, -512, 0) boundsMax (512, 512, 0) origin (-512, -512) size 1024
The worldMap header carries the same values, but in a different order: origin and size first, then the bounds. Older descriptions read both as three opaque vectors.
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 layerId and tileLen, ChunkName1/2/3 are cubemapId, zoomLvl and
entryId, and x2 to z4 are boundsMin, boundsMax, originX, originY and size.