Skip to main content

hxbit/HXS Data (Save file payloads)

HxBit is a binary serialization and network synchronization library for the Haxe programming language. The corresponding file format, often with an .hxs extension, is designed for speed and efficiency, using a compact binary representation instead of a more verbose text-based format. This makes it ideal for applications requiring fast loading times and a small data footprint, such as games and networked applications.

Unlike standard Haxe serialization, which uses runtime type checking, HxBit employs macros to generate strictly-typed serialization code. This approach results in very fast I/O operations. The format also supports versioning by storing the schema of each class within the serialized data, which allows for robust handling of data structure changes over time, such as adding or removing fields.

Format

An HXS file is a structured binary file composed of a header, class definitions, schema definitions, and the serialized object data.

File Layout

Size (bytes)NameDescriptionStruct
4HeaderFile magic and version number.Header
VariableClass DefinitionsA list of all class types present in the file, terminated by a null marker.Class Definitions
VariableSchema SectionDescribes the structure of each class, prefixed by its total size.Schema Section
VariableObject DataThe actual instances of the serialized objects, starting with the root object.Object Data

The header is a fixed-size block that identifies the file as being in the HxBit format and specifies its version.

Size (bytes)NameDescriptionStruct
3MagicThe ASCII string "HXS".ASCII-encoded text
1VersionThe version of the HXS format, typically 0x01.Unsigned byte

Class Definitions

This section lists all the classes that are serialized in the file. It is a variable-length sequence of Class Definition Entry structures. The entire section is terminated by a single VarInt with a value of 0, which acts as a null marker for the class name.

Single Class Definition Entry

Size (bytes)NameDescriptionStruct
VariableNameThe fully qualified name of the class.String
2CLIDA 2-byte unique identifier for the class.Big-endian unsigned short
4CRC32A CRC32 checksum of the class definition.Little-endian unsigned int

Schema Section

The schema section provides a detailed description of the data structure for each class, including its fields and their types. This metadata is crucial for deserialization and version management.

Size (bytes)NameDescriptionStruct
VariableSchema SizeThe total size of the following schema data in bytes.VarInt
Schema SizeSchemasA list of schema definitions for each class.Single Schema Entry

Single Schema Entry

Each schema entry defines the structure of one class.

Size (bytes)NameDescription
VariableUIDA unique identifier for this specific schema, encoded as a VarInt. This UID is used in the Object Data section to reference instances of this type.
VariableCLIDThe corresponding class identifier, matching a CLID from the Class Definitions section. Encoded as a VarInt.
VariableField Names ListA list of strings representing the names of the class fields. The list is prefixed by its count+1 as a VarInt. A count+1 of 1 means an empty list.
VariableField Types ListA list of PropType structures defining the type of each field. The list is prefixed by its count+1 as a VarInt. A count+1 of 1 means an empty list.

Object Data

This is the main content of the file, containing the serialized data for the root object and any other objects it references. The structure is hierarchical and begins with a reference to the root object. Object references are used to handle shared instances and circular dependencies efficiently.

An object is serialized as a reference followed by its payload if it's the first time it's encountered.

Size (bytes)NameDescription
VariableObject ReferenceA VarInt representing the object's UID. A value of 0 indicates a null reference. If the UID has been seen before, this is all that is written.
VariableObject PayloadIf this is the first time an object with this UID is being serialized, its reference is followed by its payload. The payload consists of the concatenated binary data of all its fields, serialized according to its Schema.

Core Data Types

The HXS format is built upon a set of core data types that are used to represent various kinds of information.

VarInt

A variable-length integer designed to use fewer bytes for smaller numbers.

ConditionSize (bytes)Format
Value is between 0 and 1271The value is stored directly as a single byte.
Value is 128 or greater5A marker byte 0x80 followed by the full 32-bit integer value in little-endian format.

String

A string is encoded with a length prefix. This structure allows for null strings to be represented compactly.

Size (bytes)NameDescription
VariableLength+1The length of the string plus one, encoded as a VarInt. A VarInt value of 0 indicates a null string. A value of 1 indicates an empty string ("").
LengthUTF-8 DataThe string data encoded in UTF-8. This part is only present if Length+1 is greater than 1.

PropType (Property Type)

A PropType is a type descriptor that defines the type of a schema field. It consists of a Kind byte followed by an optional, type-dependent definition payload.

Size (bytes)NameDescription
1KindAn unsigned byte indicating the base type (e.g., Int, Float, String, Array, Object). A value of 0 indicates an untyped or null property.
VariableDefinitionAn optional payload that provides more detail about the type. For example, for an PArray, the definition is another PropType that describes the type of elements in the array. For a PObj (Object), the definition describes the fields of the inline object structure. For simple types like PInt, this part is empty.