This file is mirrored from the libtw2 documentation and is dual-licensed under MIT or APACHE.
The Teeworlds datafile format is the format which Teeworlds uses to save its game maps. Despite having been used for quite some time, it has not yet been formally described. The format enables one to store fixed-size “items” along with variable-sized “data items”.
The format is designed in a way that makes it easy to directly load most parts into the memory (i. e. in version 4 everything except for the data block, as the data block is stored compressed in the file). In this document the versions 3 and 4 of Teeworlds datafiles will be explained.
The following is an abstract description of the data contained in a Teeworlds datafile. It does not specify how they are laid out in the file.
An item consists of a 16-bit unsigned integer
type_id, a 16-bit
id and an array of 32-bit signed integers
id is unique amongst all items. The
data is usually the same for all items of a given
Examples of types in actual Teeworlds maps include metadata for layers, layer groups, images (external or not), etc. Since only the metadata and not the actual contents are stored, the items can remain fixed-size.
A data item is an array of bytes (8-bit unsigned integers)
is unique amongst all data items, the only possible IDs are from 0
(incl.) to the number of data items (excl.). These data items are
indexed via unsigned integers, counting sequentially in the order they
are laid out in the file.
In actual Teeworlds maps, data items are used e.g. for the tiles of a tile layer or the image data of an embedded image. They are referred to in the metadata items by their index.
The format of datafiles looks like follows, all parts are explained later:
datafile: [ 8] version_header [ 28] header [*12] item_types [* 4] item_offsets [* 4] data_offsets [* 4] _data_sizes [ ] items [ ] data
_data_sizes part is only present in version 4 of Teeworlds
header contains size information for the rest of the file:
item_typeshas the length of
item_offsetshas the length of
data_offsetshas the length of
_data_sizesis only present in version 4 of Teeworlds datafiles, it has the length of
itemshas the length of
header.item_sizebytes which must be divisible by four.
datahas the length of
The version header consists of a magic byte sequence, identifying the file as a Teeworlds datafile and a version number.
version_header:  magic  version
magic must exactly be the ASCII representations of the four
characters, ‘D’, ‘A’, ‘T’, ‘A’.
NOTE: Readers of Teeworlds datafiles should be able to read datafiles
which start with a reversed
magic too, that is ‘A’, ‘T’, ‘A’, ‘D’. A
bug in the reference implementation caused big-endian machines to save
version is a little-endian signed 32-bit integer, for version 3 or
4 of Teeworlds datafiles, it must be 3 or 4, respectively.
The header specific to version 3 and 4 consists of seven 32-bit signed integers.
header:  size  swaplen  num_item_types  num_items  num_data  item_size  data_size
size is a little-endian integer and must be the size of the
complete datafile without the
version_header and both
NOTE: The reference implementation does not read this value.
swaplen is a little-endian integer and must specify the number of
bytes containing integers following the
swaplen fields, up
until the data of the data items. It can therefore be used to reverse
the endian on big-endian machines.
NOTE: The reference implementation does not read datafiles correctly on
little-endian machines, because it interprets
swaplen as starting
after the header.
NOTE: All further integers can be assumed to be already converted to
machine-native endian, if an endian swap was performed using the
num_item_types integer specifies the number of item types in the
num_items integer specifies the number of items in the
num_data integer specifies the number of raw data blocks in the
item_size integer specifies the total size in bytes of the
data_size integer specifies the total size in bytes of the
The item types are an array of item types. The number of item types in
that array is
num_item_types, each item type is identified by its
type_id (explained below). Each item type is of the following
item_type:  type_id  start  num
type_id 32-bit signed integer must be unique amongst all other
item_type.type_ids. Its value must fit into an unsigned 16-bit
start signed integer is the index of the first item in the
with the type
num signed integer must be the number of items with the the type
NOTE: Since all items of the same type must be sequential in the
array, exactly the items with the index
start (incl.) to
start + num
(excl.) are of the type
The item offsets, the data offsets and the data sizes are 32-bit signed integers.
Each item offset is the offset of the item with the corresponding index, relative to the first item’s position in the file.
Each data offset is an offset of the data with the corresponding index, relative to the position of the first data item in the file. The data item’s size can then be calculated from the next data item’s offset or the size of the data section.
Each data size is the size of the uncompressed data of the data with the corresponding index. Note that this field is only present in datafile version 4.
This is an array of items. Each is of the following form:
item:  type_id__id  size [ ] item_data
type_id__id integer consists of 16 bit
type_id of the type the
item belongs to and 16 bit
id that uniquely identifies the item among
all others of the same type, in that order, i.e. the upper 16 bit of
type_id__id specify the
type_id and the lower 16 bit specify
size signed 32-bit integer is the size of the
in bytes, which must be divisible by four.
NOTE: Neither the
type_id nor the
size are interpreted by the
This section contains the data items. The order of the data items implicitly defines their ID.
In version 3, this section solely consists of the concatenated data. In
version 4, however, it stores the data compressed by zlib’s