AINB: Difference between revisions

Dt12345 (talk | contribs)
m figured out what one of the unknown hashes was
Watertoon (talk | contribs)
m Multi-Input corrections.
 
(13 intermediate revisions by 4 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 the original October 2024 version of ''Nintendo Switch Online: Playtest Program'' (v0x407). 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 ===
=== Version Table ===
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).
{| class="wikitable"
|+
!Version
!Applications
!Differences From Previous
|-
|0x404
|''Nintendo Switch Sports, Splatoon 3''
|
|-
|0x407
|''The Legend of Zelda: Tears of the Kingdom, Super Mario Bros. Wonder, Mario Vs Donkey Kong, Nintendo Switch Online: Playtest Program (010)''
|
|-
|0x408
|''Nintendo Switch Online: Playtest Program (021)''
|>Now uses exb version 3 (u32 support)
>Added u32 type to blackboard
|}
 
== File Structure ==
AINB assumes little endian. Hashes can be assumed to be 32-bit Murmur3 unless otherwise specified.
 
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 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 data 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 ===


# 0x74-Byte File Header
==== Version 0x407 ====
# Commands
# File Header (0x74)
# Nodes
# Command Array
# Local Blackboard Parameters
# Element Array
# Node Bodies
# Blackboard
# Element Param Region
# Attachment Parameters
# Attachment Parameters
# Immediate Parameters
# Property Parameters
# Input/Output Parameters
# Input/Output Parameters
# Multi-Parameters
# Multi-Inputs
# Resident Update Array
# Jump Array
# 0x50 Section (Unused in ''TotK'')
# 0x50 Section (Unused in ''TotK'')
# Precondition Nodes
# Query Id 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 53:
# String Pool
# String Pool


=== Sections ===
== Structures ==
 
=== Helpers ===
 
==== AinbString ====
Represents a u32 offset relative to a null-terminated string from the start of the file's string pool.
 
==== AinbPtr<T> ====
Represents a u32 absolute offset from the start of the file to the struct of type "T" enclosed by <>.
 
==== AinbArray<T> ====
Represents a u32 absolute offset from the start of the file to:
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|0x0
|0x4
|u32
|Count
|-
|0x4
|
|T[Count]
|Array of struct of type T. Note; asb files only use 32-bit aligned types.
|}


==== File Header ====
=== File Header ===
AINB files begin with a 0x74 byte header. If the offset for a given section is empty, that section is not present in the file.
AINB files begin with a 0x74 byte header. If the offset for a given section is empty, that section is not present in the file.
{| class="wikitable"
{| class="wikitable"
Line 48: Line 100:
|0x04
|0x04
|u32
|u32
|Version (0x0407 in ''TotK'', 0x0404 in ''S3'' and ''NSS'')
|Version
|-
|-
|0x08
|0x08
|0x04
|0x04
|u32
|AinbString
|Filename Offset
|Filename
|-
|-
|0x0C
|0x0C
Line 63: Line 115:
|0x04
|0x04
|u32
|u32
|Node Count
|Element Count
|-
|-
|0x14
|0x14
|0x04
|0x04
|u32
|u32
|Precondition Node Count
|Query Element Count
|-
|-
|0x18
|0x18
|0x04
|0x04
|u32
|u32
|Attachment Parameter Count
|Attachment Count
|-
|-
|0x1C
|0x1C
|0x04
|0x04
|u32
|u32
|Output Node Count
|Output Element Count
|-
|-
|0x20
|0x20
|0x04
|0x04
|u32
|AinbPtr<Blackboard>
|Local Blackboard Parameters Offset
|Blackboard
|-
|-
|0x24
|0x24
|0x04
|0x04
|u32
|AinbPtr<char>
|String Pool Offset
|String Pool
|-
|-
|0x28
|0x28
|0x04
|0x04
|u32
|AinbPtr<AinbArray<Enum Relocation>>
|Enum Resolve Array Offset
|Enum Relocation Array
|-
|-
|0x2C
|0x2C
|0x04
|0x04
|u32
|AinbPtr<Property Table>
|Immediate Parameters Offset
|Property Table
|-
|-
|0x30
|0x30
|0x04
|0x04
|u32
|AinbPtr<Jump[]>
|Resident Update Array Offset
|Jump Table
|-
|-
|0x34
|0x34
|0x04
|0x04
|u32
|AinbPtr<Input Output Table>
|Input/Output Parameters Offset
|Input/Output Table
|-
|-
|0x38
|0x38
|0x04
|0x04
|u32
|AinbPtr<Multi Input[]>
|Multi-Parameters Array Offset
|Multi-Input Array
|-
|-
|0x3C
|0x3C
|0x04
|0x04
|u32
|AinbPtr<Attachment[Attachment Count]>
|Attachment Parameters Offset
|Attachment Array
|-
|-
|0x40
|0x40
|0x04
|0x04
|u32
|AinbPtr<u32[]>
|Attachment Parameters Index Array Offset
|Attachment Id Array
|-
|-
|0x44
|0x44
|0x04
|0x04
|u32
|AinbPtr<Exb>
|Expression Binary Section Offset
|Expression Binary
|-
|-
|0x48
|0x48
|0x04
|0x04
|u32
|u32
|Child Replacement Table Offset
|Child Replacement Table
|-
|-
|0x4C
|0x4C
|0x04
|0x04
|u32
|AinbPtr<u32[]>
|Precondition Node Array Offset
|Query Element Id Array
|-
|-
|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 209:
|0x5C
|0x5C
|0x04
|0x04
|u32
|AinbPtr<AinbArray<Module Caller>>
|Embedded AINB Files Offset
|Module Caller Array
|-
|-
|0x60
|0x60
|0x04
|0x04
|u32
|AinbString
|File Category Name Offset
|File Category Name
|-
|-
|0x64
|0x64
|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
|AinbPtr<AinbArray<External Action>>
|Entry Strings Offset (purpose unknown)
|External Action Array
|-
|-
|0x6C
|0x6C
Line 182: Line 234:
|0x70
|0x70
|0x04
|0x04
|u32
|AinbPtr<Module Caller Link>
|File Identification Hashes Offset (Purpose Unknown)
|Module Caller Link
|}
|}


