Relic Binary File

General Information
Relic Binary Files, or RBFs are the standard files used by Dawn of War II for storing attributes for all the games units, squads, abilities, wargear, weapons and many others. RBF files consist of a tree of key/value pairs; a name and a value. Each node can either have an integer value, a string (text) value, a float (decimal) value, or a table (it contains other nodes).

In certain cases, RBF attributes can be modularly added to an RBF to determine the actions of a certain event. For example all abilities contain a "start_target_actions" key that contains a table of RBF Actions that determine the ability effects, including modifying the target's attributes, damaging them, teleporting them, reinforcing them, making them retreat, taunting them, making them invulnerable and many others.

Format Info
The header starts with a 8 byte long format declaration. The format declaration is what tells the game or editor that this is a valid RBF file. So far there is only one know format declaration: Header consists of 10 subsets of 32-bit unsigned integers. The actual arrays in the file can occur in any order, since references to their location and their lengths are handled by the header. However, the default Relic format is the same order as in the header:
 * RBF V0.1
 * Table array offset
 * Table array entries
 * Key array offset
 * Key array entries
 * Data Index array offset
 * Data Index array entries
 * Data array offset
 * Data array entries
 * String array offset
 * String array size in bytes
 * Table array
 * Key array
 * Data Index array
 * Data array
 * String array

Table array
The table array consists of entries with two 32-bit unsigned integer values each. They are referred to simply by the order in which they occur in the file, meaning i.e. that a data entry that attempts to look up the table with an index of 55 would simply fetch the 56th value in the table array (taking into account that the first value would have an index id of 0). If the table has no children, then the data index lookup is ignored. If the table only has a single child, then it look up the child entries directly from the relevant entry in the data array. If it has multiple children, then it will attempt to look up the index from the data array index instead. It will look for the denoted index id, and then read an amount of values from that point that corresponds to the value denoted in the tables data index lookup.
 * Children of the table
 * Data index lookup.

Also note that the first table of any RBF contains the file's root nodes, which are nodes that are on the top level of the tree and not inside any other tables.

Key array
The key array consists of 64 byte NULL padded ASCII strings. These are used as the name of the various properties in the decompiled attributes file. They are referred to by the order they occur in the file.

Data Index array
The data index array consists of continual references to index of entries in the data array, stored as 32-bit unsigned integers. These are used for looking up a tables children data values. The standard sorting that Relic uses for its RBFs makes the data index array fairly redundant, however custom RBF burners will often store things in a different order which necessitates the data index array.

Data array
The data array consists of entries containing three 32-bit values. The key index reference denotes an index to look up in the key array, which defines the name of the property. In order to interpret value correctly, you'll first have to determine its type through the type property of a data array entry. The type is stored as a value between the range of 0 to 4, each meaning the following:
 * Type, which is a 32-bit unsigned integer.
 * Key, an index reference is a 32-bit unsigned integer.
 * Value, whose storage type depends on the type value.
 * 0 = The value is a boolean (true/false) stored as a 32-bit signed integer. If the value is 0, then it is false. If it is 1, then it is true.
 * 1 = The value is a 32-bit single precision float.
 * 2 = The value is a 32-bit signed integer.
 * 3 = The value is a string reference stored as a 32-bit signed integer and refers to the byte in the string array (relative to its offset) at which the string reference is located.
 * 4 = The value is a reference to a table and refers to an index in the table array.

String array
The string array is a bit special in that the size of each entry is dynamical. Each entry consists of two parts:
 * Length of string in bytes
 * The actual string

Note that there is no NULL termination or termination of any kind. They are stored continually. Instead of being looked up by its index, it is looked up by the byte (relative to the start of the index array) at which the entry's length is denoted.