Msbt: Difference between revisions

imported>Zephenryus
Added msbt File Specification
 
Ginger (talk | contribs)
m Five Flags Flags: Section title typo
 
(38 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{lowercase}}
{{lowercase}}
<onlyinclude>
<onlyinclude>
<code>msbt</code> files are message standard binary files. These files define how text is displayed and interacted with by the player.
'''Message Studio Binary Text'''
</onlyinclude>
<code>MSBT</code> is a binary file format belonging to LibMessageStudio (LMS). These files store the game's text and can contain "tags" that define how said text is displayed/interacted with.</onlyinclude>


== msbt File Layout ==
== File Layout ==
 
<code>MSBT</code> files are composed of a file header followed by blocks (each with their own block header). All sections/blocks must be aligned to 0x10 (16) bytes. In BotW, the file layout is as follows:
msbt files are made up of four sections that are aligned to 16-bytes.
* Header
* Labels Block
* Attributes Block
* Text Block
The list of possible blocks is as follows:


* Header
* LBL1 (labels)
* Labels
* TXT2 (text)
* Attributes
* ATR1 (attributes)
* Texts
* TSY1 (style info)
* ATO1 (unknown)


== msbt Header ==
== File Header ==


=== Header Structure ===
=== Header Structure ===
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 25: Line 29:
| 0x00
| 0x00
| 8
| 8
| String
| char[8]
| msbt file signature (magic) <code>4D 73 67 53 74 64 42 6E</code> or "MsgStdBn"
| msbt file signature (magic) <code>4D 73 67 53 74 64 42 6E</code> or "MsgStdBn"
|-
|-
| 0x08
| 0x08
| 2
| 2
| Unsigned Short
| u16
| Byte-Order Marker
| Byte-Order Mark
|-
|-
| 0x0a
| 0x0a
| 2
| 2
|  
|  
| Unknown (padding?)
| Padding {{check}}
|-
|-
| 0x0c
| 0x0c
| 2
| 1
| Unsigned Short
| u8
| Version? 1.3?
| Encoding (0 = UTF8, 1 = UTF16, 2 = UTF32 - games generally only support one specific encoding) {{check}}
|-
|0x0d
|1
|u8
|Version (3)
|-
|-
| 0x0e
| 0x0e
| 2
| 2
| Unsigned Short
| u16
| Section Count?
| Block Count {{check}}
|-
|-
| 0x10
| 0x10
| 2
| 2
|  
|
| Padding?
| Padding {{check}}
|-
|-
| 0x12
| 0x12
| 4
| 4
| Unsigned Int
| u32
| File Size
| File Size
|-
|-
| 0x16
| 0x16
| 10
| 10
|  
|
| Padding?
| Padding {{check}}
|}
|}


== Labels Section ==
== Block Header ==
 
This header is shared across all block types. The block data follows directly after the header and is aligned to 0x10 (16) bytes. The block size does not include the size of the header.
The labels section has a header followed by an offset table and finally a string table with meta data regarding the later text section.
 
=== Labels Section Header ===
 
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
 
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 80: Line 83:
| 0x00
| 0x00
| 4
| 4
| Unsigned Int
| u32
| Signature (magic) <code>4C 42 4C 31</code> or "LBL1"
| Block Signature
|-
|-
| 0x04
| 0x04
| 4
| 4
| Unsigned Int
| u32
| Table size
| Block Size
|-
|-
| 0x08
| 0x08
Line 94: Line 97:
|}
|}


=== Labels Section Offset Table ===
== Labels Block ==
 
The labels block contains the label names for file's text. Its signature is <code>LBL1</code>.
Offsets in the offset table are relative to the end of the Labels Section Header (byte `0x10`). The offset table length is defined in the first four bytes of the table.


The section begins with a four-byte header specifying the number of label groups.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 106: Line 109:
| 0x00
| 0x00
| 4
| 4
| Unsigned Int
| u32
| Offset count
| Label Group Count
|}
|}


Each entry in the offset table is 8 bytes. 4 bytes indicating the number of null-terminated strings at the offset and an offset relative to the beginning of the offset table.
=== Label Groups ===
 