==== Command Array ====
=== Command Array ===
The command array immediately follows the file header and is an array of all commands in the file.
The command array immediately follows the file header and is an array of all commands in the file.
{| class="wikitable"
{| class="wikitable"
Line 197: Line 249:
|0x00
|0x00
|0x04
|0x04
|u32
|AinbString
|Command Name Offset
|Name
|-
|-
| rowspan="5" |0x04
|0x04
| rowspan="5" |0x10
|0x10
|u32
|Guid
| rowspan="5" |GUID
|Guid
|-
|u16
|-
|u16
|-
|u16
|-
|u8[6]
|-
|-
|0x14
|0x14
|0x02
|0x02
|u16
|u16
|Left Node Index
|Main Element Id
|-
|-
|0x16
|0x16
|0x02
|0x02
|u16
|u16
|Right Node Index (one greater than the corresponding node index)
|Secondary Element Id (value offset by 1, 0 is reserved for invalid)
|}
|}
Command GUIDs are only used for debug messages. Right Node Index will be -1 if the command only has one child node.
Unlike asb, command GUIDs only appear to be used for debug messages. Secondary Element Id will be -1 if the command only has one child element.


==== Node Array ====
=== Property Table ===
The node array immediately follows the command array and is an array of all nodes in the file.
{| class="wikitable"
{| class="wikitable"
|+Node Entry
|+
!Offset
!Offset
!Size
!Size
Line 235: Line 278:
|-
|-
|0x00
|0x00
|0x02
|0x04
|u16
|AsbPtr<Property<s32>[]>
|Node Type Enum (see below)
|Property Array
|-
|0x02
|0x02
|u16
|Node Index
|-
|-
|0x04
|0x04
|0x02
|0x04
|u16
|AsbPtr<Property<bool>[]>
|Attachment Parameters Count
|Property Array
|-
|0x06
|0x01
|bitfield
|Node Flags
|-
|0x07
|0x01
|u8
|
|-
|-
|0x08
|0x08
|0x04
|0x04
|u32
|AsbPtr<Property<float>[]>
|Node Type Name Offset (for UserDefined nodes)
|Property Array
|-
|-
|0x0C
|0x0c
|0x04
|0x04
|u32
|AsbPtr<Property<AinbString>[]>
|Name Hash (version 0x407 only)
|Property Array
|-
|-
|0x10
|0x10
|0x04
|0x04
|u32
|AsbPtr<Property<Vector3f>[]>
|
|Property Array
|-
|-
|0x14
|0x14
|0x04
|0x04
|u32
|AsbPtr<PropertyPointer[]>
|Node Body Offset (relative to the start of the file)
|Property Array
|}
 
==== Property<T> ====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x18
|0x0
|0x02
|0x4
|u16
|AinbString
|EXB Function Count
|Name
|-
|-
|0x1A
|0x4
|0x02
|0x4
|u16
|Property Flags
|EXB Input/Output Field Size
|Flags
|-
|-
|0x1C
|0x8
|0x02
|0x4, or 0xc
|u16
|T
|Multi-Param Count
|Immediate Value
|}
 
===== Property Flags =====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x1E
|0x0
|0x02
|0x4
|u16
|u32 : 16
|Index
|-
|
|
|
|u32 : 1
|Is Use Index
|-
|-
|0x20
|
|0x04
|
|u32
|u32 : 1
|Base Attachment Parameter Index
|Is Not Local Blackboard Index
|-
|-
|0x24
|
|0x02
|
|u16
|u32 : 1
|Base Precondition Node
|
|-
|-
|0x26
|
|0x02
|
|u16
|u32 : 1
|Precondition Node Count
|
|-
|-
|0x28
|
|0x02
|
|u16
|u32 : 1
|0x58 Section Entry Offset (relative to the start of the file)
|
|-
|-
|0x2A
|
|0x02
|
|u16
|u32 : 1
|
|
|-
|-
| rowspan="5" |0x2C
|
| rowspan="5" |0x10
|
|u32
|u32 : 1
| rowspan="5" |GUID
|Is EXB Index
|-
|-
|u16
|
|
|u32 : 1
|Pulse Thread Local Storage
|-
|-
|u16
|
|
|u32 : 1
|Set Pointer Flag Bit Zero
|-
|-
|u16
|
|-
|
|u8[6]
|u32 : 7
|
|}
|}
Just like with commands, node GUIDs are only used for debug messages. The 0x58 section entry offset will be empty if unused.
 
==== PropertyPointer ====
{| class="wikitable"
{| class="wikitable"
|+Node Types
|+
!Value (Hex)
!Offset
!Value (Dec)
!Size
!Node Type
!Type
!Description
|-
|-
|0x00
|0x0
|0
|0x4
|UserDefined
|AinbString
|Name
|-
|-
|0x01
|0x4
|1
|0x4
|Element_S32Selector
|AinbString
|Class Name
|-
|-
|0x02
|0x8
|2
|0x4
|Element_Sequential
|Property Flags
|Flags
|}
 
==== Property Entries ====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x03
|0x0
|3
|0x8
|Element_Simultaneous
|Property Type Entry
|S32 Entries
|-
|-
|0x04
|0x8
|4
|0x8
|Element_F32Selector
|Property Type Entry
|Bool Entries
|-
|-
|0x05
|0x10
|5
|0x8
|Element_StringSelector
|Property Type Entry
|Float Entries
|-
|-
|0x06
|0x18
|6
|0x8
|Element_RandomSelector
|Property Type Entry
|String Entries
|-
|-
|0x07
|0x20
|7
|0x8
|Element_BoolSelector
|Property Type Entry
|Vector3f Entries
|-
|-
|0x08
|0x28
|8
|0x8
|Element_Fork
|Property Type Entry
|-
|Pointer Entries
|0x09
|}
|9
 
