AINB: Difference between revisions

15,378 bytes added ,  3 months ago
Update "precondition" to "query" and "internal" to "property" based on terminology found in NSO Playtest.
m (fixed formatting)
(Update "precondition" to "query" and "internal" to "property" based on terminology found in NSO Playtest.)
 
(16 intermediate revisions by 3 users not shown)
Line 1: Line 1:
'''AINB''' ('''AI''' '''N'''ode '''B'''inary) is a file format used for AI and logic on ''Tears of the Kingdom'' as well as other recent Nintendo EPD games. This article is primarily aimed at the version that appears in ''Tears of the Kingdom'' and ''Super Mario Bros. Wonder'' (v0x0407). AINB files can be found in the AI, Logic, and Sequence folders of the romfs as well as within various packs.
'''AINB''' ('''AI''' '''N'''ode '''B'''inary) is a file format implementing behavior trees for game-specific code. At time of writing it has only appeared in titles on the ModuleSystem game engine. This article is primarily aimed at the version that appears in ''Tears of the Kingdom,'' ''Super Mario Bros. Wonder, Mario vs Donkey Kong,'' and ''Nintendo Switch Online: Playtest Program'' (v0x407). An older version appears in ''Nintendo Switch Sports'' and ''Splatoon 3'' (v0x404). ModuleSystem provides 3 built-in file categories that appear in their own dedicated folders in a title's romfs, being "AI" for actor behavior, "Logic" for actor ai group behavior, and "Sequence" for scene behavior, individual games are free to create their own file categories.


=== File Structure ===
=== File Structure ===
AINB is a little endian format similar to most Switch file formats. An AINB file consists of a set of interconnected nodes which act like a syntax tree and control the behavior of actors. These nodes can also be calls to external AINB files, allowing AINB files to form entire trees of files. The root file of the tree will have <code>.root.ainb</code> as their extension while each module in the tree will have the extension <code>.module.ainb</code>. There are three primary categories of AINB files in ''TotK'': AI, Logic, and Sequence. For AI and Sequence files, the file's entry point is one or more commands which is linked to one or two child nodes. All nodes are accessed by their index (references to precondition nodes will use their precondition node index which is local to the amount of precondition nodes in the file).
AINB is little endian. An AINB file defines a set of commands to evaluate a tree of built-in or game-specific node classes. The built-in "Element_ModuleCaller" node and supporting structures allow a "root" AINB file to call out to an external "module" AINB file, module's can call further modules, allowing AINB files to form a tree of tree's. An AINB's file extension typically designates whether it is a root <code>.root.ainb</code> or module <code>.module.ainb</code>. For AI and Sequence files, the file's entry point is one or more commands which is linked to one or two child nodes. All nodes are accessed by their index (references to query nodes will use their query node index which is local to the amount of query nodes in the file).


 
All string offsets in the file are relative to the beginning of the string pool and name hashes are 32-bit murmur3 hashes. There are six possible data types for AINB parameters: int (signed 32-bit integer), bool, float (32-bit), vector3f, and pointer. Pointer parameters are pointers to objects.
All string offsets in the file are relative to the beginning of the string pool and name hashes are 32-bit murmur3 hashes. There are six possible types for AINB parameters: int (signed 32-bit integer), bool, float (32-bit), vector3f, and pointer. Pointer parameters are pointers to objects.


==== Section Order ====
==== Section Order ====
Line 15: Line 14:
# Node Bodies
# Node Bodies
# Attachment Parameters
# Attachment Parameters
# Immediate Parameters
# Property Parameters
# Input/Output Parameters
# Input/Output Parameters
# Multi-Parameters
# Multi-Parameters
# Resident Update Array
# Active Node Update Array
# 0x50 Section (Unused in ''TotK'')
# 0x50 Section (Unused in ''TotK'')
# Precondition Nodes
# Query Node Array
# Expression Binary
# Expression Binary
# Embedded AINB Files
# AINB Modules
# Entry Strings
# External Action Array
# File Hashes
# File Hashes
# Child Replacement Table
# Child Replacement Table
Line 29: Line 28:
# Enum Resolve Array
# Enum Resolve Array
# String Pool
# String Pool
=== Sections ===


