Skip to content
Lukas Dürrenberger edited this page Oct 8, 2026 · 4 revisions

worldMap

Files containing the minimap images / world map. One file is one tile of one zoom level of one cube face, and the set of tiles that belongs to a zone is listed in the worldDir.

Tiles are named {cubemapId}_{zoomLvl}_{entryId}_opt.worldMap, with the zoom level padded to two digits and the entry id to ten. When the .worldDir has isDataEmbedded set, the exact same bytes live inside the .worldDir instead of in a file of their own.

010 Editor Templates

Implementations

  • Reader has been implemented in FauFau: WorldMap.cs. It reads compressed and inline payloads and splits the payload into its layers.

Format

Little endian. After the magic and the version, the file consists of layers like the ones of the zone, without the marker: a uint32 layer id and a uint32 length.

Header

Field Type Notes
magic char[4] GTNO
version uint32 2
layerId uint32 0, the general layer
layerLength uint32 45
entryId uint32 Third part of the file name
zoomLvl uint32 Second part of the file name
originX float X of the tile's corner
originY float Y of the tile's corner
size float Edge length of the tile
boundsMin float[3]
boundsMax float[3]
compressed uint8 1 when the payload is in a compressed layer

The worldDir tile record carries the same nine floats, with the bounds first.

When compressed is set, the compressed layer follows:

Field Type Notes
layerId uint32 100, the compressed layer
layerLength uint32 8 + payloadCompressedSize
payloadExtractedSize uint32 Inflated size
payloadCompressedSize uint32 Size of the zlib stream, including its 2 byte header
payload byte[] zlib stream

Otherwise the payload follows the general layer as it is, up to the end of the file.

An older version of this page read the version and the general layer header as int32[3], named entryId and zoomLvl "last" and "second" (after the parts of the file name they correspond to), and had a lodSubsectionId of 25601 and an unknown byte after the floats. 25601 (0x6401) is the compressed byte followed by the first three bytes of the layer id 100, the unknown byte is the last byte of that id, and the old dataLength is the layer length.

Inflated payload

The payload is a flat chunk stream that runs to the end of the buffer. Every chunk is:

Field Type
id uint32
length uint32
data byte[length]

Known ids:

Id Contents
10 Diffuse texture
11 Normal texture
21 Vertices. uint32 count then count 24 byte records of half floats and shorts
31 uint32 total, uint32 splitAt, one padding byte, then two runs of ushort v1, v2, v3 faces, the first splitAt / 3 long and the second (total - splitAt) / 3 long
41 uint32 count, one padding byte, then count / 2 records of ushort offset, ushort count, where each count is a number of triples of shorts
50 Not decoded
61 uint32 count then count 13 byte records, followed by uint32 n and n shorts

The chunk ids are stable across the files looked at. 10 and 11 being the diffuse and normal texture, 21 the vertices and 31 and 41 indices is what FauFau goes by, the layouts of 31, 41 and 61 come from reading the shapes in a hex editor rather than from the client, so treat them as a starting point. Nothing here has been rendered back to a picture yet, which is the obvious way to confirm them.

Chunks 10 and 11 are the actual map imagery, and are the interesting ones for anyone wanting to extract the world map.

Clone this wiki locally