|Element_Join
===== Property Type Entry =====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x0A
|0x0
|10
|0x4
|Element_Alert
|u32
|Base Index - base index into the Property Table's Property Array for the specified type
|-
|-
|0x14
|0x4
|20
|0x4
|Element_Expression
|u32
|Count
|}
 
=== Input Output Table ===
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x64
|0x00
|100
|0x04
|Element_ModuleIF_Input_S32
|AsbPtr<Input<s32>[]>
|Input Array
|-
|-
|0x65
|0x04
|101
|0x04
|Element_ModuleIF_Input_F32
|AsbPtr<Output<s32>[]>
|Output Array
|-
|-
|0x66
|0x08
|102
|0x04
|Element_ModuleIF_Input_Vec3f
|AsbPtr<Input<bool>[]>
|Input Array
|-
|-
|0x67
|0x0c
|103
|0x04
|Element_ModuleIF_Input_String
|AsbPtr<Output<bool[]>
|Output Array
|-
|-
|0x68
|0x10
|104
|0x04
|Element_ModuleIF_Input_Bool
|AsbPtr<Input<float>[]>
|Input Array
|-
|-
|0x69
|0x14
|105
|0x04
|Element_ModuleIF_Input_Ptr
|AsbPtr<Output<float>[]>
|Output Array
|-
|-
|0xC8
|0x18
|200
|0x04
|Element_ModuleIF_Output_S32
|AsbPtr<Input<AinbString>[]>
|Input Array
|-
|-
|0xC9
|0x1c
|201
|0x04
|Element_ModuleIF_Output_F32
|AsbPtr<Output<AinbString>[]>
|Output Array
|-
|-
|0xCA
|0x20
|202
|0x04
|Element_ModuleIF_Output_Vec3f
|AsbPtr<Input<Vector3f>[]>
|Input Array
|-
|-
|0xCB
|0x24
|203
|0x04
|Element_ModuleIF_Output_String
|AsbPtr<Output<Vector3f>[]>
|Output Array
|-
|-
|0xCC
|0x28
|204
|0x04
|Element_ModuleIF_Output_Bool
|AsbPtr<InputPointer[]>
|Input Array
|-
|-
|0xCD
|0x2c
|205
|0x04
|Element_ModuleIF_Output_Ptr
|AsbPtr<OutputPointer[]>
|-
|Output Array
|0x012C
|}
|300
 
|Element_ModuleIF_Child
==== Input<T> ====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|0x0
|0x4
|AinbString
|Name
|-
|0x4
|0x2
|s16
|Input Element Id or Base Multi-Input Id
|-
|0x6
|0x2
|s16
|Input Element Output Plug Id or Multi-Input Count
|-
|-
|0x0190
|0x8
|400
|0x4
|Element_StateEnd
|Property Flags
|Flags
|-
|-
|0x01F4
|0xc
|500
|0x4, or 0xc
|Element_SplitTiming
|T
|Immediate Value
|}
|}
Node type names are official. For UserDefined nodes, node definitions can be found in a node definition files. This file is located at <code>NodeDefinition/Node.Product.[ver].aidefn.byml.zs</code> in the corresponding file category folder.
If the input element id is between -32768 and -100, then the input uses a multi-input. The multi-input id can be calculated as follows: <code>BaseMultiInputIndex = -100 - Index</code>.
 
==== InputPointer ====
{| class="wikitable"
{| class="wikitable"
|+Node Type Descriptions
|+
!Offset
!Size
!Type
!Type
!Description
!Description
|-
|-
|UserDefined
|0x0
|Custom node type, definition in NodeDefinition
|0x4
|AinbString
|Name
|-
|-
|Element_S32Selector
|0x4
|Conditionally links to a node depending on the value of a signed int
|0x4
|AinbString
|Class Name
|-
|-
|Element_Sequential
|0x8
|Links to nodes sequentially in the order listed
|0x2
|s16
|Input Element Id or Base Multi-Input Id
|-
|-
|Element_Simultaneous
|0xa
|Links simultaneously to multiple nodes
|0x2
|s16
|Input Element Output Plug Id or Multi-Input Count
|-
|-
|Element_F32Selector
|0xc
|Conditionally links to a node depending on the value of 32-bit float
|0x4
|Property Flags
|Flags
|-
|-
|Element_StringSelector
|0x10
|Conditionally links to a node depending on the value of a string
|0x4
|u32
|
|}
 
==== Output<T> ====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|Element_RandomSelector
|0x0
|Links to a node randomly
|0x4
|AinbString : 31
|Name
|-
|-
|Element_BoolSelector
|
|Conditionally links to a node depending on the value of a bool
|
|u32 : 1
|
|}
 
==== OutputPointer ====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|Element_Fork
|0x0
|See Resident Update Array
|0x4
|AinbString : 31
|Name
|-
|-
|Element_Join
|
|See Resident Update Array
|
|u32 : 1
|
|-
|-
|Element_Alert
|0x4
|Displays a debug message
|0x4
|-
|AinbString
|Element_Expression
|Class Name
|Passes values to and from EXB commands
|}
 
==== Input Output Entries ====
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|Element_ModuleIF_Input_S32
|0x0
|Passes a signed int as output to another node as input
|0x10
|Input Output Type Entry
|S32 Entries
|-
|-
|Element_ModuleIF_Input_F32
|0x10
|Passes a 32-bit float as output to another node as input
|0x10
|Input Output Type Entry
|Bool Entries
|-
|-
|Element_ModuleIF_Input_Vec3f
|0x20
|Passes a vector3f as output to another node as input
|0x10
|Input Output Type Entry
|Float Entries
|-
|-
|Element_ModuleIF_Input_String
|0x30
|Passes a string as output to another node as input
|0x10
|Input Output Type Entry
|String Entries
|-
|-
|Element_ModuleIF_Input_Bool
|0x40
|Passes a boolean int as output to another node as input
|0x10
|Input Output Type Entry
|Vector3f Entries
|-
|-
|Element_ModuleIF_Input_Ptr
|0x50
|Passes a pointer as output to another node as input
|0x10
|-
|Input Output Type Entry
|Element_ModuleIF_Output_S32
|Pointer Entries
|Passes a signed int as output to another node as output
|}
|-
 
