Hex Master logo Hex Master

Schema Guide

Define binary layouts with a compact, file-focused DSL.

Hex Master schemas describe endianness, named structs, scalar fields, byte ranges, arrays, repeat blocks, and offset-based sections. Run a schema at a chosen base offset to parse a file region into a structured tree with offsets, sizes, coverage reporting, and JSON export.

File type .hms
Editor Tools > Schema Editor...
Best use Custom binary headers, staged tables, animation blocks, and packed file layouts

Quick Start

What a schema contains

Required parts

  • One endianness line: endian little or endian big
  • Zero or more named struct blocks
  • Exactly one root block

Run behavior

  • The base offset is chosen when you run the schema
  • Fields parse in order
  • Later fields can refer to earlier scalar fields in the same scope
  • Repeat blocks can iterate arrays parsed earlier in the file
  1. endian little
  2. struct Entry {
  3. u32 id
  4. u16 flags
  5. u16 value
  6. }
  7. root Header {
  8. bytes[4] magic
  9. u16 version
  10. u16 entry_count
  11. Entry[entry_count] entries
  12. }

Grammar

Core forms

Scalars

  • u8, u16, u32, u64
  • i8, i16, i32, i64
  • f32, f64

Byte ranges

  • bytes[16] header
  • Useful for magic values, opaque blocks, or raw payload slices

Struct fields

  • Header header
  • Entry[count] entries
Form Meaning
u32 count Read one 32-bit unsigned integer
bytes[32] blob Read 32 raw bytes
Entry[count] entries Read an array of structs using an earlier scalar count
Entry[count] entries @table_offset Read an array from a different location in the file
Entry[count * 2] entries @base + 0x20 Use expressions in both count and offset
repeat subHeader in meshHeader.subHeaders { ... } Iterate a previously parsed array to drive a later staged section

Expressions

Supported in counts and offsets

Supported

  • Earlier scalar fields in the same scope
  • Decimal integers
  • Hex integers like 0x20
  • +, -, *, /
  • Parentheses
  • Dotted references inside repeat scopes like subHeader.faceCount

Examples

  • Entry[count + 1] entries
  • bytes[numBones * 48] pose_data
  • Section[sectionCount] sections @headerSize + 0x20

Repeat Blocks

Use staged parsing when headers describe later sections.

Form

  • repeat alias in sourcePath { ... }
  • The source must resolve to an earlier parsed array
  • The block parses sequentially at the current file position

Inside the block

  • alias refers to the current repeated item
  • Dotted references like meshHeader.subHeaders are supported
  • Counts and offsets can use values such as subHeader.vertexCount

Interaction

Using the structure tree

What it shows

  • Parsed field names and types
  • Offsets and sizes for each parsed region
  • Interpreted scalar and byte values

How to use it

  • Click a field to select that byte range in the main hex view
  • Use the tree to inspect parsed structure layout
  • Use the main hex editor itself for byte-level modifications
  • Export the current parsed tree to JSON from the Schema Editor file menu

Examples

Offset-based table

  1. endian little
  2. struct Entry {
  3. u32 id
  4. u16 flags
  5. u16 value
  6. }
  7. root Header {
  8. bytes[4] magic
  9. u16 version
  10. u16 entry_count
  11. u32 entries_offset
  12. Entry[entry_count] entries @entries_offset
  13. }

Here, entry_count controls the number of items, and entries_offset points to where the array begins relative to the selected base offset.

Examples

Character animation block with dependent transform count

  1. endian little
  2. struct Transform {
  3. f32 r00
  4. f32 r01
  5. f32 r02
  6. f32 r10
  7. f32 r11
  8. f32 r12
  9. f32 r20
  10. f32 r21
  11. f32 r22
  12. f32 px
  13. f32 py
  14. f32 pz
  15. }
  16. struct Action {
  17. u16 numBones
  18. u16 numFrames
  19. Transform[numBones * numFrames] transforms
  20. }
  21. struct Actor {
  22. u16 numAction
  23. Action[numAction] actions
  24. }
  25. root CharAni {
  26. u32 numActors
  27. Actor[numActors] actors
  28. }

This pattern is useful for animation formats where the payload count depends on more than one earlier field.

Examples

Staged mesh layout with repeat blocks

  1. endian little
  2. struct SubHeader {
  3. i32 faceCount
  4. i32 vertexCount
  5. }
  6. struct MeshHeader {
  7. i32 subMeshCount
  8. SubHeader[subMeshCount] subHeaders
  9. }
  10. struct Face {
  11. u16 a
  12. u16 b
  13. u16 c
  14. }
  15. root ItemObj {
  16. i32 numMeshes
  17. MeshHeader[numMeshes] headers
  18. repeat meshHeader in headers {
  19. repeat subHeader in meshHeader.subHeaders {
  20. Face[subHeader.faceCount] faces
  21. f32[subHeader.vertexCount] posX
  22. f32[subHeader.vertexCount] posY
  23. f32[subHeader.vertexCount] posZ
  24. }
  25. }
  26. }

This pattern is useful for formats where headers are grouped first, but the payloads they describe appear later in the file. A fuller sample is available in docs/examples/item_obj.schema.

Limits

What the current DSL does not support yet

Not supported

  • Conditional fields
  • Unions
  • Arbitrary random-access pointer chasing beyond supported offset expressions and repeat scopes
  • Named enums or bitfields

Authoring rule

  • Define dependent fields after the scalar values they depend on
  • Use repeat blocks when a later section depends on an earlier parsed array