==== File Header ====
==== File Header ====
Line 47: Line 48:
|0x04
|0x04
|u32
|u32
|Version (0x0407 in TotK, 0x0404 in S3 and NSS)
|Version (0x0407 in ''TotK'', 0x0404 in ''S3'' and ''NSS'')
|-
|-
|0x08
|0x08
Line 67: Line 68:
|0x04
|0x04
|u32
|u32
|Precondition Node Count
|Query Node Count
|-
|-
|0x18
|0x18
Line 97: Line 98:
|0x04
|0x04
|u32
|u32
|Immediate Parameters Offset
|Property Parameters Offset
|-
|-
|0x30
|0x30
|0x04
|0x04
|u32
|u32
|Resident Update Array Offset
|Active Node Update Array Offset
|-
|-
|0x34
|0x34
Line 137: Line 138:
|0x04
|0x04
|u32
|u32
|Precondition Node Array Offset
|Query Node Array Offset
|-
|-
|0x50
|0x50
|0x04
|0x04
|u32
|u32
|Unknown (unused in ''TotK'', always the same as the Resident Update Array Offset)
|Unknown (unused in ''TotK'', always the same as the Active Node Update Array Offset)
|-
|-
|0x54
|0x54
Line 157: Line 158:
|0x04
|0x04
|u32
|u32
|Embedded AINB Files Offset
|AINB Modules Array Offset
|-
|-
|0x60
|0x60
Line 167: Line 168:
|0x04
|0x04
|u32
|u32
|File Category (0 = AI, 1 = Logic, 2 = Sequence) - only ''TotK''
|File Category (0 = AI, 1 = Logic, 2 = Sequence) (''Splatoon 3'' game specific, 3 = UniqueSequenceSPL)
|-
|-
|0x68
|0x68
|0x04
|0x04
|u32
|u32
|Entry Strings Offset (purpose unknown)
|External Action Array Offset
|-
|-
|0x6C
|0x6C
Line 215: Line 216:
|0x02
|0x02
|u16
|u16
|Left Node Index
|Main Node Index
|-
|-
|0x16
|0x16
|0x02
|0x02
|u16
|u16
|Right Node Index (one greater than the corresponding node index)
|Secondary Node Index (value offset by 1, 0 is reserved)
|}
|}
Command GUIDs are only used for debug messages. Right Node Index will be -1 if the command only has one child node.
Command GUIDs are only used for debug messages. Right Node Index will be -1 if the command only has one child node.
Line 306: Line 307:
|0x02
|0x02
|u16
|u16
|Base Precondition Node
|Base Query Node
|-
|-
|0x26
|0x26
|0x02
|0x02
|u16
|u16
|Precondition Node Count
|Query Node Count
|-
|-
|0x28
|0x28
Line 482: Line 483:
|-
|-
|Element_Fork
|Element_Fork
|See Resident Update Array
|See Active Node Update Array
|-
|-
|Element_Join
|Element_Join
|See Resident Update Array
|See Active Node Update Array
|-
|-
|Element_Alert
|Element_Alert
Line 494: Line 495:
|-
|-
|Element_ModuleIF_Input_S32
|Element_ModuleIF_Input_S32
|Passes a signed int as output to another node as input
|Receives a signed int input from the calling AINB file
|-
|-
|Element_ModuleIF_Input_F32
|Element_ModuleIF_Input_F32
|Passes a 32-bit float as output to another node as input
|Receives a 32-bit float input from the calling AINB file
|-
|-
|Element_ModuleIF_Input_Vec3f
|Element_ModuleIF_Input_Vec3f
|Passes a vector3f as output to another node as input
|Receives a vector3f input from the calling AINB file
|-
|-
|Element_ModuleIF_Input_String
|Element_ModuleIF_Input_String
|Passes a string as output to another node as input
|Receives a string input from the calling AINB file
|-
|-
|Element_ModuleIF_Input_Bool
|Element_ModuleIF_Input_Bool
|Passes a boolean int as output to another node as input
|Receives a bool input from the calling AINB file
|-
|-
|Element_ModuleIF_Input_Ptr
|Element_ModuleIF_Input_Ptr
|Passes a pointer as output to another node as input
|Receives an object pointer input from the calling AINB file
|-
|-
|Element_ModuleIF_Output_S32
|Element_ModuleIF_Output_S32
|Passes a signed int as output to another node as output
|Returns a signed int output from the module to the calling AINB file
|-
|-
|Element_ModuleIF_Output_F32
|Element_ModuleIF_Output_F32
|Passes a 32-bit float as output to another node as output
|Returns a 32-bit float output from the module to the calling AINB file
|-
|-
|Element_ModuleIF_Output_Vec3f
|Element_ModuleIF_Output_Vec3f
|Passes a vector3f as output to another node as output
|Returns a vector3f output from the module to the calling AINB file
|-
|-
|Element_ModuleIF_Output_String
|Element_ModuleIF_Output_String
|Passes a string as output to another node as output
|Returns a string output from the module to the calling AINB file
|-
|-
|Element_ModuleIF_Output_Bool
|Element_ModuleIF_Output_Bool
|Passes a boolean int as output to another node as output
|Returns a bool output from the module to the calling AINB file
|-
|-
|Element_ModuleIF_Output_Ptr
|Element_ModuleIF_Output_Ptr
|Passes a pointer as output to another node as output
|Returns an object pointer output from the module to the calling AINB file
|-
|-
|Element_ModuleIF_Child
|Element_ModuleIF_Child
|Unsure, appears to just be a node connected to a ModuleIF node as a child node
|Returns the node connection name from the module to the calling AINB file
|-
|-
|Element_StateEnd
|Element_StateEnd
|Termination node
|Termination node, specifies what resident node to return to in the calling AINB file
|-
|-
|Element_SplitTiming
|Element_SplitTiming
Line 544: Line 545:
|-
|-
|1
|1
|Is Precondition Node
|Is Query Node
|-
|-
|1
|1
|Is External AINB File
|Is Module
|-
|-
|1
|1
|Is Resident Node
|Is Resident Node
|-
|-
|5
|1
|MultiParam Type 2
|-
|4
|
|
|}
|}
Line 622: Line 626:
|Is File Reference Valid
|Is File Reference Valid
|}
|}
The default value entries vary based on the parameter's data type. For int and float parameters, the entry is a four byte immediate value. String entries are a four byte string value offset. Bool entries are a single byte immediate value and vector3f entries are 12 bytes. Note that pointer parameters do not have default value entries and do not have default values.
The default value entries vary based on the parameter's data type. For int, float, and bool parameters, the entry is a four byte immediate value. String entries are a four byte string value offset. Vector3f entries are 12 bytes. Note that pointer parameters do not have default value entries and do not have default values.
{| class="wikitable"
{| class="wikitable"
|+File Reference Entry
|+File Reference Entry
Line 643: Line 647:
|0x04
|0x04
|u32
|u32
|Unknown Hash
|Filename Hash (no extension)
|-
|-
|0x0C
|0x0C
|0x04
|0x04
|u32
|u32
|Unknown Hash
|File Extension Hash (no .)
|}
|}