Following the header is a table of label groups. Each entry in the table is eight bytes. The first four bytes specify the number of labels in the group and the second four specify the offset of the first label relative to the start of the section. The number of label groups in many games appears to be the smallest prime number larger than half the number of labels (with a max of 101 groups and a minimum of 2). In BotW, this may not always be the case.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 120: Line 123:
| 0x00
| 0x00
| 4
| 4
| Unsigned Int
| u32
| String count
| Label Count
|-
|-
| 0x04
| 0x04
| 4
| 4
| Unsigned Int
| u32
| String offset
| Offset
|}
|}
Messages are sorted into label groups by hashing the label name. A recreation of the hash function is as follows:<syntaxhighlight lang="python3">
def calc_hash(label):
    hash = 0
    for char in label:
        hash = hash * 0x492 + ord(char)
    return (hash & 0xFFFFFFFF) % num_label_groups
</syntaxhighlight>


=== Labels Section String Table ===
=== Labels ===
 
Following the label groups is the array of labels. Each label consists of a u8 string length followed by a null-terminated string. At the end of the label is a u32 index specifying the index of the message that corresponds to the label in the text block.
The labels can be determined by iterating through the offset table and reading the number of null-terminated strings from the address. The first byte at the offset indicates the size of the label. One label can contain *zero* or more null-terminated strings but will not exceed the indicated total length.
 
After each null-terminated string, there are 4 bytes indicating which index in the texts table this label corresponds to. See the text table section for more information.
 
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 143: Line 149:
| 0x00
| 0x00
| 1  
| 1  
| Unsigned Byte
| u8
| String length
| String Length
|-
|-
| 0x01
| 0x01
| *n*
| ''n''
| char[*n*]
| char[''n'']
| String count number of null-terminated strings<ref>A label can contain *zero* or more null-terminated strings</ref>
| Label String
|-
|-
| 0xnn
| 0xnn
| 4  
| 4  
| Unsigned Int
| u32
| String Table Index
| Message Text Index
|}
|}


== Attributes Section ==
== Attributes Block ==
 
The attributes block stores additional, optional attributes that can be associated with messages. Its signature is <code>ATR1</code>. The interpretation of attribute data is completely up to the game's discretion and attributes in BotW are not fully understood at this time. The attribute seem to indicate which actor should be attributed with the dialog (A good example is in <code>100enemy.msbt</code> where <code>NPC_GodVoice</code> is referenced).
Attributes are not fully understood at this time. The attribute seem to indicate which actor should be attributed with the dialog (A good example is in <code>100enemy.msbt</code> where <code>NPC_GodVoice</code> is referenced).
 
The attributes seem to correspond to an entry in the text table with the same table index, since the attribute and text tables are usually the same size<ref>Needs validation with more research</ref>.
 
=== Attributes Section Header ===


The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
Each attribute corresponds to the message of the same index in the text block {{check}}.


The block begins with an eight-byte header that specifies the number of attributes and the size of a single attribute.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 175: Line 177:
| 0x00
| 0x00
| 4
| 4
| Unsigned Int
| u32
| Signature (magic) <code>41 54 52 31</code> or "ATR1"
| Attribute Count
|-
|-
| 0x04
| 0x04
| 4
| 4
| Unsigned Int
| u32
| Table size
| Attribute Size
|-
| 0x08
| 8
|
| Padding
|}
|}
 
Following the brief header is an array of the attribute data. In many cases, this data is actually a string offset relative to the start of the section (as is the case in BotW).
=== Attributes Section Offset Table ===
 
Offsets in the offset table are relative to the end of the Attributes Section Header (byte <code>0x10</code>). The first 4 bytes of the table are the number of offsets and the second 4 bytes indicate the size of each offset (or table entry) in bytes.
 
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 201: Line 194:
| 0x00
| 0x00
| 4
| 4
| Unsigned Int
| u32
| Offset count
| Attribute String Offset
|-
| 0x04
| 4
| Unsigned Int
| Attribute data size
|}
|}


Each entry in the offset table is a 4-byte relative offset from the beginning of the table.
=== Attribute Strings ===
 
Should the attribute data be a string offset, then the data is followed by an array of null-terminated strings encoded using the encoding specified in the file header. In BotW, this is means UTF16-LE on Switch and UTF16-BE on Wii U.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 219: Line 207:
|-
|-
| 0x00
| 0x00
| 4
| ''n''
| Unsigned Int
| char_type[]
| Attribute offset
| String
|}
|}