|Element_ModuleIF_Output_F32
===== Input Output Type Entry =====
|Passes a 32-bit float as output to another node as output
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|Element_ModuleIF_Output_Vec3f
|0x0
|Passes a vector3f as output to another node as output
|0x4
|u32
|Input Base Index - base index into the Input Output Table's Input<T> array for the specified type
|-
|-
|Element_ModuleIF_Output_String
|0x4
|Passes a string as output to another node as output
|0x4
|u32
|Input Count
|-
|-
|Element_ModuleIF_Output_Bool
|0x8
|Passes a boolean int as output to another node as output
|0x4
|u32
|Output Base Index  - base index into the Input Output Table's Output<T> array for the specified type
|-
|-
|Element_ModuleIF_Output_Ptr
|0x10
|Passes a pointer as output to another node as output
|0x4
|-
|u32
|Element_ModuleIF_Child
|Output Count
|Unsure, appears to just be a node connected to a ModuleIF node as a child node
|-
|Element_StateEnd
|Termination node
|-
|Element_SplitTiming
|Changes when child nodes are run (Enter - first time visiting a node, Update - every frame, Leave - ran upon leaving the node)
|}
|}
=== Element Array ===
The node array immediately follows the command array and is an array of all nodes in the file.
{| class="wikitable"
{| class="wikitable"
|+Node Flags
|+Node Entry
!Bits
!Offset
!Description
|-
|1
|Is Precondition Node
|-
|1
|Is External AINB File
|-
|1
|Is Resident Node
|-
|5
|
|}
 
==== Local Blackboard Parameters ====
This section contains an array of the Blackboard parameters used by file. These parameters may be sourced from external Blackboards or parameter files. The section begins with a 0x30 byte section header followed by the array of parameters, an array of default values of said parameters, and an array of file references if applicable. The order of parameters is in the order of string, int, float, bool, vector3f, and pointer. The section header contains six entries, one for each type.
{| class="wikitable"
|+Section Header Entry
!Offset
!Size
!Size
!Type
!Type
Line 569: Line 744:
|0x02
|0x02
|u16
|u16
|Number of Entries of the Corresponding Data Type
|Element Type
|-
|-
|0x02
|0x02
|0x02
|0x02
|u16
|u16
|Parameter Index of the First Entry of the Corresponding Data Type
|Element Id - Index of this element within the element array
|-
|-
|0x04
|0x04
|0x02
|0x02
|u16
|u16
|Relative Offset of the First Entry of the Corresponding Data Type
|Attachment Count
|-
|-
|0x06
|0x06
|0x02
|0x01
|u16
|bitfield
|Element Flags
|-
|0x07
|0x01
|u8
|
|
|}
{| class="wikitable"
|+Local Blackboard Parameter Entry
!Offset
!Size
!Type
!Description
|-
|-
|0x00
|0x08
|0x04
|AinbString
|Element Type Name (for ApplicationDefined nodes)
|-
|0x0C
|0x04
|0x04
|bitfield
|u32
|Name Offset and Flags
|Name Hash (version 0x407+)
|-
|-
|0x04
|0x10
|0x04
|0x04
|u32
|u32
|String Offset (Notes)
|
|}
{| class="wikitable"
|+Name Offset Flags
!Bits
!Description
|-
|-
|22
|0x14
|Name Offset
|0x04
|AinbPtr<ElementParam<Element Type>>
|Element Param
|-
|-
|1
|0x18
|0x02
|u16
|EXB Function Count
|-
|0x1A
|0x02
|u16
|EXB Input/Output Field Size
|-
|0x1C
|0x02
|u16
|Multi-Input Count
|-
|0x1E
|0x02
|u16
|
|
|-
|-
|1
|0x20
|Does Not Have File Reference
|0x04
|u32
|Base Attachment Id
|-
|-
|7
|0x24
|File Reference Index
|0x02
|u16
|Base Query Element Id
|-
|-
|1
|0x26
|Is File Reference Valid
|0x02
|u16
|Query Element Count
|-
|0x28
|0x02
|u16
|0x58 Section Entry Offset (relative to the start of the file)
|-
|0x2A
|0x02
|u16
|
|-
|0x2C
|0x10
|Guid
|Guid
|}
|}
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.
Just like with commands, node GUIDs are only used for debug messages. The 0x58 section entry offset will be empty if unused.
 