Line 662: Line 666:
|0x04
|0x04
|u32
|u32
|Int Immediate Parameter Base Index
|Int Property Parameter Base Index
|-
|-
|0x04
|0x04
|0x04
|0x04
|u32
|u32
|Int Immediate Parameter Count
|Int Property Parameter Count
|-
|-
|0x08
|0x08
|0x04
|0x04
|u32
|u32
|Bool Immediate Parameter Base Index
|Bool Property Parameter Base Index
|-
|-
|0x0C
|0x0C
|0x04
|0x04
|u32
|u32
|Bool Immediate Parameter Count
|Bool Property Parameter Count
|-
|-
|0x10
|0x10
|0x04
|0x04
|u32
|u32
|Float Immediate Parameter Base Index
|Float Property Parameter Base Index
|-
|-
|0x14
|0x14
|0x04
|0x04
|u32
|u32
|Float Immediate Parameter Count
|Float Property Parameter Count
|-
|-
|0x18
|0x18
|0x04
|0x04
|u32
|u32
|String Immediate Parameter Base Index
|String Property Parameter Base Index
|-
|-
|0x1C
|0x1C
|0x04
|0x04
|u32
|u32
|String Immediate Parameter Count
|String Property Parameter Count
|-
|-
|0x20
|0x20
|0x04
|0x04
|u32
|u32
|Vector3f Immediate Parameter Base Index
|Vector3f Property Parameter Base Index
|-
|-
|0x24
|0x24
|0x04
|0x04
|u32
|u32
|Vector3f Immediate Parameter Count
|Vector3f Property Parameter Count
|-
|-
|0x28
|0x28
|0x04
|0x04
|u32
|u32
|Pointer Immediate Parameter Base Index
|Pointer Property Parameter Base Index
|-
|-
|0x2C
|0x2C
|0x04
|0x04
|u32
|u32
|Pointer Immediate Parameter Count
|Pointer Property Parameter Count
|-
|-
|0x30
|0x30
Line 859: Line 863:
|0x01
|0x01
|u8
|u8
|Unknown Connection Type Count (Unused in TotK)
|Unknown Connection Type Count (Unused in ''TotK'')
|-
|-
|0x03
|0x03
|0x01
|0x01
|u8
|u8
|Unknown Connection Type Base Index (Unused TotK)
|Unknown Connection Type Base Index (Unused ''TotK'')
|-
|-
|0x04
|0x04
Line 879: Line 883:
|0x01
|0x01
|u8
|u8
|Resident Update Node Count
|Active Node Update Count
|-
|-
|0x07
|0x07
|0x01
|0x01
|u8
|u8
|Resident Update Base Index
|Active Node Update Base Index
|-
|-
|0x08
|0x08
Line 964: Line 968:
|Value
|Value
|}
|}
The interpretation of the value depends on the connection type. For input or output connections, the value is a string offset to the parameter name. For standard connections, the value is a string offset to the connection name. For resident update connections, the value is an index into the resident update array. Certain node/connection types will also extend the entry length. Selector-type nodes excluding <code>Element_BoolSelector</code> and <code>Element_F32Selector</code> will have an extra four bytes which stores the condition for to link to the child node. For <code>Element_S32Selector</code>, this is an immediate value. For <code>Element_RandomSelector</code>, this is a weight and for <code>Element_StringSelector</code> it is a u32 string offset. The condition for  <code>Element_BoolSelector</code> is the entry's value string. <code>Element_F32Selector</code> adds 24 bytes to each entry, consisting of four eight-byte sub-entries.
The interpretation of the value depends on the connection type. For input or output connections, the value is a string offset to the parameter name. For standard connections, the value is a string offset to the connection name. For active node update connections, the value is an index into the active node update array. Certain node/connection types will also extend the entry length. Selector-type nodes excluding <code>Element_BoolSelector</code> and <code>Element_F32Selector</code> will have an extra four bytes which stores the condition for to link to the child node. For <code>Element_S32Selector</code>, this is an immediate value. For <code>Element_RandomSelector</code>, this is a weight and for <code>Element_StringSelector</code> it is a u32 string offset. The condition for  <code>Element_BoolSelector</code> is the entry's value string. <code>Element_F32Selector</code> adds 24 bytes to each entry, consisting of four eight-byte sub-entries.
{| class="wikitable"
{| class="wikitable"
|+<code>Element_F32Selector Condition Entry</code>
|+<code>Element_F32Selector Condition Entry</code>
Line 985: Line 989:


==== Attachment Parameters ====
==== Attachment Parameters ====
This section contains an array of attachments for nodes. This section is preceded by the attachment index array which is an array of u32 indices into the entries in this section. Nodes contain an index into the index array rather than directly into this section. The section contains an array of entries followed by an array of parameter entries.
{| class="wikitable"
|+Attachment Parameter Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|Name Offset
|-
|0x04
|0x04
|u32
|Parameters Entry Offset
|-
|0x08
|0x02
|u16
|EXB Function Count
|-
|0x0A
|0x02
|u16
|EXB Input/Output Field Size
|-
|0x0C
|0x04
|u32
|Name Hash (version 0x0407 only)
|}
{| class="wikitable"
|+Parameter Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|Unknown (possibly related to debug)
|-
|0x04
|0x04
|u32
|Int Property Parameter Base Index
|-
|0x08
|0x04
|u32
|Int Property Parameter Count
|-
|0x0C
|0x04
|u32
|Bool Property Parameter Base Index
|-
|0x10
|0x04
|u32
|Bool Property Parameter Count
|-
|0x14
|0x04
|u32
|Float Property Parameter Base Index
|-
|0x18
|0x04
|u32
|Float Property Parameter Count
|-
|0x1C
|0x04
|u32
|String Property Parameter Base Index
|-
|0x20
|0x04
|u32
|String Property Parameter Count
|-
|0x24
|0x04
|u32
|Vector3f Property Parameter Base Index
|-
|0x28
|0x04
|u32
|Vector3f Property Parameter Count
|-
|0x2C
|0x04
|u32
|Pointer Property Parameter Base Index
|-
|0x30
|0x04
|u32
|Pointer Property Parameter Count
|-
|0x34
|0x04
|u32
|
|-
|0x38
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x3C
|0x04
|u32
|
|-
|0x40
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x44
|0x04
|u32
|
|-
|0x48
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x4C
|0x04
|u32
|
|-
|0x50
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x54
|0x04
|u32
|
|-
|0x58
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x5C
|0x04
|u32
|
|-
|0x60
|0x04
|u32
|Unknown (contains address to next entry)
|}


==== Immediate Parameters ====
==== Property Parameters ====
This section contains an array of property parameters for nodes. The section begins with a six u32 relative offsets to the first entry for each data type. The data type order for this section is int, bool, float, string, vector3f, and pointer.
{| class="wikitable"
|+Parameter Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|Name Offset
|-
|0x04
|0x04
|u32
|Flags
|-
|0x08
|
|
|Value
|}
The value is an immediate value for the data type (excluding string which is a string offset and pointer which doesn't store a value). Pointer entries also have an additional u32 class name offset at offset 0x04, pushing the flags to offset 0x08.
{| class="wikitable"
|+Parameter Flags
!Bits
!Description
|-
|16
|Source Index
|-
|1
|Is Use Index
|-
|1
|Is Not Local Blackboard Index
|-
|1
|
|-
|1
|
|-
|1
|
|-
|1
|
|-
|1
|Is EXB Index
|-
|1
|Pulse Thread Local Storage
|-
|1
|Set Pointer Flag Bit Zero
|-
|2
|
|-
|2
|
|-
|2
|
|}


==== Input/Output Parameters ====
==== Input/Output Parameters ====
This section contains an array of input and output parameter entries. These appear to be canonically referred to as "plugs". Similarly to the property parameters section, the section begins with u32 relative offsets to the first entry of each data type. However, instead of six offsets, there are 12 - two for each data type (one input, one output). The order of parameters in this section is int input, int output, bool input, bool output, float intput, float output, string input, string output, vector3f input, vector3f output, pointer input, and pointer output.
{| class="wikitable"
|+Input Parameter Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|Name Offset
|-
|0x04
|0x02
|s16
|Input Child Node Index / Multi-Parameter Array Base Index
|-
|0x06
|0x02
|s16
|Input/Output Source Node Index / Multi-Parameter Count
|-
|0x08
|0x04
|u32
|Flags
|-
|0x0C
|
|
|Default Value
|}
The default value is an immediate value for the data type (excluding string which is a string offset and pointer which is always an empty four bytes). Pointer entries also have an additional u32 class name offset at offset 0x04, pushing the rest of the entry back by four bytes. If the input child node index is between -32768 and -100, it corresponds to a multi-parameter array index. The multi-parameter index can be calculated as follows: <code>MultiParamIndex = -100 - Index</code>.
{| class="wikitable"
|+Parameter Flags
!Bits
!Description
|-
|16
|Source Index
|-
|1
|Is Use Index
|-
|1
|Is Not Local Blackboard Index
|-
|1
|
|-
|1
|
|-
|1
|
|-
|1
|
|-
|1
|Is EXB Index
|-
|1
|Pulse Thread Local Storage
|-
|1
|Set Pointer Flag Bit Zero
|-
|2
|
|-
|2
|
|-
|2
|
|}
Each output parameter entry is four bytes.
{| class="wikitable"
|+Output Parameter Entry
!Bits
!Description
|-
|31
|Name Offset
|-
|1
|Set Pointer Flag Bit Zero
|}


==== Multi-Parameters ====
==== Multi-Parameters ====
This section contains entries specifying parameters that have multiple values and the sources of those values. Each entry is eight bytes.
{| class="wikitable"
|+Multi-Parameter Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x02
|u16
|Node Index
|-
|0x02
|0x02
|u16
|Input/Output Source Parameter Index
|-
|0x04
|0x04
|u32
|Flags
|}
{| class="wikitable"
|+Parameter Flags
!Bits
!Description
|-
|16
|Source Index
|-
|1
|Is Use Index
|-
|1
|Is Not Local Blackboard Index
|-
|1
|
|-
|1
|
|-
|1
|
|-
|1
|
|-
|1
|Is EXB Index
|-
|1
|Pulse Thread Local Storage
|-
|1
|Set Pointer Flag Bit Zero
|-
|2
|
|-
|2
|
|-
|2
|
|}


==== Resident Update Array ====
==== Active Node Update Array ====
This section is an array of entries for updates to the active node array. The first four bytes specify the number of entries. Each entry is four bytes.
{| class="wikitable"
|+
!Bits
!Description
|-
|8
|Is Valid Update
|-
|23
|
|-
|1
|Update Post Calc
|}
If the first byte of the flags is set to false, then the entry contains another four bytes with a string offset (purpose unknown). Otherwise, the entry is considered valid if the first byte equals 1. When processing a node graph, the game maintains an array of active root nodes. When a command calculated, the root node of the command is added to this array and it and its child nodes are calculated recursively. An active node update will change the current active root node to the specified node. This usually happens right before the next command's calculation occurs, but if the top bit is set, then it will occur immediately after the current command's calculation finishes (if the source node is an Element_Join nodes, it will always update the active node post current command calculation). This is primarily used for "subroutines" that run a single time then return to the main execution routine. This system is also used for Element_Fork and Element_Join nodes. An Element_Fork node, unlike normal nodes, will replace the entire current active node array with its array of active node updates (essentially forking execution into multiple different paths). The node at the end of each of these paths will optionally also have an active node update referencing a specific Element_Join node. Each of these nodes will push the Element_Join into the active node array. However, Element_Join nodes have an property parameter called InFlowNum and until it has been pushed onto the array that many times in a single calculation, it will not activate and remain dormant. However, once this threshold is reached, it will begin execution (with a guard to make sure only one of the instances added to the array will execute).


==== 0x50 Section ====
==== 0x50 Section ====
This section is unused in ''Tears of the Kingdom''.
This section is unused in ''Tears of the Kingdom''.


==== Precondition Nodes Array ====
==== Query Node Array ====
This section is an array of entries of query nodes present in the file.
{| class="wikitable"
|+Query Node Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x02
|u16
|Query Node Index (local to number of query nodes)
|-
|0x02
|0x02
|u16
|
|}


==== Expression Binary Section ====
==== Expression Binary Section ====
The '''EXB''' ('''Ex'''pression '''B'''inary) section is a completely self-contained section that stores custom instructions for a simple command processor. These instructions are grouped into functions that can be called by nodes to perform calculations.
The '''EXB''' ('''Ex'''pression '''B'''inary) section is a completely self-contained section that stores custom instructions for a simple command processor. These instructions are grouped into functions that can be called by nodes to perform calculations. Because the section is self-contained, all offsets in this section are local to the section. The EXB section is shared with ASB files ('''A'''nimation '''S'''equence '''B'''inary).
 
===== Section Structure =====
EXB is essentially its own format and allows for the storage of custom functions in files.
 
====== Section Order ======


==== Embedded AINB Files ====
# 0x2C-Byte Header
# Command Info Table
# Instructions Table
# Parameter Region
# Signature Table
# String Pool


==== Entry Strings ====
===== Sub-Sections =====
 
====== Header ======
{| class="wikitable"
|+EXB Header
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|char[4]
|Magic - “EXB “
|-
|0x04
|0x04
|u32
|Version (0x02)
|-
|0x08
|0x04
|u32
|Static Memory Allocation Size
|-
|0x0C
|0x04
|u32
|Parameter EXB Field Entry Count
|-
|0x10
|0x04
|u32
|32-bit Scratch Allocation Size
|-
|0x14
|0x04
|u32
|64-bit Scratch Allocation Size
|-
|0x18
|0x04
|u32
|Command Info Offset
|-
|0x1C
|0x04
|u32
|Command Table Offset
|-
|0x20
|0x04
|u32
|Signature Table Offset
|-
|0x24
|0x04
|u32
|Parameter Region Offset
|-
|0x28
|0x04
|u32
|String Pool Offset
|}
 
====== Command Info Table ======
This section contains an array of command (function) info entries. The first four bytes specify the entry count.
{| class="wikitable"
|+Command Info Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|s32
|Base Index Pre-Command Entry
|-
|0x04
|0x04
|u32
|Pre-Entry Static Memory Usage
|-
|0x08
|0x04
|u32
|Instruction Base Index
|-
|0x0C
|0x04
|u32
|Instruction Count
|-
|0x10
|0x04
|u32
|Static Memory Size
|-
|0x14
|0x02
|u16
|32-bit Scratch Memory Size
|-
|0x16
|0x02
|u16
|64-bit Scratch Memory Size
|-
|0x18
|0x02
|u16
|Output Data Type Enum
|-
|0x1A
|0x02
|u16
|Input Data Type Enum
|}
{| class="wikitable"
|+Data Type Enum
!Value (Hex)
!Value (Dec)
!Data Type
|-
|0x0
|0
|No Data
|-
|0x1
|1
|Immediate Value/From User
|-
|0x02
|2
|bool
|-
|0x03
|3
|int
|-
|0x04
|4
|float
|-
|0x05
|5
|string
|-
|0x06
|6
|vector3f
|}
 
====== Instructions Table ======
This section contains an array of instruction entries which are read by the EXB command processor. The first four bytes specify the entry count.
{| class="wikitable"
|+Instruction Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x01
|u8
|Instruction Type
|-
|0x01
|0x01
|u8
|Data Type Enum
|-
|0x02
|0x01
|u8
|Left-Hand Side Parameter Source Enum
|-
|0x03
|0x01
|u8
|Right-Hand Side Parameter Source Enum
|-
|0x04
|0x02
|u16
|Left-Hand Side Parameter Value
|-
|0x06
|0x02
|u16
|Right-Hand Side Parameter Value
|}
For UserDefined type instructions, the bytes at offset 0x02-0x04 become a u16 static memory index and the bytes at 0x04-0x08 become a u32 index into the function signatures table.
{| class="wikitable"
|+Instruction Types
!Value (Hex)
!Value (Dec)
!Instruction Type
|-
|0x01
|1
|Terminator
|-
|0x02
|2
|Store
|-
|0x03
|3
|Negate
|-
|0x04
|4
|NegateBool
|-
|0x05
|5
|Add
|-
|0x06
|6
|Subtract
|-
|0x07
|7
|Multiply
|-
|0x08
|8
|Divide
|-
|0x09
|9
|Modulus
|-
|0x0A
|10
|Increment
|-
|0x0B
|11
|Decrement
|-
|0x0C
|12
|ScalarMultiplyVec3f
|-
|0x0D
|13
|ScalarDivideVec3f
|-
|0x0E
|14
|LeftShift
|-
|0x0F
|15
|RightShift
|-
|0x10
|16
|LessThan
|-
|0x11
|17
|LessThanEqual
|-
|0x12
|18
|GreaterThan
|-
|0x13
|19
|GreaterThanEqual
|-
|0x14
|20
|Equal
|-
|0x15
|21
|NotEqual
|-
|0x16
|22
|AND
|-
|0x17
|23
|XOR
|-
|0x18
|24
|OR
|-
|0x19
|25
|LogicalAND
|-
|0x1A
|26
|LogicalOR
|-
|0x1B
|27
|UserFunction
|-
|0x1C
|28
|JumpIfLHSZero
|-
|0x1D
|29
|Jump
|}
UserFunctions are mapped to a function in the executable by function signature. There are two types of these functions: direct and object. Direct functions are straightforward functions that take up to two arguments and are matched using the function signature. Function objects can take additional arguments and are indexed at runtime.
 
{| class="wikitable"
|+Data Type Enum
!Value (Hex)
!Value (Dec)
!Data Type
|-
|0x0
|0
|No Data
|-
|0x1
|1
|Immediate Value/From User
|-
|0x02
|2
|bool
|-
|0x03
|3
|int
|-
|0x04
|4
|float
|-
|0x05
|5
|string
|-
|0x06
|6
|vector3f
|}
{| class="wikitable"
|+Parameter Source Enum
!Value (Hex)
!Value (Dec)
!Parameter Source
|-
|0x00
|0
|Immediate Parameters
|-
|0x01
|1
|Immediate Parameters (String)
|-
|0x02
|2
|Static Memory
|-
|0x03
|3
|Parameters Region
|-
|0x04
|4
|Parameters Region (String)
|-
|0x05
|5
|Output Value
|-
|0x06
|6
|Input Value
|-
|0x07
|7
|32-bit Scratch
|-
|0x08
|8
|64-bit Scratch
|-
|0x09
|9
|UserOutput
|-
|0x0A
|10
|UserInput
|}
UserCallback is a class that contains virtual functions providing memory allocation. The input value is passed from the calling node and the output value is passed back.
 
====== Parameter Region ======
The parameter region is a region that stores the values for parameters values that are too large to fit into two bytes. Parameters that get their values from this section instead store an offset relative to the beginning of the parameter region to the start of the value.
 
====== Signatures Table ======
This section is an array of u32 string offsets for each function signature.
 
====== String Pool ======
The string pool is an array of null-terminated strings encoded with UTF-8. All string offsets in this section are relative to the beginning of the string pool.
 
==== AINB Modules ====
This section contains an array of all AINB modules linked to the current AINB file. The first four bytes specify the entry count.
{| class="wikitable"
|+AINB Module Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|File Path Offset
|-
|0x04
|0x04
|u32
|File Category Offset
|-
|0x08
|0x04
|u32
|AINB File Count
|}
 
==== External Action Array ====
This section appears to interact with XLink. The first four bytes specify the entry count.
{| class="wikitable"
|+Entry String Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|Node Index
|-
|0x04
|0x04
|u32
|String 1 Offset (always メインステート ("Main State"))
|-
|0x08
|0x04
|u32
|State Name Offset
|}


==== File Hashes ====
==== File Hashes ====
Line 1,010: Line 1,910:


==== Child Replacement Table ====
==== Child Replacement Table ====
This section is used to remove or replace specific nodes or attachments at runtime. This is used to toggle of debug nodes/attachments for release builds. The section begins with an eight-byte section header.
{| class="wikitable"
|+Child Replacement Section Header
!Offset
!Size
!Type
!Description
|-
|0x00
|0x01
|u8
|Initialization Guard (Is Initialized)
|-
|0x01
|0x01
|u8
|
|-
|0x02
|0x02
|u16
|Replacement Count
|-
|0x04
|0x02
|s16
|Override Node Count
|-
|0x06
|0x02
|s16
|Override Attachment Parameter Count
|}
{| class="wikitable"
|+Child Replacement Table Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x01
|u8
|Replacement Type Enum (0 = remove child node, 1 = replace child node, 2 = remove attachment)
|-
|0x01
|0x01
|u8
|
|-
|0x02
|0x02
|u16
|Node Index
|-
|0x04
|0x02
|u16
|Child Node Index/Attachment Index
|-
|0x06
|0x02
|u16
|New Node Index (for child node replacements)
|}


==== 0x6C Section ====
==== 0x6C Section ====
Line 1,015: Line 1,980:


==== Enum Resolve Array ====
==== Enum Resolve Array ====
This section is used to resolve enum values at runtime. This section is unused in ''Tears of the Kingdom'' as all enum values are statically present in the file. However, in ''Splatoon 3'', this section is used extensively as all enum values are stored in the main executable. The first four bytes of this section specifies the number of entries in the section.
{| class="wikitable"
|+Enum Resolve Array Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x04
|u32
|Enum Value Offset
|-
|0x04
|0x04
|u32
|Enum Class Name Offset
|-
|0x08
|0x04
|u32
|Enum Value Name Offset
|}


==== String Pool ====
==== String Pool ====
The string pool is an array of null-terminated strings encoded with UTF-8. All string offsets in the file are relative to the first byte of this section.
The string pool is an array of null-terminated strings encoded with UTF-8. All string offsets in the file are relative to the first byte of this section. Note that this section also contains some unreferenced strings which are the enums for certain parameters.
[[Category:File formats]]
[[Category:File formats]]
46

edits