MTS File Format
===============

This document describes the MTS format native to MTSEdit and the Minetest Engine. For other formats that are supported
by MTSEdit to import schematics, see [import formats](https://gitlab.com/bztsrc/mtsedit/blob/master/docs/import.md).

MTS
---

MTS files are [MineTest Schematic files](https://dev.minetest.net/Minetest_Schematic_File_Format) used by the
[Minetest Engine](https://www.minetest.net). This is the default format of MTSEdit for both loading and saving.

All values are stored in __BIG endian__ format.

### Header

| Offset  | Length | Description                              |
|--------:|-------:|------------------------------------------|
|       0 |      4 | magic "MTSM"                             |
|       4 |      2 | file format version, currently 4         |
|       6 |      2 | size X                                   |
|       8 |      2 | size Y                                   |
|      10 |      2 | size Z                                   |
|      12 |      Y | layer probability values                 |
|    12+Y |      2 | number of strings in Name-ID table       |

Layer probability values: an unsigned char for each layer, bit 7 is reserved and must be zero, meaning 0x7F maps to 100%.

The header is followed by the Name-ID Table, which is followed by the Block Definitons section.

### Name-ID Table

For each string, the following record format repeats:

| Offset | Length | Description              |
|-------:|-------:|--------------------------|
|      0 |      2 | length of the string (N) |
|      2 |      N | string, block type name  |

The block IDs in the next section reference these.

MTSEdit uses different block type mappings to generate this table. Those mappings are specified in the
[blocks.csv](https://gitlab.com/bztsrc/mtsedit/blob/master/docs/blocks.md) file in the `data` directory.

### Block Definitons Section

This part of the file is zlib compressed, with the deflate algorithm using gz header bytes
([RFC 1950](http://tools.ietf.org/html/rfc1950), but not with the gzip header which has magic bytes too). After uncompressing,
the format is as follows:

| Offset  | Length  | Description                              |
|--------:|--------:|------------------------------------------|
|       0 | 2\*X\*Y\*Z | block IDs (param0)                       |
| 2\*X\*Y\*Z | X\*Y\*Z   | probability values (param1)              |
| 3\*X\*Y\*Z | X\*Y\*Z   | rotation info (param2)                   |

To get the block ID from `param0` for a given coordinate (x,y,z), you should calculate the index param0\[(Z-z)\*Z\*Y + y\*X + x\].
That is right, Z axis is mirrored for some reason unknown to me. That's simply not right if you catch my drift :-) Each block ID
is stored on a big endian 2 bytes, although I haven't seen any MTS files yet that used more than 255 block types per file. Also
most files store "air" block type in the first type (block ID being 0), but this is not mandatory unfortunately.

Orientation is NOT defined in any way, there's absolutely no convention. MTSEdit however prefers to save schematics in a
standardized way, that is, the entrance is on the South side. You can use the "Change Oriantation" icon in the editor to
set that right before you save. In the editor's isometric view, South is on the bottom left corner, and North is on the top
right. This aligns with the Lua API place_schematics(rotation=0).

Probability values in `param1` are encoded on 8-bits. They are indexed the same way as block IDs. Version 3 ranges from 0 to 0xFF,
while version 4 uses the same values as for layer probability, from 0 to 0x7F. According to the spec, in version 4 bit 7 means node
force placement, but I haven't seen any MTS files yet with that bit set. MTSEdit supports that force placement bit however. For
Air blocks, the probability and force placement flag is automatically handled: upon save, all Air blocks outside of rooms will
have the probability of 0, while Air blocks inside rooms will have 0xFF (probability 100% plus force placement).

Rotation information is stored in `param2`. This is the worst documented part of the MTS files. It sometimes has large values,
what I could make out from C++ source, orentation is as follows: 0 means normal orientation (block faces North), 1 means rotated
by 90 degrees (faces East), 2 means rotated by 180 degrees (faces South), and 3 means rotated by 90 degrees counter clock-wise
(faces West). I have absoultely no idea what 4-31 supposed to mean, but MTSEdit will allow those too. If you provide images with
more than 4 icons, they will be shown for those rotations.

#### Addition to the MTS Specification

Normally MTS files can't store ground level information. MTSEdit solves this by setting `param2` to 0x20 for air blocks on
ground level. This is not a perfect solution (the ground level might have no air blocks), but at least it does not interfere
with the Minetest Engine.

Another addition is that MTS files can be saved with biome specific block type names. In the Lua API, register_biome() calls
can set default block types for certain blocks, such as node_top, node_filler, node_stone etc. MTSEdit can save files with those
names, such as `biome:node_stone`. When reading these schematics, block types that start with "biome:" should be handled indirectly
by looking up the property of the biome where the schematics is placed. This is not supported by the Minetest Engine yet, but Lua
modules can implement this easily.

