Skip to content

Tag File Specification#

The format for tag files is still in its early stages. While we will try to avoid any breaking changes, don't be too surprised if any major format changes occur.

Tags are the primary way that any game content will be stored.

Tag data will vary wildly based on a class, but the following format details are consistent across all tags. The format is based loosely on the format used by Halo Custom Edition, while taking cues from future versions as well as injecting some of our own DNA to fit our needs better.

Remember: Any sizes that begin with 0x indicate a hexadecimal (base 16) length. Ex: 0x10 is equal to decimal 16.

File Header#

Address range: 0x0 -> 0x8F

  • 0x0 -> 0x23 - Empty padding
  • 0x24 -> 0x27 - Tag class (short name)
  • 0x2A - Will be 01 in the case of a Blamite tag, legacy blam! tags will be something else (usually 00)
  • 0x3C -> 0x3F - Will always contain blam
  • 0x60 -> 0x7F - Engine version the tag was designed for, will be used in the future for backwards compatibility
  • 0x80 -> 0x8F - Empty padding

Tag Data#

Address range: 0x90 -> End of File

Tag data will vary drastically for each tag class. Below, you can find information on how various tag fields are stored.

Tag Fields#

Be aware: Modern systems perform something known as "clamping" to ensure that variables are located at even addresses. If you encounter an exception relating to a tag using Int8 or Boolean fields, keep this in mind if addresses are seemingly "offset" by 1.

  • ASCII Fields
    • ASCII fields store text up to 32 bytes long. In memory, these fields will always take up 32 bytes of space.
  • Int32 Fields
    • Int32 fields store a 32-bit integer, and take up 4 bytes in memory.
  • Int16 Fields
    • Int16 fields store a 16-bit integer, and take up 2 bytes in memory.
  • Int8 Fields
    • Int8 fields store an 8-bit integer, and take up 1 byte in memory.
  • Boolean Fields
    • Boolean fields store a true or false value (as either 01 or 00) and take up 1 byte in memory.
  • ColorFloat Fields
    • ColorFloat fields store a D2D1_COLOR_F, and take up bytes in memory.
  • Enum Fields
    • Enum fields allow for the selection of one of many items, such as a ComboBox. They take up bytes in memory, and the stored value is the index of the enumerator item.
  • Bitfield8 Fields
    • Bitfield8 fields store 8 boolean values, and take up 8 bytes in memory. These are typically used for a series of related flags. These will (usually) be preferred to boolean fields.
  • Bitfield16 Fields
    • Bitfield16 fields store 16 boolean values, and take up 8 bytes in memory. These are typically used for a series of related flags. These will (usually) be preferred to boolean fields.
  • Bitfield32 Fields
    • Bitfield32 fields store 32 boolean values, and take up 8 bytes in memory. These are typically used for a series of related flags. These will (usually) be preferred to boolean fields. I don't know why you'd have 32 flags all related, but hey - it's an option. And options are good.
  • Tag Blocks
    • Blocks are the most complex type of tag in the engine. They are used to group together many related fields, as well as provide support for "entries". A block's entries all share the same data structure, but can have unique values per-entry. These allow for more flexibility when defining new tags and see usage all over the place.
    • Memory Structure (addresses given are relative to the start of the block data)
      • Total size in main tag data: 0x14
      • 0x0 -> 0x7 - Block identifier, will always contain tbfd followed by 4 null bytes.
      • 0x8 -> 0xB - Size of each entry
      • 0xC -> 0xF - The address in memory (when a tag is loaded in-engine), or the file offset to the block entry data
      • 0x10 -> 0x13 - The number of entries in the block