==== Element Type ====
{| class="wikitable"
{| class="wikitable"
|+File Reference Entry
|+Element Types
!Offset
!Value (Hex)
!Size
!Value (Dec)
!Type
!Node Type
!Description
|-
|-
|0x00
|0x00
|0x04
|0
|u32
|Application Defined
|File Path Offset
|-
|0x01
|1
|Element_S32Selector
|-
|0x02
|2
|Element_Sequential
|-
|-
|0x04
|0x03
|0x04
|3
|u32
|Element_Simultaneous
|File Path Hash
|-
|-
|0x08
|0x04
|0x04
|u32
|4
|Filename Hash (no extension)
|Element_F32Selector
|-
|-
|0x0C
|0x05
|0x04
|5
|u32
|Element_StringSelector
|Unknown Hash
|}
 
==== Node Bodies ====
Each node body is composed of two parts: a 0x90 byte parameter section and a 0x14 child node section header followed by said section if applicable. The child node section contains information about the child node and specific connection types. The following parameter indices are indices into the parameter array for that specific type and data type.
{| class="wikitable"
!Offset
!Size
!Type
!Description
|-
|-
|0x00
|0x06
|0x04
|6
|u32
|Element_RandomSelector
|Int Immediate Parameter Base Index
|-
|-
|0x04
|0x07
|0x04
|7
|u32
|Element_BoolSelector
|Int Immediate Parameter Count
|-
|-
|0x08
|0x08
|0x04
|8
|u32
|Element_Fork
|Bool Immediate Parameter Base Index
|-
|-
|0x0C
|0x09
|0x04
|9
|u32
|Element_Join
|Bool Immediate Parameter Count
|-
|-
|0x10
|0x0A
|0x04
|10
|u32
|Element_Alert
|Float Immediate Parameter Base Index
|-
|-
|0x14
|0x14
|0x04
|20
|u32
|Element_Expression
|Float Immediate Parameter Count
|-
|-
|0x18
|0x64
|0x04
|100
|u32
|Element_ModuleIF_Input_S32
|String Immediate Parameter Base Index
|-
|-
|0x1C
|0x65
|0x04
|101
|u32
|Element_ModuleIF_Input_F32
|String Immediate Parameter Count
|-
|-
|0x20
|0x66
|0x04
|102
|u32
|Element_ModuleIF_Input_Vec3f
|Vector3f Immediate Parameter Base Index
|-
|-
|0x24
|0x67
|0x04
|103
|u32
|Element_ModuleIF_Input_String
|Vector3f Immediate Parameter Count
|-
|-
|0x28
|0x68
|0x04
|104
|u32
|Element_ModuleIF_Input_Bool
|Pointer Immediate Parameter Base Index
|-
|-
|0x2C
|0x69
|0x04
|105
|u32
|Element_ModuleIF_Input_Ptr
|Pointer Immediate Parameter Count
|-
|-
|0x30
|0xC8
|0x04
|200
|u32
|Element_ModuleIF_Output_S32
|Int Input Parameter Base Index
|-
|-
|0x34
|0xC9
|0x04
|201
|u32
|Element_ModuleIF_Output_F32
|Int Input Parameter Count
|-
|-
|0x38
|0xCA
|0x04
|202
|u32
|Element_ModuleIF_Output_Vec3f
|Int Output Parameter Base Index
|-
|-
|0x3C
|0xCB
|0x04
|203
|u32
|Element_ModuleIF_Output_String
|Int Output Parameter Count
|-
|-
|0x40
|0xCC
|0x04
|204
|u32
|Element_ModuleIF_Output_Bool
|Bool Input Parameter Base Index
|-
|-
|0x44
|0xCD
|0x04
|205
|u32
|Element_ModuleIF_Output_Ptr
|Bool Input Parameter Count
|-
|-
|0x48
|0x012C
|0x04
|300
|u32
|Element_ModuleIF_Child
|Bool Output Parameter Base Index
|-
|-
|0x4C
|0x0190
|0x04
|400
|u32
|Element_StateEnd
|Bool Output Parameter Count
|-
|-
|0x50
|0x01F4
|0x04
|500
|u32
|Element_SplitTiming
|Float Input Parameter Base Index
|}
Element type names are official (outside ApplicationDefined). For ApplicationDefined elements, definitions can be found in a node definition file for the respective file category. This file is located at <code>NodeDefinition/Node.Product.[ver].aidefn.byml.zs</code> in the corresponding file category folder.
{| class="wikitable"
|+Node Type Descriptions
!Type
!Description
|-
|-
|0x54
|UserDefined
|0x04
|Custom node type, definition in NodeDefinition
|u32
|Float Input Parameter Count
|-
|-
|0x58
|Element_S32Selector
|0x04
|Conditionally links to a node depending on the value of a signed int
|u32
|Float Output Parameter Base Index
|-
|-
|0x5C
|Element_Sequential
|0x04
|Links to nodes sequentially in the order listed
|u32
|Float Output Parameter Count
|-
|-
|0x60
|Element_Simultaneous
|0x04
|Links simultaneously to multiple nodes
|u32
|String Input Parameter Base Index
|-
|-
|0x64
|Element_F32Selector
|0x04
|Conditionally links to a node depending on the value of 32-bit float
|u32
|String Input Parameter Count
|-
|-
|0x68
|Element_StringSelector
|0x04
|Conditionally links to a node depending on the value of a string
|u32
|String Output Parameter Base Index
|-
|-
|0x6C
|Element_RandomSelector
|0x04
|Links to a node randomly
|u32
|String Output Parameter Count
|-
|-
|0x70
|Element_BoolSelector
|0x04
|Conditionally links to a node depending on the value of a bool
|u32
|Vector3f Input Parameter Base Index
|-
|-
|0x74
|Element_Fork
|0x04
|See Active Node Update Array
|u32
|Vector3f Input Parameter Count
|-
|-
|0x78
|Element_Join
|0x04
|See Active Node Update Array
|u32
|Vector3f Output Parameter Base Index
|-
|-
|0x7C
|Element_Alert
|0x04
|Displays a debug message
|u32
|Vector3f Output Parameter Count
|-
|-
|0x80
|Element_Expression
|0x04
|Passes values to and from EXB commands
|u32
|Pointer Input Parameter Base Index
|-
|-
|0x84
|Element_ModuleIF_Input_S32
|0x04
|Receives a signed int input from the calling AINB file
|u32
|Pointer Input Parameter Count
|-
|-
|0x88
|Element_ModuleIF_Input_F32
|0x04
|Receives a 32-bit float input from the calling AINB file
|u32
|Pointer Output Parameter Base Index
|-
|-
|0x8C
|Element_ModuleIF_Input_Vec3f
|0x04
|Receives a vector3f input from the calling AINB file
|u32
|-
|Pointer Output Parameter Count
|Element_ModuleIF_Input_String
|}
|Receives a string input from the calling AINB file
{| class="wikitable"
|+Child Node Section Header
!Offset
!Size
!Type
!Description
|-
|-
|0x00
|Element_ModuleIF_Input_Bool
|0x01
|Receives a bool input from the calling AINB file
|u8
|Bool/float Input Source Node/Output Source Node Count
|-
|-
|0x01
|Element_ModuleIF_Input_Ptr
|0x01
|Receives an object pointer input from the calling AINB file
|u8
|Bool/float Input Source Node/Output Source Node Base Index
|-
|-
|0x02
|Element_ModuleIF_Output_S32
|0x01
|Returns a signed int output from the module to the calling AINB file
|u8
|Unknown Connection Type Count (Unused in ''TotK'')
|-
|-
|0x03
|Element_ModuleIF_Output_F32
|0x01
|Returns a 32-bit float output from the module to the calling AINB file
|u8
|Unknown Connection Type Base Index (Unused ''TotK'')
|-
|-
|0x04
|Element_ModuleIF_Output_Vec3f
|0x01
|Returns a vector3f output from the module to the calling AINB file
|u8
|Standard Child Node Count
|-
|-
|0x05
|Element_ModuleIF_Output_String
|0x01
|Returns a string output from the module to the calling AINB file
|u8
|Standard Child Node Base Index
|-
|-
|0x06
|Element_ModuleIF_Output_Bool
|0x01
|Returns a bool output from the module to the calling AINB file
|u8
|Resident Update Node Count
|-
|-
|0x07
|Element_ModuleIF_Output_Ptr
|0x01
|Returns an object pointer output from the module to the calling AINB file
|u8
|Resident Update Base Index
|-
|-
|0x08
|Element_ModuleIF_Child
|0x01
|Returns the node connection name from the module to the calling AINB file
|u8
|String Input Source Node Count
|-
|-
|0x09
|Element_StateEnd
|0x01
|Termination node, specifies what resident node to return to in the calling AINB file
|u8
|String Input Source Node Base Index
|-
|-
|0x0A
|Element_SplitTiming
|0x01
|Changes when child nodes are run (Enter - first time visiting a node, Update - every frame, Leave - ran upon leaving the node)
|u8
|}
|Int Input Source Node Count
 
==== Element Flags ====
{| class="wikitable"
|+Element Flags
!Bits
!Description
|-
|-
|0x0B
|1
|0x01
|Is Query Element
|u8
|Int Input Source Node Base Index
|-
|-
|0x0C
|1
|0x01
|Is Module Caller
|u8
|Unknown Connection Type Count (Unused in ''TotK'')
|-
|-
|0x0D
|1
|0x01
|Is Resident Initialized
|u8
|Unknown Connection Type Base Index (Unused ''TotK'')
|-
|-
|0x0E
|1
|0x01
|Is Query Multi-Input
|u8
|Unknown Connection Type Count (Unused in ''TotK'')
|-
|-
|0x0F
|4
|0x01
|
|u8
|}
|Unknown Connection Type Base Index (Unused ''TotK'')
 
==== ElementParam<T> ====
Each element contains a table into the 4 parameter types, properties, inputs, outputs, and plugs. The child plugs inform the structure of the element tree.
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x10
|0x0
|0x01
|0x30
|u8
|Property Entries
|Unknown Connection Type Count (Unused in ''TotK'')
|Entries into the Property Table.
|-
|-
|0x11
|0x30
|0x01
|0x60
|u8
|Input Output Entries
|Unknown Connection Type Base Index (Unused ''TotK'')
|Entries into the Input Output Table.
|-
|-
|0x12
|0x90
|0x01
|0x14
|u8
|Plug Entries
|Unknown Connection Type Count (Unused in ''TotK'')
|Entries into the following plug pointer array.
|-
|-
|0x13
|0xa4
|0x01
|AsbPtr<>[Total Plug Count]
|u8
|Plug Data
|Unknown Connection Type Base Index (Unused ''TotK'')
|Plug Data Pointer Array.
|}
|}
If the node has any child nodes, the section header is followed by an array of u32 offsets to each of the child node entries. For most nodes, each entry is eight bytes.
 
