Blender’s .blend file format is famous for its speed, but fundamentally it is a raw in-memory C struct dump keyed by embedded “DNA” definitions. While clever in the 1990s, this approach creates fundamental architectural liabilities:
- Struct Coupling: Data is tightly coupled to compiler pointer size and byte alignment of the era.
- Brittle Migrations: Every minor struct change requires manual
do_versionsC migration code. - Whole-File Loading: You cannot partially load or stream assets from a 40 GB scene.
- Pointer Fragility: Inter-object references use raw memory pointers, making git diffing and asset merging nearly impossible.
To solve this, we designed the .nxm (Nexum 3D) format specification (v0.1) from first principles.
The Core Design Goals
graph LR
Durability["50-Year Durability<br/>(Additive Schema Evolution)"] --> Core["NXM Container Core"]
PartialLoad["Partial / Lazy Load<br/>(Stream chunks on demand)"] --> Core
Dedup["BLAKE3 Deduplication<br/>(Content-addressed buffers)"] --> Core
ZeroCopy["Zero-Copy Deserialization<br/>(FlatBuffers tables)"] --> Core
1. Container Structure
A .nxm file is a chunked binary container where the Table of Contents (TOC) lives near the end of the file, allowing writers to stream data out continuously without knowing total byte counts in advance:
┌────────────────────────────────────────────────────────────┐
│ HEADER (fixed 64 bytes - magic, endianness, flags, UUID) │
├────────────────────────────────────────────────────────────┤
│ CHUNK 0 (Type: 'MESH', ID: 0x1A4F, BLAKE3, payload) │
│ CHUNK 1 (Type: 'MATL', ID: 0x1A50, BLAKE3, payload) │
│ ... │
│ CHUNK n (Type: 'GEOM', ID: 0x9B12, zstd compressed vertex) │
├────────────────────────────────────────────────────────────┤
│ TABLE OF CONTENTS (Index of all chunks: ID → offset, size) │
├────────────────────────────────────────────────────────────┤
│ FOOTER (fixed 32 bytes - TOC offset, TOC hash, 'NXM!END') │
└────────────────────────────────────────────────────────────┘
2. FlatBuffers for Schema Evolution & Zero-Copy Access
We evaluated multiple serialization formats:
- Raw Struct Dumps: Fails forward/backward compatibility.
- glTF / JSON + bin: High parsing overhead for complex digital content creation (DCC) node graphs.
- Protocol Buffers: Requires object allocation on deserialization.
- FlatBuffers: Selected. Allows zero-copy reads, strict backward-compatible additive field evolution, and native C++ performance.
Heavy mesh geometry arrays (GEOM) and high-resolution textures (IMAG) live in dedicated raw binary chunks referenced by 64-bit chunk IDs, allowing independent Zstandard compression and content deduplication.
3. How a 50-Year File Works
- Additive Schema Evolution: Fields in FlatBuffers tables are only ever added, never removed or renumbered. Old software versions ignore unknown fields; new software sees default values.
- Schema Catalog Versions: The file header tracks the catalog schema revision. When a breaking semantic change occurs, permanent, chained upgraders transform old representations on load.
- Conformance Corpus: Every schema milestone is committed with real
.nxmtest files to guarantee that any file ever written will always open decades later.
The complete NXM specification lives in my 3D modeling docs and will be published separately.