Skip to content

Format Coverage ​

Numeric fields are little-endian. Storage preserves raw floats, strings, placeholder fields and known opaque ranges. Field layouts list serialized members, conditions and explicit nonserialized parameters.

FamilyExtensionsProfiles
Geometryn3pmesh, n3cskin, n3cskinsProgressive storage, standalone and named four-LOD skins
Compositionn3cpart, n3cplug, n3shape, n3chrMaterials, transforms, references and optional character tails
Animationn3joint, n3animRecursive joint keys and control records including sentinel clips
Environmentn3skyThree suns, six clouds, moon and unsorted schedule
Effectsfxb, n3fxplugFXB bundle 0-3, observed parts 0-7/base 0-2, known opaque extensions
Worldgtd, opdGTD 0-2 including lightmaps/water; explicit OPD collision/spatial cells
UI/datauif, tblExternal UIF version/spacing profiles; nine TBL types and encryption
Texturesdxt, gtt, tctNTF, sequential collections, DXT1/3/5 and D3DFMT 20-26
Imagesbmp, tgaBI_RGB 8/24/32-bit BMP; uncompressed truecolour 24/32-bit TGA

Layout Parameters ​

OPD does not serialize its grid-cell size. Default gridCell is 16; observed variants may require 8, 4, 32, 64 or 128. Pass a verified profile explicitly using parseOpd(bytes, { parameters: { gridCell: 64 } }) or Rust parse_opd_with_limits. Writers retain the profile as metadata but do not rebuild collision/spatial grids after geometry/object edits. Applications must maintain those dependent structures consistently.

UIF version is external. Default fileVersion is 0x4f0; modern child counts are i16 plus node-version i16, older counts are i32. spacingPresent defaults to 1 and selects the ambiguous modern text-line-spacing field when node versions do not decide it. Use 0 for the omitted-spacing variant. Unknown controls and historical layouts are not supported merely by retaining a suffix.

GTD lightmaps contain signed i16 X/Z then an embedded NTF. Water vertices retain all eleven f32 fields even where semantics remain undocumented. FX-plug's eight extension bytes and FXB newer tails remain opaque. FXB v3 preserves the observed 44/45-byte tail, not arbitrary unknown suffixes.

Pixels And Round Trips ​

Unchanged containers retain compressed blocks. New compression is lossy; Rust and JS encoders can choose different valid endpoints. Packed linear channels quantize. Legacy untyped compatibility images are preserved, not decoded under a guessed format. BMP/TGA RLE is outside these profiles.

NTF mip chains follow engine rules and stop at 4x4. Collection boundaries are calculated from payload sizes, not signature scans inside pixels. Unframed suffixes inside GTT/TCT are rejected.

Evidence ​

Layouts were transcribed from supplied format references and checked against named engine routines, including CN3Terrain::Load for nonzero lightmaps. Engine source is a research input, not distributed code or a build dependency. Original corpus counts in the supplied notes have not been independently reproduced by this project.

Shared generated fixtures check creation, stored values, byte-exact rewrites, malformed headers and cross-language parity. They are not proof of compatibility with every game version. Run npm run verify:formats -- /path/to/assets against a legally usable private corpus; no proprietary content should be committed.

MIT licensed. Game assets are not distributed.