BinarySpecifications

Aggregate Repository of all Binary File Format Specifications I have released.

View on GitHub

ShadeNBT Version 1.4

Release Date: 2021-03

Description: ShadeNBT is a modification on the standard Named Binary Tag Specification, created for the Game Minecraft. The format is used to protection against corrupt game files, as well as to ensure Binary Version Compatibility. The format contains a 7-byte header, which declares that the file is a ShadeNBT File, followed by a well-formed uncompressed NBT File, that contains a single, nameless compound tag.

A Variation of this Specification, known as CryptoShade, provides Strong, Password-based Encryption of the enclosed NBT File and MAY additionally be supported by conforming implementations.

References

This document references a modification of the Named Binary Tag Specification, created by Markus Perrson for the Game Minecraft. An up to date version of the NBT Specification can be found here.

All Binary Datatypes are written and read according to [LCS4 - Binary IO].

The terms “MUST”, “SHALL”, “SHOULD”, “MAY”, “MUST NOT”, “SHALL NOT”, “SHOULD NOT”, “REQUIRED”, “RECOMMENDED”, and “OPTIONAL”, when in all caps, are to be interpreted according to [RFC 2119] and [RFC 8174]. When the terms MUST, SHALL, MUST NOT, SHALL NOT, or REQUIRED are used in terms of a requirement on a file produced by this specification, the implementation MUST NOT produce a file that violates the requirement, and MUST reject any file that violates the requirement.

Changes from 1.3

The integrity flag from 1.3 was deprecated and made optional to support. The recommendation that the flag be set was removed. The NaN flag was deprecated and it’s effect was made default.

Rejecting Files

For various reasons implementations MUST, SHOULD, or MAY reject a ShadeNBT File. If a user attempts to load a file which is rejected, an error MUST be reported to the user. A rejected file MUST NOT be loaded. Implementations MUST NOT create a ShadeNBT File that it would reject.

Conformance

Structure of a Shade Save File

Each Shade file shall contain a header, which is defined by the following structure:

shade_head{
	Byte magic[4];
	Version ver;
	Byte shadeFlags;
}

magic MUST be exactly the bytes [AD 4E 42 54], or the file MUST be rejected.

ver encodes the version of the ShadeNBT Specification which the file was created in. This is encoded in the LCLib Versioning format, where the major value indicates the major version-1, and the minor value indicates the minor version. The current version of the specification is 1.4, and therefore the version for a file created in this version is [00 04].

Conforming Implementations MUST Document at least 1 supported version, and support all versions with the same major version number and a lesser or equal minor version number as each of those supported versions.

Conforming Implementations SHOULD support the latest version of the Specification released at the time the Implementation was created or updated.

Implementations MUST reject any file that indicates an unsupported version, or any version that has not been released.

If ver indicates the version 1.1 or less, then shadeFlags does not exist and the file MUST be read in Big Endian Byte Order Mode, with the integrity flag clear and . Otherwise, shadeFlags indicates a series of flags.

Bit 0x80 of shadeFlags is the byte order flag. If set, the file is read in Little Endian Byte Order Mode, otherwise, it is read in the Big Endian Byte Order Mode.

Bit 0x40 of shadeFlags is the integrity flag. If a file has this bit set, then 32-bytes following the header is a SHA-256 hash of the TAG_Compound. the If the hash of the Compound does not match these bytes, the file MAY be rejected. If this bit is set and the version indicated is 1.2 or less, then the file MUST be rejected. This bit is deprecated and SHOULD not be set by implementations conforming to version 1.4.

If shadeFlags has its 3rd most significant bit set (0x20), and the indicated version is 1.3 or later, then NaN values may be written in float, double, float array, and double array tags. A file with this flag set MAY be rejected by an implementation. If this bit is set and the version indicated is 1.2 or less, then the file MUST be rejected. An implementation MAY accept files with NaN values in float, double, float array, or double array flags reguardless of this flag. This flag is deprecated and SHOULD not be set by implementations conforming to version 1.4.

If any other bits are set in shadeFlags, the file MUST be rejected.

NBT Data

NBT Data Tags are encoded using LCLib Binary Data IO Format, in Big Endian. There are various tags which indicate the type of data stored.

NBT_Tag{
	Byte tag;
	String name;
	union TAG_Payload{
		Byte tag_byte;
		Short tag_short;
		Int tag_int;
		Long tag_long;
		Float tag_float;
		Double tag_double;
		ByteArray{
			Int len;
			Byte payload[len];
		} tag_byte_array;
		string tag_string;
		List{
			Byte listTagType;
			Int len;
			TAG_Payload[len];
		} tag_list;
		Compound{
			NBT_Tag tags[];
			Byte endTagType;
		} tag_compound;
		IntArray{
			Int len;
			Int payload[len];
		}tag_int_array;
		LongArray{
			Int len;
			Long payload[len];
		}tag_long_array;
		FloatArray{
			Int len;
			Float payload[len];
		}tag_float_array;
		DoubleArray{
			Int len;
			Double payload[len];
		}tag_double_array;
		UUID tag_uuid;
	}payload;
}

Where tag determines the payload, and shall be either 0x01 (tag_byte), 0x02 (tag_short), 0x03 (tag_int), 0x04 (tag_long), 0x05 (tag_float), 0x06 (tag_double), 0x07 (tag_byte_array), 0x08 (tag_string), 0x09 (tag_list), 0x0a (tag_compound), 0x0b (tag_int_array), 0x0c (tag_long_array), 0x0d (tag_float_array), 0x0e (tag_double_array), 0x0f (tag_uuid).

If any other tag is read, except for tag 0 inside of a tag_compound, the file MUST be rejected. If the tag is 0x10 and the version indicated is 1.3 or lower, then the file MUST be rejected. If the tag is 0x0d, 0x0e, or 0x0f and the version indicated is 1.2 or lower, then the file MUST be rejected. If the tag is 0x0c and the version indicated is 1.0, then the file MUST be rejected.

In Compound tags shall continue until the tag read is 0x00.

In List, listTagType shall be any valid value for tag, or 0x00 if len is 0. If it is not, then the file MUST be rejected.

Every ShadeNBT File shall contain a Compound Payload following the header. This Compound must contain a single nameless NBT Tag which is a tag_compound. This Compound is refered to as the Top Level Compound.

There may be any number of zero bytes following the Compound Payload in a ShadeNBT File.

Limits of the Implementation

Implementations may impose various limits upon Read ShadeNBT Files, including number of nested compound and list tags, and number of tags in a compound. Specifically, Implementions MUST support at least:

Implementations MAY choose to reject any file which violates any of those above limits.