Analysis of the Tibia 11 & 12 map file formats

Support TibiaMaps.io by bidding on a character auction!

The character Wablieftru is being auctioned for 59 TC.

The Qt-based Tibia 11 and Tibia 12 clients store their map data in the %LOCALAPPDATA%\Tibia\packages\Tibia\minimap folder on Windows, in ~/Library/Application Support/CipSoft GmbH/Tibia/packages/Tibia.app/Contents/Resources/minimap on macOS, and in ~/.local/share/CipSoft GmbH/Tibia/packages/Tibia/minimap on Linux.

Visual map data

Each file with a name of the form Minimap_Color_x_y_z.png contains the visual map data for a tile of 256×256 pixels. The coordinates in the file name look like this:

See tile coordinates for instructions on how to convert between the .map and .png file name format. For example, 12612507.map corresponds to Minimap_Color_32256_32000_7.png.

These aren’t just ordinary PNGs, though — the Tibia client expects them to use a very particular color palette. As a result, PNGs exported from Photoshop or other image editors won’t render properly in the Tibia client. The same goes for PNGs that have been optimized by minimizing the palette. The advantage of using this palette is that the actual PNG image data matches the binary data in the corresponding *.map file. To programmatically create PNGs that are compatible with Tibia’s minimap, use tibia-minimap-png.

Pathfinding data

Each file with a name of the form Minimap_WaypointCost_x_y_z.png contains the pathfinding data for a tile of 256×256 pixels. This is the map that is used for pathfinding, e.g. to calculate the fastest route to a destination when map-clicking. Each of these pixels represents the walking speed friction on a specific tile. Each of the RGB color components (in most cases R=G=B) contains the friction value at a given position. In general, the darker the color, the lower the friction value, and the higher your movement speed on that tile. There are two special cases: magenta (#FF00FF) tiles are unexplored, and yellow (#FFFF00) tiles are non-walkable.

These aren’t just ordinary PNGs, though — the Tibia client expects them to use a very particular color palette. As a result, PNGs exported from Photoshop or other image editors won’t render properly in the Tibia client. The same goes for PNGs that have been optimized by minimizing the palette. The advantage of using this palette is that the actual PNG image data matches the binary pathfinding data in the corresponding *.map file. To programmatically create PNGs that are compatible with Tibia’s minimap, use tibia-minimap-png.

Map marker data: minimapmarkers.bin

The minimapmarkers.bin file contains the map marker data for all the markers. Here’s a simplified example with just a couple of markers:

$ hexdump -C minimapmarkers.bin
00000000 0a 2a 0a 0a 08 8e fc 01 10 ab fb 01 18 07 10 02 |.*..............|
00000010 1a 18 46 75 72 79 20 47 61 74 65 20 28 77 6f 72 |..Fury Gate (wor|
00000020 6c 64 20 63 68 61 6e 67 65 29 20 00 0a 19 0a 0a |ld change) .....|
00000030 08 c1 fc 01 10 d3 fb 01 18 07 10 09 1a 07 48 61 |..............Ha|
00000040 72 62 6f 75 72 20 00 0a 1e 0a 0a 08 db fc 01 10 |rbour ..........|
00000050 e2 fb 01 18 07 10 0a 1a 0c 44 65 70 6f 74 20 26 |.........Depot &|
00000060 20 62 61 6e 6b 20 00 0a 2d 0a 0a 08 de fc 01 10 | bank ..-.......|
00000070 ee fb 01 18 07 10 08 1a 1b 4f 66 66 6c 69 6e 65 |.........Offline|
00000080 20 74 72 61 69 6e 69 6e 67 20 28 64 69 73 74 61 | training (dista|
00000090 6e 63 65 29 20 00 0a 1b 0a 0a 08 e1 fc 01 10 de |nce) ...........|
000000a0 fb 01 18 07 10 0c 1a 09 50 76 50 20 61 72 65 6e |........PvP aren|
000000b0 61 20 00 0a 18 0a 0a 08 f1 fc 01 10 ef fb 01 18 |a ..............|
000000c0 07 10 05 1a 06 54 65 6d 70 6c 65 20 00 0a 1d 0a |.....Temple ....|
000000d0 0a 08 8f fd 01 10 dc fb 01 18 07 10 03 1a 0b 4d |...............M|
000000e0 61 67 69 63 20 73 74 6f 72 65 20 00 |agic store .|
000000ec

The markers are ordered by their x coordinate value, then by their y coordinate value, in ascending order.

The structure of a single marker is as follows:

  1. The first byte is 0x0A.
  2. The second byte indicates the size of this marker’s data block (i.e. all the following bytes), as a uint8.
  3. The following byte is another 0x0A separator, indicating the start of the coordinate data block.
  4. The next byte indicates the size of this marker’s coordinate data block.
  5. The 0x08 byte marks the start of the x coordinate data.
  6. The next 1, 2, or 3 bytes represent the x coordinate. These values x1, x2, and x3 are all uint8s. See converting between absolute coordinates and coordinate bytes for more info.
  7. The 0x10 byte marks the end of the x coordinate data.
  8. The next 1, 2, or 3 bytes represent the y coordinate. These values y1, y2, and y3 are all uint8s. See converting between absolute coordinates and coordinate bytes for more info.
  9. The 0x18 byte marks the end of the y coordinate data.
  10. The next byte is the floor ID, as a uint8.
  11. The following byte is 0x10.
  12. The next byte represents the image ID of the marker icon, as a uint8. See our analysis of the binary *.map file format for an overview of the available icons.
  13. The next byte is 0x1A.
  14. The next indicates the size of the string that follows, as a uint8.
  15. The following bytes represent the marker description as a UTF-8–encoded string. Despite the use of UTF-8, only printable ASCII symbols seem to be allowed. When a marker description containing a disallowed symbol is imported by the beta client, the symbol is replaced with the byte sequence EF BF BD which is the UTF-8–encoded form of U+FFFD. Each marker description is limited to 100 symbols.
  16. The byte sequence 0x20 0x00 marks the end of the marker.

This structure is repeated for every marker in the file, after which the file ends.

Converting between absolute coordinates and coordinate bytes

The absolute x coordinate value corresponding to a group of x1, x2, and x3 bytes is given by the following formula:

x = x1 + ((x2 - 1) << 7) + ((x3 - 1) << 14)
// …which is equivalent to…
x = x1 + 0x80 * x2 + 0x4000 * x3 - 0x4080

// Note: `x2` and `x3` default to the value `0x01` if they’re not present in
// the coordinate data. Since this only applies for coordinate values smaller
// than `16384` (`0x4000`) this never happens for a legitimate marker on the
// official Tibia servers.

Thus, the x1, x2, and x3 values for a given absolute coordinate value x can be computed using the following formula:

// This formula assumes that the absolute coordinate value is greater than or
// equal to `16384` (`0x4000`). This currently holds true for all coordinates
// used on the official Tibia servers.
x3 = x >> 14
x1 = 0x80 + x % 0x80
x2 = (x - 0x4000 * x3 - x1 + 0x4080) >> 7

// If the absolute coordinate value is smaller than `16384` (`0x4000`), only
// two bytes (`x1` and `x2`) are written. Such coordinate values aren’t used
// on the official Tibia servers.
x2 = x >> 7
x1 = 0x80 + x % 0x80

// If the absolute coordinate value is smaller than `128` (`0x80`), only a
// single byte is written. Such coordinate values aren’t used on the official
// Tibia servers.
x1 = x

The same goes for the y coordinates.