===== Plug Entries =====
{| class="wikitable"
{| class="wikitable"
|+Child Node Entry
|+
!Offset
!Offset
!Size
!Size
Line 955: Line 1,101:
!Description
!Description
|-
|-
|0x00
|0x0
|0x04
|0x2
|u32
|Plug Type Entry
|Child Node Index
|Bool/float Input Source/Output Source
|-
|0x2
|0x2
|Plug Type Entry
|
|-
|0x4
|0x2
|Plug Type Entry
|Child Plugs
|-
|0x6
|0x2
|Plug Type Entry
|Jump Plugs
|-
|0x8
|0x2
|Plug Type Entry
|String Input Source
|-
|0xa
|0x2
|Plug Type Entry
|Int Input Source
|-
|0xc
|0x2
|Plug Type Entry
|
|-
|0xe
|0x2
|Plug Type Entry
|
|-
|0x10
|0x2
|Plug Type Entry
|
|-
|-
|0x04
|0x12
|0x04
|0x2
|u32
|Plug Type Entry
|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.
 
====== Plug Type Entry ======
{| class="wikitable"
{| class="wikitable"
|+<code>Element_F32Selector Condition Entry</code>
|+
!Offset
!Offset
!Size
!Size
Line 973: Line 1,160:
!Description
!Description
|-
|-
|0x00
|0x0
|0x04
|0x1
|u32
|u8
|Local Blackboard Parameter Index and Flags
|Count
|-
|-
|0x04
|0x1
|0x04
|0x1
|float
|u8
|Condition Value
|Base Index - base index into Plug Pointer Array
|}
|}
The first two bytes of the four bytes at offset 0x00 are the local blackboard parameter index while the last bit is whether or not the index is used or not. The first entry for <code>Element_F32Selector</code> is the minimum value condition while the second entry is the maximum value condition. The last two entries appear to be unused. The last child node entry for Selector-type nodes is the default case. The condition for this case is either a string offset to the string その他 ("Other") or 0 (in the case of <code>Element_S32Selector</code>). Input nodes that are Selector-type nodes also appear to have an additional eight bytes (purpose unknown). <code>Element_Expression</code> have an additional eight bytes per input node (16 bytes in the case of vector3f entries). The purpose of these bytes is unknown.


==== Attachment Parameters ====
====== Plugs ======
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"
{| class="wikitable"
|+Attachment Parameter Entry
|+
Typical Plug Data
!Offset
!Offset
!Size
!Size
Line 997: Line 1,183:
|0x04
|0x04
|u32
|u32
|Name Offset
|Element Id
|-
|-
|0x04
|0x04
|0x04
|0x04
|u32
|u32
|Parameters Entry Offset
|Value
|-
|0x08
|0x02
|u16
|EXB Function Count
|-
|0x0A
|0x02
|u16
|EXB Input/Output Field Size
|-
|0x0C
|0x04
|u32
|Name Hash (version 0x0407 only)
|}
|}
The interpretation of the value depends on the connection type. For input or output connections, the value is a string of the parameter name. For standard connections, the value is a string of the connection name. For jump connections, the value is an id into the Jump Table. Elements are free to extend the plug data with their own element specific values. For built-in element selector-types, excluding <code>Element_BoolSelector</code> and <code>Element_F32Selector</code>, an extra four bytes stores data used to select the child plug. 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 string. 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"
|+Parameter Entry
|+<code>Element_F32Selector Condition Entry</code>
!Offset
!Offset
!Size
!Size
Line 1,029: Line 1,201:
|0x04
|0x04
|u32
|u32
|Unknown (possibly related to debug)
|Local Blackboard Parameter Index and Flags
|-
|-
|0x04
|0x04
|0x04
|0x04
|u32
|float
|Int Immediate Parameter Base Index
|Condition Value
|}
The first two bytes of the four bytes at offset 0x00 are the blackboard parameter index while the last bit is whether or not the index is used or not. The first entry for <code>Element_F32Selector</code> is the minimum value condition while the second entry is the maximum value condition. The last two entries appear to be unused. The last child element entry for Selector-type nodes is the default case. The condition for this case is either the string その他 ("Other") or 0 (in the case of <code>Element_S32Selector</code>). Input elements that are Selector-type elements also appear to have an additional eight bytes (purpose unknown). <code>Element_Expression</code> has an additional eight bytes per input element (16 bytes in the case of vector3f entries). The purpose of these bytes is unknown.
 
