Skip to content

Map files documentation

Sebastian Melzer edited this page Apr 10, 2017 · 24 revisions

General Description

An Arcanum map will consist of sectors spread over two axis.

In WorldEd the terms width and height are used when creating a new map, and no names are used for the axis coordinates. We will use rows instead of width and cols (columns) instead of height, and for every set of coordinates the left one will be the row and the right one the col (column).

Each sector consist of 64x64 tiles, and each tile also has inner coordinates for objects within (you can for example place a tree with its base located in several different locations inside a tile).

This data is saved in the map's folder and is spread across several files.

The *.sec files will contains most of the data of one sector in the map, it has an 64*64 array describing the tiles, a dynamic array for objects like trees, etc..
When a *.sec file doesn't exist for one of the sectors, pointer data from the terrain.tdf file will contain the information needed to get the correct sector from one of the folders in arcanum1.dat/terrain.

The terrain.tdf file in addition to default sector pointers has a header that contains useful map information, like the sectors geometry. I assume that tdf stands for Terrain Definition.

Another file that contains mostly redundant map data is map.prp. The data there is mostly redundant because all the information that it contains and is used by Arcanum can be fetched from the header in terrain.tdf. I assume that map.prp stands for map properties

I assume that the *.mob files contain data about critters and items, but i didn't get to the yet.

I assume that the map.jmp defines jump points, but i didn't get to that yet either.

The map.sbf is a file used for storing sectors that are blocked on the world map, therefore only the main map has one.

The files startloc.txt and mapinfo.txt are text files and thus very easy to understand.

terrain.tdf

8 bytes - I think this is a collection of flags, but there are only three variations in the game files, it information about how sector pointers are saved in this file. (sector pointers is what we call the data that is used to fetch sector data for sector that have no *.sec files)
The three different values in this parameter can be:

  • 0x03F8CCCCD - For no pointers (so all the *.sec should be present in this case)
  • 0x03F99999A - The pointers written as is
  • 0x13F99999A - compressed pointers

8 bytes - An unsigned long long that contains the the number of sector rows (so when creating a 4x3 map, it will hold 4).

8 bytes - An unsigned long long that contains the the number of sector cols (so when creating a 4x3 map, it will hold 3).

8 bytes - An unsigned long long that contains the original terrain type that the map was created with, the type numbers can be found in the first section of arcanum1.dat/terrain/terrain.mes. (same as the first 4 bytes of map.prp)
This value doesn't seem to be used anywhere, and in one case it is different from the one in map.prp, but i assume this is a mistake.

At this point if the file has no pointers then there will be no more data.

In case of compressed pointers, it will contain sector cols compressed with zlib. before each col there will be a 4 byte unsigned integers specifying the length of the compressed data, and then the data itself.
The compression seems to be a bit pointless since we already use zlib to compress files inside the dat's.

Once pointer data is uncompressed, or if it was not compressed in the first place, then the data will just be an array 2 byte unsigned short's representing the sector pointers, ordered by cols (So it will be the first col adjusted to the second, etc..)

The pointer is uses binary separation to hold the data it needs, the 16 bits are separated like this (I am showing this as big endian because it is easier when thinking about shifts, but remember that all number in Arcanum files are stored as little endians): FFFFFTTTTTMMMMII
Index - When the pointer points to a regular terrain (for example: green grasslands) first 2 bits will be used as a direct index to the relevant *.sec file in the relevant folder in arcanum1.dat/terrain. The index is used as if the sectors are stored as a one dimensional array sorted by rows (so 1 will go to the second row first col, and 2 to first row second col)
Mixed Index - When a mixed terrain is used (for example: green grasslands to water) the next 4 bits will serve as a very complex index for the sector. A dedicated paragraph for this index will follow.
To terrain - The next 5 bits holds the terrain type number (from arcanum1.dat/terrain/terrain.mes) of the destination terrain, in case of "green grasslands to water" it will hold 2. in case of a single typed terrain the From and the To numbers will be the same.
From terrain - The last 5 bits holds the terrain type number of the origin terrain, in case of "green grasslands to water" it will hold 0.