=== Attributes Section String Table ===
== Text Block ==
 
The text block contains the text for messages. Its signature is <code>TXT2</code>.
The attributes can be determined by iterating through the offset table and a null-terminated string from the address. Strings in this table are UTF-16 (Wii U files are UTF-16-BE encoded) encoded and take up 2 bytes for each character. Strings are terminated with a UTF-16 null character <code>00 00</code> or <code>\u0000</code>.


The section begins with a small four-byte header specifying the number of messages in the section.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 235: Line 223:
|-
|-
| 0x00
| 0x00
| *n*
| 4
| char[2]
| u32
| Unicode character
| Message Count
|}
|}
 
Following the brief header is an array of u32 offsets to the text strings. Each offset is relative to the beginning of the section.
== Texts Section ==
 
The text section contains a table of strings.
 
=== Texts Section Header ===
 
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
 
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 256: Line 236:
| 0x00
| 0x00
| 4
| 4
| Unsigned Int
| u32
| Signature (magic) <code>54 58 54 32</code> or "TXT2"
| String Offset
|-
| 0x04
| 4
| Unsigned Int
| Table size
|-
| 0x08
| 8
|
| Padding
|}
|}


=== Texts Section Offset Table ===
=== Message Strings ===
 
The strings are stored as an array of strings encoded using the encoding specified in the header. In BotW, this is means UTF16-LE on Switch and UTF16-BE on Wii U. Each string is read from its specified offset until the next string offset. The last string uses the section size specified in the block header to determine its end position.
Offsets in the offset table are relative to the end of the Texts Section Header (byte `0x10`). The offset table length is defined in the first four bytes of the table.
 
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 281: Line 249:
|-
|-
| 0x00
| 0x00
| 4
| ''n''
| Unsigned Int
| char_type[]
| Offset count
| String
|}
|}


Each entry in the offset table is a 4-byte relative offset from the beginning of the table.
== Tags ==
{{expand section}}
Message strings can contain tags that alter how the message is displayed or processed. These tags are processed by <code>nn::ui2d::TagProcessorBase</code> which in Nintendo EPD games is extended by<code>eui::TagProcessor</code> which can then be further extended by the game to handle game-specific tags. The interpretation of tags is completely game-dependent.


Tags are embedded directly inside of the text and begin with a brief tag header.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 294: Line 265:
!Description
!Description
|-
|-
| 0x00
|0x00
| 4
|2
| Unsigned Int
|u16
| String offset
|Signature (<code>00 0e</code> or <code>00 0f</code>)
|-
|0x02
|2
|u16
|Tag Group
|-
|0x04
|2
|u16
|Tag Type
|-
|0x06
|2
|u16
|Extra Data Size (this value is ignored for <code>00 0f</code> tags which have no data)
|-
|0x08
|?
|?
|Extra data (size is dependent on Extra Data Size, type is dependent on Group and Type)
|}
|}
In Nintendo EPD games, tag group 0 tags are system tags, group 1 is <code>eui</code> tags, group 2 is app (game) specific tags, and group 201 is grammar tags. The other groups are currently unknown. In BotW, group 4 appears to be for animations and group 5 appears to be for delays.


=== Texts Section String Table ===
For example, in <code>100enemy.msbt</code> the following data appears:
<pre>  | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |                 
---|-------------------------------------------------|------------------|
00 | 00 57 00 68 00 69 00 63 00 68 00 20 00 70 00 61 | .W.h.i.c.h. .p.a |
10 | 00 72 00 74 00 20 00 6F 00 66 00 20 00 74 00 68 | .r.t. .o.f. .t.h |
20 | 00 65 00 20 00 54 00 72 00 69 00 61 00 6C 00 20 | .e. .T.r.i.a.l.  |
30 | 00 77 00 6F 00 75 00 6C 00 64 00 20 00 79 00 6F | .w.o.u.l.d. .y.o |
40 | 00 75 00 0A 00 6C 00 69 00 6B 00 65 00 20 00 74 | .u...l.i.k.e. .t |
50 | 00 6F 00 20 00 63 00 68 00 61 00 6C 00 6C 00 65 | .o. .c.h.a.l.l.e |
60 | 00 6E 00 67 00 65 00 3F 00 0E 00 01 00 06 00 0A | .n.g.e.?........ |
70 | 00 02 00 03 00 04 00 05 02 03 00 00            | ............    |
</pre>
At byte <code>0x68</code> is the tag header followed with tag group 1 and tag type 6. 0xa is the size of the extra data with the extra data being <code>[00 02 00 03 00 04 00 05 02 03]</code>.
 
