3rd NX File Format [PKG4.1]

The NX file format was designed with speediness and ease of reading in mind, to speed up loading times for anything that uses a node-tree-based data file format.

In the NX file format, the following should be followed:

These are the reference implementations of the NX format:

Recommended File Format

NameTypeDescription
HeaderHeaderFile header
Node dataNode[]Node data, including all children.
String offset tableUInt64[]String offset table. Contiguous block.
String dataString[]String data.
Bitmap offset tableUInt64[]Bitmap offset table. Contiguous block.
BitmapsBitmap[]Bitmap data.
Audio offset tableUInt64[]Audio offset table. Contiguous block.
Audio dataAudio[]Audio data.

Header (52 bytes)

NameTypeDescription
MagicUInt8[4]"PKG4" = {0x50, 0x4B, 0x47, 0x34}
Node countUInt32Total number of nodes in the file. Cannot be zero.
Node block offsetNode*Offset to the start of the node block, which should be the base node: the parent of all other nodes in the file. This must be a multiple of 4.
String countUInt32Total number of String entries in the file. Cannot be zero.
String offset table offsetOffsetTable*Offset to the string offset table in the file, with the number of entries equal to the String count. This must be a multiple of 8.
Bitmap countUInt32Total number of Bitmap entries in the file. Zero indicates no bitmap data.
Bitmap offset table offsetOffsetTable*Offset to the bitmap offset table in the file, with the number of entries equal to Bitmap count. This must be a multiple of 8. Ignored if Bitmap count is 0.
Audio countUInt32Total number of Audio entries in the file. Zero indicates no audio data.
Audio offset table offsetOffsetTable*Offset to the audio offset table in the file, with the number of entries equal to Audio count. This must be a multiple of 8. Ignored if Audio count is 0.

Node (20 bytes)

Each Node is assigned a zero-based 32-bit unsigned ID in the order they appear in the node block; that is, the first Node (the base node) has ID 0, the second node has ID 1, and so on. This ID is used to point to child nodes of Nodes.

All Nodes should be in one contiguous block, which should be of size 20 * Number of nodes. Nodes must be aligned to an 8-byte boundary.

Children Nodes of each parent Node must be consecutive in one contiguous block, and the ID of the first child in the block is specified in the First Child ID field of the parent Node. Children Nodes of each parent Node must be sorted in ascending order according to the UTF-8 value of the node name of each child. Children Nodes of any given parent Node must have unique node names.

The base node should have an ID of 0, and preferably have type 0 (None).

NameTypeDescription
Node nameUInt32String ID representing the name of this node
First Child IDUInt32Node ID of first child. Present but ignored if child count is zero (0).
Children countUInt16Zero means there are no children.
TypeUInt160 = No data
1 = Int64
2 = Double
3 = String (UInt32 ID)
4 = Vector
5 = Bitmap (UInt32 ID, UInt16 Width, UInt16 Height)
6 = Audio (UInt32 ID, UInt32 Length)
DataVariesThis field is always 8 bytes.
TypeDescription
0NoneThis field is ignored.
1Int6464-bit signed integer.
2Double64-bit IEEE double-precision floating point.
3String32-bit unsigned string ID.
4VectorTwo 32-bit signed integers (Int32), for X and Y respectively.
5Bitmap32-bit unsigned bitmap ID, followed by 16-bit unsigned width and height in that order. Ignored if Bitmap count in Header is 0.
6Audio32-bit unsigned audio ID, followed by 32-bit unsigned data length. Ignored if Audio count in Header is 0.

String (2-65537 bytes)

Each String is assigned a zero-based unsigned 32-bit ID. Offsets to Strings are located in the String offset table. Strings do not need to be in a contiguous block, though this is recommended. Strings must be aligned to a 2-byte boundary.

NameTypeDescription
LengthUInt16Length, in bytes, of the following string data
String dataUInt8[]String data, encoded in UTF-8. This byte array is Length bytes long.

Bitmap (4-4294967299 bytes)

Each Bitmap is assigned a zero-based unsigned 32-bit ID. Offsets to Bitmaps are located in the bitmap offset table. Bitmaps do not need to be in a contiguous block, though this is recommended.

NameTypeDescription
LengthUInt32Length, in bytes, of the image data. Uncompressed length is Width * Height * 4. Width and Height are specified in the Node's Data field after the bitmap ID.
Bitmap dataUInt8[]Bitmap data, stored in BGRA8888 format, that is, 1 byte each for the blue, green, red and alpha components, in that order. This data is compressed with LZ4. This byte array is Length bytes long.

Audio (0-4294967295 bytes)

Each Audio is assigned a zero-based unsigned 32-bit ID. Offsets to Audios are located in the audio offset table. Audios do not need to be a contiguous block, though this is recommended.

NameTypeDescription
Audio dataUInt8[]Audio data, including the 82-byte WZ header. This byte array is Length bytes long. Length is specified in the NX node's data field after the audio ID.

Offset Table

Offset tables are used to refer to Strings, Bitmaps and Audios. String offsets must be a multiple of 2. Bitmap and audio offsets must be a multiple of 8.

NameTypeDescription
Offset ArrayUInt64[]Sequential offset array; the first offset has ID 0, the second has ID 1, and so on.

Acknowledgements:

Contributions to this specification are welcome. Please fork and then send a pull request to this repository.

Creative Commons License
This specification is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.