When dealing with a mixed terrain things get very complex. For each mix there are two folders, for example "green grasslands to water" and "water to green grasslands", and both of the variations of the From To numbers will use both folders to get their sectors from.
In addition, not all sectors contained in those folders are used, and when the sectors are used the index mapping is not direct.
To make my life easier i made an index to coordinates mapping. So each index has a row, col coordinates and a Boolean that indicates if it should use the map that fits its From To numbers or the inverse map. It looks like this:
00. This number is never used as an index

  1. (1, 0) uses the regular map
  2. (1, 2) uses the regular map
  3. (1, 1) uses the regular map
  4. (3, 2) uses the regular map
  5. (0, 0) uses the regular map
  6. (2, 2) uses the regular map
  7. (3, 0) uses the inverse map
  8. (3, 0) uses the regular map
  9. (2, 0) uses the regular map
  10. (0, 0) uses the inverse map
  11. (3, 2) uses the inverse map
  12. (3, 1) uses the regular map
  13. (1, 2) uses the inverse map
  14. (1, 0) uses the inverse map

As an example to the last explanation, if your From value is 2 (Water) and your To value is 0 (green grassland) then an index of 4 will map into the sector that corresponds to row 3 and col 2 in the "water to green grasslands" terrain folder, 11 will map into the same coordinates but in the "green grasslands to water" terrain.

map.prp

4 bytes - An unsigned integer containing the original terrain type that the map was created with, the type numbers can be found in the first section of arcanum1.dat/terrain/terrain.mes
I don't know of anything that uses this value. and there is a copy in terrain.tdf as well.

4 bytes - Some kind of a stamp, it doesn't seem to effect anything. different computers have different numbers and on some computers a restart could cause at least for part of the number to change.

8 bytes - An unsigned long long that holds the total number of tiles in one map row (so if you created a 4x3 map, this should be 4*64 = 256)
Unless Arcanum supports different number of tiles per sectors, this number is redundant.

8 bytes - An unsigned long long that holds the total number of tiles in one map column (so if you created a 4x3 map, this should be 3*64 = 192) Unless Arcanum supports different number of tiles per sectors, this number is redundant.

sec

4 bytes - An unsigned long that holds the number of lights in the following array.

24 bytes per light - Unknown format

4096 bytes - An array of 64 by 64 tiles.

1024 bytes - An array of 16 by 16 roofs.

4 bytes - An unsigned integer that represents the extensiveness of the following information. The possible values are: 0x00AA0000, 0x00AA0001, 0x00AA0002, 0x00AA0003, and 0x00AA0004. The higher the value there more information is included. Furthermore a higher value always includes all the information of a lower value. Following is a list of included information and the minimum value required for this information to be included.

At least 0x00AA0001:

  • 4 bytes - An unsigned integer that stands for the number of script tiles that follow.
  • 24 bytes per script tile - 4 bytes (unknown), 2 bytes (index of tile in sector), 2 bytes (unknown), 4 bytes (flags), 4 bytes (counters), 4 bytes (id), 4 bytes (unknown)

At least 0x00AA0002:

  • 4 bytes - Sector script flags
  • 4 bytes - Sector script counters
  • 4 bytes - Sector script id

At least 0x00AA0003:

  • 4 bytes - An unsigned integer equal to the town map id.
  • 4 bytes - A signed integer that represents the aptitude adjustment. (Magick positive, technology negative)
  • 4 bytes - An unsigned integer that holds the light scheme id.
  • 4 bytes - Unknown (always zero)
  • 4 bytes - An unsigned integer that stands for the music id
  • 4 bytes - An unsigne integer that stands for the ambient sound id.

At least 0x00AA0004:

  • 4096 bits - Blocked tile information - each bit represents a single tile, if it is 1 the tile is blocked. But, this does not mean a tile is not blocked if it is 0. Blocking objects, or the tile type still block the tile even if the value in this array is 0.

Unknown bytes - A list of objects. The format for each is the same as in *.mob files.

4 bytes - An unsigned integer that represents the number of objects in the former list.

mob

Not only is this format shared by non-mobile objects in sector files, proto files also are stored in this format.

2 bytes - Object file format. This is an unsigned short and must be equal to 119. The original game does not parse any other object file formats.

Fill me

map.jmp

Fill me

map.sbf

This file holds an array of sector coordinates, which are blocked on the world map.

4 bytes - An unsigned integer that holds the number of sectors in the array.

8 bytes per sector - The coordinates per sector are stored as single unsigned long long, but this long long can be split up into two values. Both coordinates are stored in 24 bits, the last 16 bits of the long long are presumably unused.

startloc.txt

Fill me

mapinfo.txt

Fill me

Clone this wiki locally