2
edits
imported>Leoetlino (Created page with "'''BYML''' is a file format that is used as a generic data container throughout ''Breath of the Wild''. It is a simplified, binary form of YAML. Only the v...") |
(Updated file format to version 7 for TotK) |
||
(10 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
'''BYML''' | <onlyinclude>'''BYML''' is a simplified, binary form of [[wikipedia:YAML|YAML]].</onlyinclude> | ||
Only the version 2 format is documented in this article. | Only the version 2+ format is documented in this article. | ||
== Structure == | == Structure == | ||
Line 7: | Line 7: | ||
=== Header === | === Header === | ||
{|class="wikitable" | {| class="wikitable" | ||
!align="center" width="4%"| Offset | ! align="center" width="4%" | Offset | ||
!align="center" width="3%"| Size | ! align="center" width="3%" | Size | ||
!width="91%"| Description | ! width="91%" | Description | ||
|- | |- | ||
|align="center"| 0x00 | | align="center" | 0x00 | ||
|align="center"| 2 | | align="center" | 2 | ||
| | | “BY” (big endian) or “YB” (little endian). | ||
|- | |- | ||
|align="center"| 0x02 | | align="center" | 0x02 | ||
|align="center"| 2 | | align="center" | 2 | ||
| Version | | Version 2 in ''Breath of the Wild'', Versions 4 to 7 in ''Tears of the Kingdom''. 1 and 3 are also valid version numbers. | ||
|- | |- | ||
|align="center"| 0x04 | | align="center" | 0x04 | ||
|align="center"| 4 | | align="center" | 4 | ||
| Offset to the hash key table, relative to start (usually 0x010). May be 0 if no hash nodes are used. Must be a string value node (0xc2). | | Offset to the hash key table, relative to start (usually 0x010). May be 0 if no hash nodes are used. Must be a string value node (0xc2). | ||
|- | |- | ||
|align="center"| 0x08 | | align="center" | 0x08 | ||
|align="center"| 4 | | align="center" | 4 | ||
| Offset to the string table, relative to start. May be 0 if no strings are used. Must be a string value node (0xc2). | | Offset to the string table, relative to start. May be 0 if no strings are used. Must be a string value node (0xc2). | ||
|- | |- | ||
|align="center"| 0x0c | | align="center" | 0x0c | ||
|align="center"| 4 | | align="center" | 4 | ||
| Offset to the root node, relative to start. May be 0 if the document is totally empty. Must be either an array node (0xc0) or | | Offset to the root node, relative to start. May be 0 if the document is totally empty. Must be either an array node (0xc0) or one of the hash nodes (0x20, 0x21 or 0xc1). | ||
|} | |} | ||
Line 37: | Line 37: | ||
Every node format has a unique one byte identifier as follows. Some nodes are considered value nodes as indicated below. The container nodes have a longer encoding in the file, which must be four byte aligned. The order of encoding full nodes within the file does not seem to matter. | Every node format has a unique one byte identifier as follows. Some nodes are considered value nodes as indicated below. The container nodes have a longer encoding in the file, which must be four byte aligned. The order of encoding full nodes within the file does not seem to matter. | ||
{|class="wikitable" | {| class="wikitable" | ||
!align="center" width="8%"| Identifier | ! align="center" width="8%" | Identifier | ||
!align="center" width="17%"| Type | ! align="center" width="17%" | Type | ||
!width=" | ! width="63%" | Description | ||
! width="10%" | Version | |||
|- | |||
| align="center" | 0x20 | |||
| align="center" | Container | |||
| Plain hash. Node is a mapping from 32-bit hashes to other nodes. | |||
| 7+ | |||
|- | |||
| align="center" | 0x21 | |||
| align="center" | Container | |||
| Value hash. Node is a mapping from 32-bit hashes to other nodes and a second 4 byte value. | |||
| 7+ | |||
|- | |- | ||
|align="center"| 0xA0 | | align="center" | 0xA0 | ||
|align="center"| Value (Index) | | align="center" | Value (Index) | ||
| String. Value is an index into the string table. | | String. Value is an index into the string table. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xC0 | | align="center" | 0xA1 | ||
|align="center"| Container | | align="center" | Value (Special) | ||
| Binary data. | |||
| 4+ | |||
|- | |||
| align="center" | 0xA2 | |||
| align="center" | Value (Special) | |||
| File data. Node contains the binary data of another file. | |||
| 5+ | |||
|- | |||
| align="center" | 0xC0 | |||
| align="center" | Container | |||
| Array. Node is an array of nodes, typically, though not necessarily, all of the same format. | | Array. Node is an array of nodes, typically, though not necessarily, all of the same format. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xC1 | | align="center" | 0xC1 | ||
|align="center"| Container | | align="center" | Container | ||
| | | String hash. Node is a mapping from strings in the hash key table to other nodes. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xC2 | | align="center" | 0xC2 | ||
|align="center"| Container (Special) | | align="center" | Container (Special) | ||
| String table. Special purpose node type only seen in the hash key table and the string table. | | String table. Special purpose node type only seen in the hash key table and the string table. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xD0 | | align="center" | 0xD0 | ||
|align="center"| Value | | align="center" | Value | ||
| Bool. Node is 1 or 0 representing true or false respectively. | | Bool. Node is 1 or 0 representing true or false respectively. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xD1 | | align="center" | 0xD1 | ||
|align="center"| Value | | align="center" | Value | ||
| Int. Node is a signed 32 bit integer value. | | Int. Node is a signed 32 bit integer value. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xD2 | | align="center" | 0xD2 | ||
|align="center"| Value | | align="center" | Value | ||
| Float. Node is a binary32 floating-point number. | | Float. Node is a binary32 floating-point number. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xD3 | | align="center" | 0xD3 | ||
|align="center"| Value | | align="center" | Value | ||
| UInt. Node is an unsigned 32 bit integer value. The game uses this for some CRC32 hashes and for masks. | | UInt. Node is an unsigned 32 bit integer value. The game uses this for some CRC32 hashes and for masks. | ||
| 2+ | |||
|- | |- | ||
|align="center"| 0xD4 | | align="center" | 0xD4 | ||
|align="center"| Value (Special) | | align="center" | Value (Special) | ||
| Int64. Node is a 64 bit integer value. | | Int64. Node is a 64 bit integer value. | ||
| 3+ | |||
|- | |- | ||
|align="center"| 0xD5 | | align="center" | 0xD5 | ||
|align="center"| Value (Special) | | align="center" | Value (Special) | ||
| UInt64. Node is an unsigned 64 bit integer value. | | UInt64. Node is an unsigned 64 bit integer value. | ||
| 3+ | |||
|- | |- | ||
|align="center"| 0xD6 | | align="center" | 0xD6 | ||
|align="center"| Value (Special) | | align="center" | Value (Special) | ||
| Double. Node is a binary64 floating-point number. | | Double. Node is a binary64 floating-point number. | ||
| 3+ | |||
|- | |- | ||
|align="center"| 0xFF | | align="center" | 0xFF | ||
|align="center"| Value | | align="center" | Value | ||
| Null. Value is always 0. | | Null. Value is always 0. | ||
| 3+ | |||
|} | |} | ||
Line 97: | Line 130: | ||
For string nodes, this encoding is simply a four byte index into the string table respectively. | For string nodes, this encoding is simply a four byte index into the string table respectively. | ||
For special value nodes, the value is an offset to a | For special value nodes, the value is an offset relative to the start of the file. | ||
==== 0x20 - Hash Node ==== | |||
Hash / dictionary nodes are used to encode name value collections. Entries must sorted by their hash value. | |||
{| class="wikitable" | |||
! align="center" | Offset | |||
! align="center" | Size | |||
! Description | |||
|- | |||
| align="center" | 0x00 | |||
| align="center" | 1 | |||
| 0x20 node type. | |||
|- | |||
| align="center" | 0x01 | |||
| align="center" | 3 | |||
| Number of entries in dictionary. | |||
|- | |||
| align="center" | 0x04 | |||
| align="center" | 8*N | |||
| Dictionary entries. | |||
|- | |||
| align="center" | 0x04+8*N | |||
| align="center" | 1*N | |||
| Array of N types, on for each entry in the dictionary. This is padded to 4 bytes. | |||
|} | |||
Each entry in the dictionary has the following structure. | |||
{| class="wikitable" | |||
! align="center" width="5%" | Offset | |||
! align="center" width="3%" | Size | |||
! width="90%" | Description | |||
|- | |||
| align="center" | 0x00 | |||
| align="center" | 4 | |||
| Hash. A 32-bit hash of the key. | |||
|- | |||
| align="center" | 0x04 | |||
| align="center" | 4 | |||
| Value. For regular value nodes, this is the 4 byte node value. For other nodes, this is a 4 byte offset to the node relative to the start of the file. | |||
|} | |||
==== 0x21 - Value Hash Node ==== | |||
This type is the similar to the hash node with the addition of a 4-byte value in each dictionary entry. | |||
{| class="wikitable" | |||
! align="center" width="5%" | Offset | |||
! align="center" width="3%" | Size | |||
! width="90%" | Description | |||
|- | |||
| align="center" | 0x00 | |||
| align="center" | 4 | |||
| Value. For regular value nodes, this is the 4 byte node value. For other nodes, this is a 4 byte offset to the node relative to the start of the file. | |||
|- | |||
| align="center" | 0x04 | |||
| align="center" | 4 | |||
| Hash. A 32-bit hash of the key. | |||
|- | |||
| align="center" | 0x08 | |||
| align="center" | 4 | |||
| Unknown. Always 0 in ''Tears of the Kingdom''. | |||
|} | |||
==== 0xA1 - Binary Data Node ==== | |||
{| class="wikitable" | |||
! align="center" | Offset | |||
! align="center" | Size | |||
! Description | |||
|- | |||
| align="center" | 0x00 | |||
| align="center" | 4 | |||
| Data length | |||
|- | |||
| align="center" | 0x04 | |||
| align="center" | variable | |||
| Data | |||
|} | |||
==== 0xA2 - File Node ==== | |||
{| class="wikitable" | |||
! align="center" | Offset | |||
! align="center" | Size | |||
! Description | |||
|- | |||
| align="center" | 0x00 | |||
| align="center" | 4 | |||
| File length | |||
|- | |||
| align="center" | 0x04 | |||
| align="center" | 4 | |||
| Unknown. Always 0x1000. | |||
|- | |||
| align="center" | 0x08 | |||
| align="center" | variable | |||
| File data | |||
|} | |||
==== 0xC0 - Array Node ==== | ==== 0xC0 - Array Node ==== | ||
{|class="wikitable" | {| class="wikitable" | ||
!align="center" width="12%"| Offset | ! align="center" width="12%" | Offset | ||
!align="center" width="6%"| Size | ! align="center" width="6%" | Size | ||
!width="81%"| Description | ! width="81%" | Description | ||
|- | |- | ||
|align="center"| 0x00 | | align="center" | 0x00 | ||
|align="center"| 1 | | align="center" | 1 | ||
| 0xC0 node type. | | 0xC0 node type. | ||
|- | |- | ||
|align="center"| 0x01 | | align="center" | 0x01 | ||
|align="center"| 3 | | align="center" | 3 | ||
| Number of entries in array. | | Number of entries in array. | ||
|- | |- | ||
|align="center"| 0x04 | | align="center" | 0x04 | ||
|align="center"| N | | align="center" | N | ||
| Array of N node types; the type of each element in the array. | | Array of N node types; the type of each element in the array. | ||
|- | |- | ||
|align="center"| 0x04 + N’ | | align="center" | 0x04 + N’ | ||
|align="center"| 4*N | | align="center" | 4*N | ||
| Array of N node values. For regular value nodes, this is a 4 byte node value. For other nodes, this is a 4 byte offset to the node relative to the start of the file. | | Array of N node values. For regular value nodes, this is a 4 byte node value. For other nodes, this is a 4 byte offset to the node relative to the start of the file. | ||
|} | |} | ||
Line 125: | Line 256: | ||
N’ is N rounded up to the nearest multiple of 4. | N’ is N rounded up to the nearest multiple of 4. | ||
==== 0xC1 - Hash Node ==== | ==== 0xC1 - String Hash Node ==== | ||
Hash / dictionary nodes are used to encode name value collections. | Hash / dictionary nodes are used to encode name value collections. Entries must be lexicographically sorted<ref>Nintendo's BYML library performs a binary search when looking up items by key in a hash node.</ref>. | ||
{|class="wikitable" | {| class="wikitable" | ||
!align="center"| Offset | ! align="center" | Offset | ||
!align="center"| Size | ! align="center" | Size | ||
! Description | ! Description | ||
|- | |- | ||
|align="center"| 0x00 | | align="center" | 0x00 | ||
|align="center"| 1 | | align="center" | 1 | ||
| 0xC1 node type. | | 0xC1 node type. | ||
|- | |- | ||
|align="center"| 0x01 | | align="center" | 0x01 | ||
|align="center"| 3 | | align="center" | 3 | ||
| Number of entries in dictionary. | | Number of entries in dictionary. | ||
|} | |} | ||
Line 145: | Line 276: | ||
What then follows is a variable length array of dictionary entries. Each entry has the following structure. | What then follows is a variable length array of dictionary entries. Each entry has the following structure. | ||
{|class="wikitable" | {| class="wikitable" | ||
!align="center" width="5%"| Offset | ! align="center" width="5%" | Offset | ||
!align="center" width="3%"| Size | ! align="center" width="3%" | Size | ||
!width="90%"| Description | ! width="90%" | Description | ||
|- | |- | ||
|align="center"| 0x00 | | align="center" | 0x00 | ||
|align="center"| 3 | | align="center" | 3 | ||
| Name. Value is an index in the hash key table. | | Name. Value is an index in the hash key table. | ||
|- | |- | ||
|align="center"| 0x03 | | align="center" | 0x03 | ||
|align="center"| 1 | | align="center" | 1 | ||
| The node type. | | The node type. | ||
|- | |- | ||
|align="center"| 0x04 | | align="center" | 0x04 | ||
|align="center"| 4 | | align="center" | 4 | ||
| Value. For regular value nodes, this is the 4 byte node value. For other nodes, this is a 4 byte offset to the node relative to the start of the file. | | Value. For regular value nodes, this is the 4 byte node value. For other nodes, this is a 4 byte offset to the node relative to the start of the file. | ||
|} | |} | ||
Line 165: | Line 296: | ||
==== 0xC2 - String Table Node ==== | ==== 0xC2 - String Table Node ==== | ||
{|class="wikitable" | {| class="wikitable" | ||
!align="center" width="4%"| Offset | ! align="center" width="4%" | Offset | ||
!align="center" width="7%"| Size | ! align="center" width="7%" | Size | ||
!width="87%"| Description | ! width="87%" | Description | ||
|- | |- | ||
|align="center"| 0x00 | | align="center" | 0x00 | ||
|align="center"| 1 | | align="center" | 1 | ||
| 0xC2 node type. | | 0xC2 node type. | ||
|- | |- | ||
|align="center"| 0x01 | | align="center" | 0x01 | ||
|align="center"| 3 | | align="center" | 3 | ||
| Number of entries in the string table. | | Number of entries in the string table. | ||
|- | |- | ||
|align="center"| 0x04 | | align="center" | 0x04 | ||
|align="center"| Y=4*(N+1) | | align="center" | Y=4*(N+1) | ||
| Array of N+1 offsets to each string relative to the start of the node. The last entry is an offset to the end of the last string. | | Array of N+1 offsets to each string relative to the start of the node. The last entry is an offset to the end of the last string. | ||
|- | |- | ||
|align="center"| 0x04+Y’ | | align="center" | 0x04+Y’ | ||
|align="center"| variable | | align="center" | variable | ||
| Array of N null-terminated strings stored in alphabetical order. | | Array of N null-terminated strings stored in alphabetical order. | ||
|} | |} | ||
Y’ is Y rounded up to the nearest multiple of 4. | Y’ is Y rounded up to the nearest multiple of 4. | ||
== Usage in Nintendo games == | |||
{|class="wikitable" | |||
! Game !! Endianness !! Version || Notes | |||
|- | |||
| ''Breath of the Wild'' (Wii U) || Big endian || 2 || Uses SMO's library (in al::) | |||
|- | |||
| ''Breath of the Wild'' (Switch) || Little endian || 2 || Uses SMO's library (in al::), but with unused code and support for big endian eliminated | |||
|- | |||
| ''Super Mario Odyssey'' (Switch) || Little endian (supports big endian as well) || 3 || | |||
|- | |||
| ''Splatoon 2'' (Switch) || Little endian (supports big endian as well) || 3? || Uses SMO's library, but in the Lp::Utl:: namespace | |||
|- | |||
| ''Animal Crossing: New Horizons'' (Switch) || Little endian (supports big endian as well) || 4 || | |||
|} | |||
The v3 format seems to be identical to v2 but with the 64-bit node types added. | |||
=== Extensions === | |||
Nintendo uses several file extensions for BYML files in BotW. The basic format is the same even though each kind has a different purpose and contains different parameters. Known extensions: | |||
* [[Baischedule|.baischedule]] | |||
* [[Baniminfo|.baniminfo]] | |||
* [[Bgdata|.bgdata]] | |||
* [[Bgsvdata|.bgsvdata]] | |||
* [[Bquestpack|.bquestpack]] | |||
* [[BYML|.byml]] | |||
* [[BYML|.byaml]] | |||
* [[Mubin|.mubin]] | |||
TotK has added the following extensions: | |||
* .bgyml | |||
== Tools == | == Tools == | ||
{{tool table|category=Tools (BYML)}} | |||
''This article was adapted from documentation in the [https://github.com/handsomematt/botw-modding/blob/master/docs/file_formats/byml.md handsomematt/botw-modding repo].'' | ''This article was adapted from documentation in the [https://github.com/handsomematt/botw-modding/blob/master/docs/file_formats/byml.md handsomematt/botw-modding repo].'' | ||
[[Category:File formats]] |
edits