=== Blackboard ===
This section contains an array of the Blackboard parameters used by file. These parameters may be sourced from external Blackboards or parameter files. The section begins with a 0x30 byte section header followed by the array of parameters, an array of default values of said parameters, and an array of file references if applicable. The order of parameters is in the order of string, int, float, bool, vector3f, and pointer. The section header contains six entries, one for each type.
{| class="wikitable"
|+Section Header Entry
!Offset
!Size
!Type
!Description
|-
|0x00
|0x02
|u16
|Number of Entries of the Corresponding Data Type
|-
|-
|0x08
|0x02
|0x04
|0x02
|u32
|u16
|Int Immediate Parameter Count
|Parameter Index of the First Entry of the Corresponding Data Type
|-
|-
|0x0C
|0x04
|0x04
|u32
|0x02
|Bool Immediate Parameter Base Index
|u16
|Relative Offset of the First Entry of the Corresponding Data Type
|-
|-
|0x10
|0x06
|0x04
|0x02
|u32
|u16
|Bool Immediate Parameter Count
|
|}
{| class="wikitable"
|+Local Blackboard Parameter Entry
!Offset
!Size
!Type
!Description
|-
|-
|0x14
|0x00
|0x04
|0x04
|u32
|bitfield
|Float Immediate Parameter Base Index
|Name Offset and Flags
|-
|-
|0x18
|0x04
|0x04
|u32
|Float Immediate Parameter Count
|-
|0x1C
|0x04
|0x04
|u32
|u32
|String Immediate Parameter Base Index
|String Offset (Notes)
|}
{| class="wikitable"
|+Name Offset Flags
!Bits
!Description
|-
|-
|0x20
|22
|0x04
|Name Offset
|u32
|String Immediate Parameter Count
|-
|-
|0x24
|1
|0x04
|
|u32
|Vector3f Immediate Parameter Base Index
|-
|-
|0x28
|1
|0x04
|Does Not Have File Reference
|u32
|Vector3f Immediate Parameter Count
|-
|-
|0x2C
|7
|0x04
|File Reference Index
|u32
|Pointer Immediate Parameter Base Index
|-
|-
|0x30
|1
|0x04
|Is File Reference Valid
|u32
|}
|Pointer Immediate Parameter Count
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"
|+File Reference Entry
!Offset
!Size
!Type
!Description
|-
|-
|0x34
|0x00
|0x04
|0x04
|u32
|u32
|
|File Path Offset
|-
|-
|0x38
|0x04
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x3C
|0x04
|0x04
|u32
|u32
|
|File Path Hash
|-
|-
|0x40
|0x08
|0x04
|0x04
|u32
|u32
|Unknown (contains address to next entry)
|Filename Hash (no extension)
|-
|-
|0x44
|0x0C
|0x04
|0x04
|u32
|u32
|
|File Extension Hash (no .)
|}
 
=== Attachments ===
{| class="wikitable"
|+
!Offset
!Size
!Type
!Description
|-
|-
|0x48
|0x00
|0x04
|0x04
|u32
|AinbString
|Unknown (contains address to next entry)
|Name
|-
|-
|0x4C
|0x04
|0x04
|u32
|0x04
|
|AinbPtr<Attachment Param>
|Parameters Entry Offset
|-
|0x08
|0x02
|u16
|EXB Function Count
|-
|-
|0x50
|0x0A
|0x04
|0x02
|u32
|u16
|Unknown (contains address to next entry)
|EXB Input/Output Field Size
|-
|-
|0x54
|0x0C
|0x04
|0x04
|u32
|u32
|
|Name Hash (version 0x407+)
|-
|0x58
|0x04
|u32
|Unknown (contains address to next entry)
|-
|0x5C
|0x04
|u32
|
|-
|0x60
|0x04
|u32
|Unknown (contains address to next entry)
|}
|}


