The AIN file format (System 4)
System 4 AIN files contain a game’s code and script.
Encryption
AIN files are encrypted by XORing each byte of the input with the output of a mersenne twister PRNG seeded with the key 0x5D3E3.
Sections
AIN files are broken into a number of sections, each beginning with a 4 byte ASCII magic word. The structure of each section varies. Not all sections are present in all versions of the AIN format.
VERS |
AIN file version |
|
KEYC |
Keycode (???) |
Removed in v12 |
CODE |
Bytecode |
|
FUNC |
Function descriptors |
|
GLOB |
Global variable descriptors |
|
GSET |
Global variable initvals |
Removed in v12 |
STRT |
Struct descriptors |
|
MSG0 |
Messages |
|
MSG1 |
Messages (encrypted) |
Since Rance IX (introduced mid-v6) |
MAIN |
Index of main function |
|
MSGF |
Index of message function |
|
HLL0 |
Library descriptors |
|
SWI0 |
Switch descriptors |
|
GVER |
Game version |
|
STR0 |
String constants |
|
FNAM |
Filenames |
|
OJMP |
??? |
Removed in v7 |
FNCT |
Function type descriptors |
Until Oyako Rankan (removed mid-v6) |
DELG |
Delegate descriptors |
Since Oyako Rankan (introduced mid-v6) |
OBJG |
Global group names |
|
ENUM |
Enums |
Since Rance X |
VERS Section
KEYC Section
CODE Section
The CODE section contains the actual code of the game, compiled from the System 4 language down to bytecode.
0x0 |
4 |
Size of bytecode |
0x4 |
Varies |
Bytecode |
Instructions in System 4 bytecode consist of a 16-bit opcode followed by a variable number of 32-bit arguments (depending on the opcode).
FUNC Section
0x0 |
4 |
Function count |
0x4 |
Varies |
Function descriptors |
Function Descriptors
4 |
Function start address |
|
Varies |
Function name (null-terminated) |
|
4 |
Is label? |
AIN version 1-6 only |
Varies |
Return type descriptor |
|
4 |
Number of arguments |
|
4 |
Total number of variables |
Includes arguments |
4 |
Checksum |
AIN version 1+ only |
Varies |
Variable descriptors |
|
Variable Descriptors
Varies |
Variable name (null-terminated) |
|
Varies |
Variable name2 (null-terminated) |
AIN version 12+ only |
Varies |
Type descriptor |
Typically 24 bytes |
4 |
Has value? |
AIN version 8+ only |
Varies |
Variable value |
See below |
If the ‘Has value?’ field is 1, then:
- If the variable is a string, ‘Variable value’ is a null-terminated string value
- If the variable is a reference type or a delegate, ‘Variable value’ is not present
- Otherwise, ‘Variable value’ is a 32-bit value
If ‘Has value?’ is 0, then ‘Variable value’ is not present.
Type Descriptors
A type descriptor is a 3-tuple of a data type, struct type and array rank, sometimes followed by an additional type descriptor for the sub-type.
4 |
Data type |
4 |
Struct Type |
4 |
Array rank |
Varies |
Sub-type |
Starting with ain v11, the meaning of the ‘array rank’ value changes. Rather than giving the rank of an array, it becomes a boolean which indicates the presense of a sub-type. If this value is 1, then another type descriptor should be read recursively.
Return Type Descriptors
Before AIN v11, return type descripors inside of function and functype descriptors do not have an ‘array rank’ field like regular type descriptors.
4 |
Data type |
4 |
Struct Type |
Starting in AIN v11, return type descriptors are identical to regular type descriptors found elsewhere.
GLOB Section
0x0 |
4 |
Global count |
0x4 |
Varies |
Global variable descriptors |
Global Variable Descriptors
Varies |
Variable name (null-terminated) |
|
Varies |
Variable name2 (null-terminated) |
AIN version 12+ only |
Varies |
Type descriptor |
Typically 24 bytes |
4 |
Group index |
AIN version 5+ only |
GSET Section
0x0 |
4 |
Global initval count |
0x4 |
Varies |
Global initval descriptors |
Global Initval Descriptors
4 |
Global index |
Index into GLOB array |
4 |
Data type |
|
Varies |
Value |
|
If data type is AIN_STRING (12) then ‘Value’ is a null-terminated string. Otherwise it’s a 32-bit value.
STRT Section
0x0 |
4 |
Structure count |
0x4 |
Varies |
Structure descriptors |
Structure Descriptors
Varies |
Structure name (null-terminated) |
|
4 |
Interface count |
AIN version 11+ only |
Varies |
Interface descriptors |
AIN version 11+ only |
4 |
Constructor function index |
|
4 |
Destructor function index |
|
4 |
Variable count |
|
Varies |
Variable descriptors |
|
4 |
Virtual method count |
Since HENTAI LABYRINTH |
Varies |
Virtual methods (function indices) |
Since HENTAI LABYRINTH |
Interface Descriptors
MSG0 Section
0x0 |
4 |
Message count |
0x4 |
Varies |
Messages (null-terminated strings) |
MSG1 Section
Encrypted Strings
4 |
Length (bytes) |
Varies |
Encrypted data |
The encrypted data can be decrypted as follows,
MAIN Section
0x0 |
4 |
main function index |
MSGF Section
0x0 |
4 |
message function index |
HLL0 Section
Library Descriptors
Library Function Descriptors
Argument Descriptors
Varies |
Name (null-terminated) |
|
4 |
Return data type |
Until v14+ |
Varies |
Return type descriptor |
Since v14+ |
SWI0 Section
Switch Descriptors
Case Descriptors
GVER Section
STR0 Section
0x0 |
4 |
String count |
0x4 |
Varies |
Strings (null-terminated) |
FNAM Section
0x0 |
4 |
File count |
0x4 |
Varies |
File names (null-terminated) |
OJMP Section
FNCT Section
Functype Descriptors
DELG Section
OBJG Section
0x0 |
4 |
Delegate count |
0x4 |
Varies |
Global group names (null-terminated) |
ENUM Section
0x0 |
4 |
Delegate count |
0x4 |
Varies |
Enum names (null-terminated) |