Misc > Binary YAML
These files are similar to regular YAML files, but are encoded in binary form. They usually have the file extension .byml
or .byaml
.
A BYAML file contains a graph of nodes. Every node has a type and value. There are sequence types, such as arrays and dictionaries, and basic types such as strings and integers. The root node must always be an array or dictionary.
BYAML files are used to store all kinds of data, such as configuration data and levels.
Note: a BYAML file may contain cycles. This means that an array or dictionary may contain a node that the parser has seen earlier. Because of this, parsers must be careful not to end up in an infinite loop.
Header
In most games, the header looks as follows:
Offset | Size | Description |
---|---|---|
0x0 | 2 | Magic number / BOM (BY : big endian, YB : little endian) |
0x2 | 2 | Version number |
0x4 | 4 | Offset to dictionary key table |
0x8 | 4 | Offset to string table |
0xC | 4 | Offset to root node (array or dictionary) |
Only in Mario Kart 8, an additional binary data table is used:
Offset | Size | Description |
---|---|---|
0x0 | 2 | Magic number / BOM (BY : big endian, YB : little endian) |
0x2 | 2 | Version number |
0x4 | 4 | Offset to dictionary key table |
0x8 | 4 | Offset to string table |
0xC | 4 | Offset to binary data table |
0x10 | 4 | Offset to root node (array or dictionary) |
If a table is empty, the offest in the header is 0.
Changelog
Version | Changes |
---|---|
v1 | Initial file format. |
v2 | Unsigned integers were added (0xD3). |
v3 | 64-bit values were added (0xD4 - 0xD6). |
v4 | Binary data was added again (0xA1), but without binary data table (0xC3). |
v5 | Binary data with param (0xA2) was added. |
v6 or v7 | Hashmaps (0x20 - 0x3F) and ordered dictionaries (0xC4) were added. |
v8 to v10 | Unknown |
Node Types
ID | Type | Version |
---|---|---|
0x20 ‑ 0x2F | Hash map | (6 or 7)+ |
0x30 ‑ 0x3F | Ordered hash map | (6 or 7)+ |
0xA0 | String | Any |
0xA1 | Binary data | 4+ and MK8 |
0xA2 | Binary data with param | 5+ |
0xC0 | Array | Any |
0xC1 | Dictionary | Any |
0xC4 | Ordered dictionary | (6 or 7)+ |
0xD0 | Bool | Any |
0xD1 | Integer | Any |
0xD2 | Float | Any |
0xD3 | Unsigned integer | 2+ |
0xD4 | Integer (64 bits) | 3+ |
0xD5 | Unsigned integer (64 bits) | 3+ |
0xD6 | Double | 3+ |
0xFF | Null | Any |
The following node types may not be contained in an array or dictionary. They are only used by the header:
ID | Type | Version |
---|---|---|
0xC2 | String table | Any |
0xC3 | Binary data table | MK8 |
Node Values
To store values, arrays and dictionaries reserve 32 bits per element. Because not all node types fit into 32 bits, they are stored as follows:
Type | Value |
---|---|
0xA0 | An index into the string table (see header). |
0xA1 | An absolute offset to a binary blob. The blob is prefixed by a 32-bit integer that holds its size. MK8 stores an index into the binary data table instead (see header). |
0xA2 | An absolute offset to a binary blob. The blob is prefixed by a 32-bit integer that holds its size and another 32-bit integer with application-specific information. |
0xC0 ‑ 0xC4 | An absolute offset to the node. |
0xD0 ‑ 0xD3 | Simply the value. |
0xD4 ‑ 0xD6 | An absolute offset to the value. |
0xFF | Doesn't matter, always 0. |
Array
If the number of elements is not a multiple of 4, additional null bytes are inserted between the type table and the data table such that the data table is aligned to 4 bytes.
Offset | Size | Description |
---|---|---|
0x0 | 1 | Node type (0xC0) |
0x1 | 3 | Number of elements (N) |
0x4 | N | Type table |
4 x N | Value table |
The type table contains one byte per element that indicates its node type. The format of a value depends on the node type (see here).
Dictionary
A dictionary contains key / value pairs. The pairs must be sorted by their keys, because a binary search algorithm is used to look them up.
Offset | Size | Description |
---|---|---|
0x0 | 1 | Node type (0xC1) |
0x1 | 3 | Number of element (N) |
0x4 | 8 x N | Element table |
Every element is stored as follows:
String Table
Offset | Size | Description |
---|---|---|
0x0 | 1 | Node type (0xC2) |
0x1 | 3 | Number of strings (N) |
0x4 | 4 x (N + 1) | Address table |
Null-terminated strings |
The address table contains offsets to the strings, relative to the start of the string table node. It also contains an offset that points to the end of the string table (right behind the last string).
The address table and strings must both be sorted, because a binary search algorithm is used to find them.
Binary Data Table
Offset | Size | Description |
---|---|---|
0x0 | 1 | Node type (0xC3) |
0x1 | 3 | Number of binary blobs (N) |
0x4 | 4 x (N + 1) | Address table |
Binary data |
The address table contains offsets to the binary data, relative to the start of the binary table node. It also contains an offset that points to the end of the binary table (right behind the last binary blob).
The address table must be sorted, because the size of a binary blob is calculated from the difference between two offsets.
Ordered Dictionary
Dictionary elements are always stored in alphabetical order. To restore the original order, ordered dictionaries store an array of indices behind the element table.
Offset | Size | Description |
---|---|---|
0x0 | 1 | Node type (0xC4) |
0x1 | 3 | Number of elements (N) |
0x4 | 8 x N | Element table |
Index table |
Every element is stored as follows:
The index table contains a list of indices into the element table. The size of each index depends on the number of elements (N):
- If there are less than 256 elements, the index table contains one byte per element.
- If there are less than 65536 elements, the index table contains two bytes per element.
- Otherwise, the index table contains 4 bytes per element.