Instance block format ======================= This page describes the binary format used by the module to save instances to files or databases. Specification --------------- ### Compressed container A block is usually serialized as compressed data. Compressed data starts with one byte. Depending on its value, what follows is different. - 0: no compression. Following bytes can be read as as block format directly. This is rarely used and could be for debugging. - 1: LZ4 compression. The next big-endian 32-bit unsigned integer is the size of the decompressed data, and following bytes are compressed data using LZ4 default parameters. This mode is used by default. ### Binary data This data uses big-endian. In pseudo-code: ```cpp // Root structure struct InstanceBlockData { // Version tag in case more stuff is added in the future uint8_t version = 0; // There can be up to 256 different layers in one block uint8_t layer_count; // To compress positions we need to know their range. // It's local to the block so we know it starts from zero. float position_range; LayerData layers[layer_count]; // Magic number to signal the end of the data block uint32_t control_end = 0x900df00d; }; struct LayerData { uint16_t id; // Identifies the type of instances (rocks, grass, pebbles, bushes etc) uint16_t count; // To be able to compress scale we must know its range float scale_min; float scale_max; // This tells which format instances of this layer use. For now I always use the same format, // But maybe some types of instances will need more, or less data? uint8_t format = 0; InstanceData data[count]; }; struct InstanceData { // Position is lossy-compressed based on the size of the block uint16_t x; uint16_t y; uint16_t z; // Scale is uniform and is lossy-compressed to 256 values uint8_t scale; // Rotation is a compressed quaternion uint8_t x; uint8_t y; uint8_t z; uint8_t w; }; ```