==== Immediate Parameters ====
==== Attachment Param ====
This section contains an array of immediate 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"
|}
{| class="wikitable"
{| class="wikitable"
|+Parameter Entry
|+Parameter Entry
Line 1,162: Line 1,350:
|-
|-
|0x00
|0x00
|0x04
|0x1
|u32
|u8
|Name Offset
|Unknown (possibly related to debug)
|-
|-
|0x04
|0x01
|0x04
|0x3
|u32
|u24
|Flags
|
|-
|-
|0x08
|0x4
|
|0x30
|
|Property Entries
|Value
|Property Entries
|}
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 ====
This section contains an array of input and output parameter entries. Similarly to the immediate 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"
{| class="wikitable"
|+Output Parameter Entry
!Bits
!Description
|-
|31
|Name Offset
|-
|1
|Set Pointer Flag Bit Zero
|}
|}


==== Multi-Parameters ====
=== Multi-Input ===
This section contains entries specifying parameters that have multiple values and the sources of those values. Each entry is eight bytes.
{| class="wikitable"
{| class="wikitable"
|+Multi-Parameter Entry
|+Multi-Input Entry
!Offset
!Offset
!Size
!Size
Line 1,326: Line 1,378:
|0x02
|0x02
|u16
|u16
|Node Index
|Input Element Id
|-
|-
|0x02
|0x02
|0x02
|0x02
|u16
|u16
|Input/Output Source Parameter Index
|Input Element Output Plug Id
|-
|-
|0x04
|0x04
Line 1,337: Line 1,389:
|u32
|u32
|Flags
|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 ====
=== Jump ===
This section is an array of entries for resident nodes that are updated mid-node update sequence. The first four bytes specify the number of entries. Each entry is four bytes.
{| class="wikitable"
{| class="wikitable"
|+
|+
Line 1,397: Line 1,404:
|-
|-
|1
|1
|Update Post Current Command Calculation
|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). By default, the node is scheduled to update pre-next command calculation, however, this can change depending on the flags set. Additionally, Fork and Join nodes behave differently. Fork nodes will append the node to the run array while Join nodes will update the node post-current command calculation.
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 evaluating the behavior trees, the game maintains an array of each root element. When a command is set, the root element of the command is set to this context. A jump will change that root element to the element specified by the jump plug's element id. 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 element is an Element_Join, it will always update the root elements post current command calculation). This is primarily used for "subroutines" that run a single time then return to the main execution routine. Element_Fork and Element_Join are the main mechanism to manage multiple root elements. An Element_Fork will replace the current root elements with the element id's of it's jump plugs, possibly "forking" execution into multiple roots. The element at the end of a root element specified by an Element_Fork will optionally have a jump plug referencing a specific Element_Join. Each of these elements will push the Element_Join into the root element array. However, Element_Join has a property parameter called InFlowNum, and until that element has been pushed onto the root element 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 Element Id Array ===
This section is an array of entries of precondition nodes present in the file.
This section is an array of entries of query element ids present in the file.
{| class="wikitable"
{| class="wikitable"
|+Precondition Node Entry
|+Query Node Entry
!Offset
!Offset
!Size
!Size
Line 1,416: Line 1,423:
|0x02
|0x02
|u16
|u16
|Precondition Node Index (local to number of precondition nodes)
|Query Element Id (local to number of query nodes)
|-
|-
|0x02
|0x02
Line 1,424: Line 1,431:
|}
|}


==== Expression Binary Section ====
=== Expression Binary ===
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).
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).


Line 1,853: Line 1,860:
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.
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.


==== Embedded AINB Files ====
=== Module Caller ===
This section contains an array of all external AINB files linked to the current AINB file. The first four bytes specify the entry count.
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"
{| class="wikitable"
|+Embedded AINB File Entry
|+AINB Module Entry
!Offset
!Offset
!Size
!Size
Line 1,878: Line 1,885:
|}
|}


==== Entry Strings ====
=== External Action Array ===
The purpose of this section is unknown. The first four bytes specify the entry count.
This section appears to interact with XLink. The first four bytes specify the entry count.
{| class="wikitable"
{| class="wikitable"
|+Entry String Entry
|+Entry String Entry
Line 1,903: Line 1,910:
|}
|}


==== File Hashes ====
=== Module Caller Link ===
This section contains two 32-bit file hashes. The first hash is a hash for the file itself and the second hash appears to be a hash for that file's parent file. The purpose of these hashes is unclear.
This section contains two 32-bit file hashes. The first hash is a hash for the file itself and the second hash appears to be a hash for that file's parent file. These are used by Element_ModuleCaller.


==== 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.
This section is used to remove or replace specific elements or attachments at runtime. This is used to toggle off debug elements/attachments in release builds. The section begins with an eight-byte section header.
{| class="wikitable"
{| class="wikitable"
|+Child Replacement Section Header
|+Child Replacement Section Header
Line 1,933: Line 1,940:
|0x02
|0x02
|s16
|s16
|Override Node Count
|Override Element Count
|-
|-
|0x06
|0x06
Line 1,950: Line 1,957:
|0x01
|0x01
|u8
|u8
|Replacement Type Enum (0 = remove child node, 1 = replace child node, 2 = remove attachment)
|Replacement Type Enum (0 = remove child element, 1 = replace child element, 2 = remove attachment)
|-
|-
|0x01
|0x01
Line 1,960: Line 1,967:
|0x02
|0x02
|u16
|u16
|Node Index
|Element Id
|-
|-
|0x04
|0x04
|0x02
|0x02
|u16
|u16
|Child Node Index/Attachment Index
|Child Element Id/Attachment Id
|-
|-
|0x06
|0x06
|0x02
|0x02
|u16
|u16
|New Node Index (for child node replacements)
|New Element Id (for child element replacements)
|}
|}


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


==== Enum Resolve Array ====
=== Enum Relocation ===
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.
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"
{| class="wikitable"
Line 2,001: Line 2,008:
|}
|}


==== 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. Note that this section also contains some unreferenced strings which are the enums for certain parameters.
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]]