=== Tags ===
Not all tags functions are currently known.


The attributes can be determined by iterating through the offset table. Strings in this table are UTF-16 (Wii U files are UTF-16-BE encoded) encoded and take up 2 bytes for each character.
==== System Tags ====
{| class="wikitable"
!Group
!Type
!Notes
|-
| 0
| 0
|Ruby (extra data is a u16 display span followed by the ruby text)
|-
|0
|1
|Font (extra data is a u16 font type)
|-
|0
|2
|Font Size (extra data is a u16 font size)
|-
|0
|3
|Font Color (extra data is a u16 color type)
|-
|0
|4
|Page Break (no extra data)
|}
The available colors in BotW are listed in [[#Font Color]]. These colors are generally either hardcoded in the game's executable or defined in a separate MSBP file if present. If defined in a MSBP file, the color type instead acts as an index into the colors in the MSBP file.
 
===== Font =====
{| class="wikitable"
!Value
!Font
!Notes
|-
|0
|Hylian
|Stylized Hylian font (Unofficially known as Hylian Serif)
|-
|4
|Unknown
|
|-
|65535
|Normal
|Standard text font
|}


String length is determined by reading until the next offset in the table and not exceeding the end of the file. Strings cannot be read as null-terminated strings since many strings will have multiple null characters in them.
===== Font Color =====
{| class="wikitable"
!Value
!Color (h)
!Color
|-
|0
|0xff0a1aff
|Red
|-
|1
|0x64ff00ff
|Green
|-
|2
|0x00ffffff
|Cyan
|-
|3
|0xffffff40
|Grey (partly transparent white)
|-
|4
|0x007fffff
|Azure
|-
|5
|0xff4800ff
|Orange
|-
|6
|0x7f794aff
|Dull Gold
|-
|65535
|
|Reset to white or black, depending on background
|}


==== EUI Tags ====
{| class="wikitable"
!Group
!Type
!Notes
|-
| 1
| 0
|Delay (extra data is a u32 frame count)
|-
| 1
| 1
| Text Speed?
|-
| 1
| 2
|No Text Scroll?
|-
| 1
| 3
|Auto Advance (extra data is a u32 frame count)
|-
|1
|4
|Two Choices (See [[#Choices]])
|-
|1
|5
|Three Choices (See [[#Choices]])
|-
|1
|6
|Four Choices (See [[#Choices]])
|-
|1
|7
|Picture Font (Icon) (extra data is two u8s, the second being the type)
|-
|1
|8
|Three Choices based on flags (See [[#Choices Based on Flags]])
|-
|1
|9
|Five Flags (See [[#Five Flags]])
|-
|1
|10
|One Choice (See [[#Choices]])
|}
===== Choices =====
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 312: Line 452:
!Description
!Description
|-
|-
| 0x00
|0x00
| *n*
|2
| char[2]
|Unsigned Short
| Unicode character
|First choice
|-
|0x02
|2
|Unsigned Short
|Second choice
|-
|0x04
|1
|Byte
|Default option (option highlighted when the choices are first shown)
|-
|0x05
|1
|Byte
|Cancel option (option chosen when the B button is pressed)
|}
|}
Each choice type is a group of choices, whose text corresponds to the string conversion of the label indices in the current file. For example, if the label is <code>00 04</code> then the displayed choice will be the text corresponding to the <code>"0004"</code> key.
For ChoiceThree there is an additional choice at 0x04, and the default and cancel options are at 0x06 and 0x07, respectively.


=== Text Commands ===
For ChoiceFour there are additional choices at 0x04 and 0x06, and the default and cancel options are at 0x08 and 0x09, respectively.


Some string include interpolation operators or commands within the strings. These commands tell the game to behave in a certain way while displaying the string. Commands include choices, selling items, buying items and interacting with objects.
For ChoiceOne, there is no choice at 0x02. Instead, the default option is always 1 and is located at 0x02, and the cancel option is always 0xCD and is located at 0x03.


Commands are indicated in the strings with <code>00 0e</code> or <code>\u000e</code>.
===== Choices Based on Flags =====
{{expand section}}


{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Unofficial Name
!Size
!Size
!Data Type
!Data Type
!Description
!Description
|-
|-
| 0x00
|ParamSize
| 2
|2
| Unsigned Short
|Unsigned short
| Indicator <code>00 0e</code>
|Number of bytes in the parameter, starting after the ParamSize
|-
|VarType
|2
|Unsigned short
|Type of the variable. Seems to use the same variable types as the Variable tag.{{check}} All flags are of the same type.
|-
|FlagOne
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|ChoiceOne
|2
|Unsigned short
|First choice
|-
|FlagTwo
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|ChoiceTwo
|2
|Unsigned short
|Second choice
|-
|FlagThree
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|ChoiceThree
|2
|Unsigned short
|Third choice
|-
|DefaultIndex
|2
|Unsigned short
|Index of the choices that the cursor starts on
|-
|-
| 0x02
|CancelIndex
| 2
|2
| Unsigned Short
|Unsigned short
| Command type
|Index of the choice that is chosen if the player presses B while selecting an option
|}
|}


For example, in <code>100enemy.msbt</code> the following data appears:
===== Five Flags =====
{{expand section}}


{| class="wikitable"
!Unofficial Name
!Size
!Data Type
!Description
|-
|ParamSize
|2
|Unsigned short
|Number of bytes in the parameter, starting after the ParamSize
|-
|FlagIndexOne
|2
|Unsigned short
|u16 that seems to correspond to some kind of index. There is always one number each of 0-4, for each flag {{check}}
|-
|FlagOne
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|FlagIndexTwo
|2
|Unsigned short
|u16 that seems to correspond to some kind of index. There is always one number each of 0-4, for each flag {{check}}
|-
|FlagTwo
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|FlagIndexThree
|2
|Unsigned short
|u16 that seems to correspond to some kind of index. There is always one number each of 0-4, for each flag {{check}}
|-
|FlagThree
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|FlagIndexFour
|2
|Unsigned short
|u16 that seems to correspond to some kind of index. There is always one number each of 0-4, for each flag {{check}}
|-
|FlagFour
|?
|C-String
|u16 number of bytes in string, UTF-16 representation of the string (letters equal to number of bytes / 2)
|-
|FlagValueOne
|2
|Unsigned short
|Unknown{{check}}
|-
|FlagValueTwo
|2
|Unsigned short
|Unknown{{check}}
|-
|FlagValueThree
|2
|Unsigned short
|Unknown{{check}}
|-
|FlagValueFour
|2
|Unsigned short
|Unknown{{check}}
|-
|UnknownArray
|?
|byte[]
|Unknown purpose. Length is the remainder of the ParamSize that has not already been taken up by previous values
|}


<pre>  | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |                 
==== App Tags ====
---|-------------------------------------------------|------------------|
In BotW, the AppTag type is repurposed as a way to display the current value of a data flag. The Extra Data is the name of the data flag.
00 | 00 57 00 68 00 69 00 63 00 68 00 20 00 70 00 61 | .W.h.i.c.h. .p.a |
10 | 00 72 00 74 00 20 00 6F 00 66 00 20 00 74 00 68 | .r.t. .o.f. .t.h |
20 | 00 65 00 20 00 54 00 72 00 69 00 61 00 6C 00 20 | .e. .T.r.i.a.l.  |
30 | 00 77 00 6F 00 75 00 6C 00 64 00 20 00 79 00 6F | .w.o.u.l.d. .y.o |
40 | 00 75 00 0A 00 6C 00 69 00 6B 00 65 00 20 00 74 | .u...l.i.k.e. .t |
50 | 00 6F 00 20 00 63 00 68 00 61 00 6C 00 6C 00 65 | .o. .c.h.a.l.l.e |
60 | 00 6E 00 67 00 65 00 3F 00 0E 00 01 00 06 00 0A | .n.g.e.?........ |
70 | 00 02 00 03 00 04 00 05 02 03 00 00            | ............    |
</pre>
 
At byte <code>0x68</code> is the command indicator followed by the type of <code>1</code>. Command types of <code>1</code> seem to be variable length. The type (in this instance) is followed by the number of additional Unsigned Shorts <code>6</code> and 6 shorts.
 
<code>[00 0A] [00 02] [00 03] [00 04] [00 05] [02 03]</code>
 
The commands are not fully understood at this time, but below is a list of the known command identifiers and variable counts.


It is currently unknown what differentiates the various types that retrieve from the same data flag file.
{| class="wikitable"
{| class="wikitable"
!Group
!Type
!Type
!Additional Bytes
!Variable Type
!Notes
|-
|2
|0
|
|-
|2
|1
|
|-
|2
|2
|
|-
|2
|3
|
|-
|2
|4
|
|-
|2
|5
|
|-
|2
|6
|
|-
|2
|7
|
|-
|2
|8
|
|-
|2
|9
|
|-
|-
| 0
|2
| 3
|10
|
|
|-
|-
| 1
|2
| *n*
|11
| Variable length. Length is the unsigned short following the type.
|String64 (defined in <code>string64_data_%d.bgdata</code>)
|-
|2
|12
|
|-
|-
| 2
|2
| 2
|13
|
|
|-
|-
| 3
|2
| 3
|14
|Integer (defined in <code>s32_data_%d.bgdata</code>)
|-
|2
|15
|Integer (defined in <code>s32_data_%d.bgdata</code>)
|-
|2
|16
|
|
|-
|-
| 4
|2
| 3
|17
| Often end with <code>XX CD</code>
|Integer (defined in <code>s32_data_%d.bgdata</code>)
|-
|2
|18
|Integer (defined in <code>s32_data_%d.bgdata</code>)
|-
|2
|19
|Integer (defined in <code>s32_data_%d.bgdata</code>)
|-
|}
 
==== Group 3 Tags ====
{| class="wikitable"
!Group
!Type
!Notes
|-
|3
|1
|Sound (Extra data is 2 byte values of unknown purpose)
|}
It is currently unknown if there are other group 3 tags
 
==== Group 4 Tags ====
{| class="wikitable"
!Group
!Type
!Notes
|-
|4
|1
|Sound (Extra data is 2 byte values: 1 of unknown purpose, and 0xCD)
|-
|4
|2
|Animation (Extra data is a C style string denoting the name of an animation for the controlling actor to play)
|}
It is currently unknown if there are other group 4 tags
 
==== Group 5 Tags ====
Group 5 is used a more general form of the Delay tag. Exact durations have not been tested.
{| class="wikitable"
!Group
!Type
!Pause Duration
|-
|5
|0
|Short
|-
|5
|1
|Long
|-
|-
| 5
|5
| 2
|2
| Seem to always end with a line-feed character <code>00 0A</code>
|Longer
|}
|}
==== Grammar Tags ====
// TODO


== Compiling the Sections ==
== Compiling the Sections ==
The sections are held together by the indexes in the labels table. The indexes correspond to the attributes table and the texts table. The data can be compiled using the index.
The sections are held together by the indexes in the labels table. The indexes correspond to the attributes table and the texts table. The data can be compiled using the index.


By default the indexes in the labels table are not in order, but the text table is (and possibly the attributes table). Below is the labels table in <code>100enemy.msbt</code>.
By default the indexes in the labels table are not in order, but the text table is (and possibly the attributes table). Below is the labels table in <code>100enemy.msbt</code>.
{| class="wikitable"
{| class="wikitable"
!String Count
!String Count
Line 519: Line 887:
| 2
| 2
|}
|}
And the texts table.
And the texts table.
{| class="wikitable"
{| class="wikitable"
!Index
!Index
Line 562: Line 928:
| Cancel  
| Cancel  
|}
|}
Using the indexes to match the labels to the attributes and texts tables, the following table can be compiled.
Using the indexes to match the labels to the attributes and texts tables, the following table can be compiled.


The empty labels are not fully understood.
The empty labels are not fully understood.
{| class="wikitable"
{| class="wikitable"
!Label
!Label
Line 633: Line 997:
| Cancel
| Cancel
|}
|}
The attribute table is still not fully understood. In this example, there are 8 attribute entries in the table, but they correctly map to the 8 blocks of dialog.


The attribute table is still not fully understood. In this example, there are 8 attribute entries in the table, but they correctly map to the 8 blocks of dialog.
<references />
 
[[Category:File formats]]
[[Category:File extensions]]
[[Category:File extensions (MSBT)]]
 
== Tools ==
{{tool table|category=Tools (MSBT)}}
 
[[Category:File formats]]