NBT format

The Named Binary Tag (NBT) format is use by Minecraft for the various files in which it saves data. The format is designed to store data in a tree structure made up of various tags. All tags have an ID and a name.

Another more user-friendly format of NBT is in plain string, as used in commands. This format is referred to as SNBT, short for stringified NBT.

SNBT format
SNBT, also known as data tag, is often used in command $$. It can be described starting with attribute-value pairs enclosed in curly braces. One common usage of data tags $$ is in commands, used to specify complex data for any entity.

A data tag consists of zero or more attribute-value pairs delimited by commas and enclosed in curly braces. Each attribute-value pair consists of an tag name and the tag's value, separated by a colon. Some values, however, may be a compound tag and themselves contain attribute-value pairs, allowing a data tag to describe a hierarchical data structure.


 * Example:

Tag's name can be enclosed with double quotes if necessary.

It is different from the JSON format; hence, any JSON used in NBT, such as raw JSON text, must be enclosed within a string tag.

Format of each type
The defined data structures also expect the values to be of the correct type.

NBT object
When the game is running, entities and block entities in loading chunks are stored in the memory. They are not strored with NBT, instead, they are just programmatic objects.

When processing NBT operations, the game needs to obtain programmatic NBT object from entities/block entities, parse SNBT into programmatic NBT object, modify entities/blocks based on provided programmatic NBT object, or convert programmatic NBT object into SNBT.

Getting NBT object
When getting NBT from an entity/block, some certain properties are added into programmatic NBT object.

Note that not all properties are added. For example, the value of whether a player is opening a chest won't be added into NBT object.

A value is added with certain data type. For example, a namespaced ID will be converted to a string value.

These NBT objects will also be stored into game's save files as NBT files when the game quits or automatically saves. So the data structures that NBT tags describe and the data type for each tag are basically the same ones used in game's save files. These data structures are described in other articles and commands expect data tags to use the same attribute names (which are case-sensitive):

Conversion to SNBT
An programmatic NBT object would be converted to a SNBT when trying to get it with etc.

After converted, a number is always followed by a letter (lowercase for b, s, f, d, and uppercase for L) except. For example,  for a short,   for a float, etc.

And a string is always enclosed by double or single quotes.

Other data types are expressed as the table above.

Conversion from SNBT
An SNBT will be converted to a programmatic NBT object when parsed by the game.

A number that followed by a letter (B, S, L, F, D, or their lowercase) is resolved to corresponding data type. For example,  for a short,   for a float, etc. The letter can be uppercase or lowercase. When no letter is used, it assumes double if there's a decimal point, int if there's no decimal point and the size fits within 32 bits, or string if neither is true.

A square-bracketed literal is assumed to be a list unless an identifier is used:  for an int array and   for a long array.

and  are converted as   and   respectively.

Modifying entity/block based on NBT object
Modifying entity/block based on a programmatic NBT object is not a simple progress. All certain tags need to be resolved before changing properties of a block/entity. Note that only certain properties can be changed. For example, when using command to modify a block entity, its coordinates cannot be changed.

If a property needs a value of namespaced ID and gets a tag, the string will be converted to an ID.

If a property needs a value of JSON text and gets a tag, the string will be parsed into JSON text object.

If a property needs a numeric value of certain type and gets a numeric tag of wrong type, the number will get some rounding operation and converts to the required type.

If a property needs a numeric value and gets a non-numeric tag, the number will become 0.

If a property needs a string value and gets a non-string tag, the string will become an empty string.

If a property needs a list or array of certain type and gets a wrong-type tag, a empty list/array will be got.

If a property needs a compount tag and gets a non-compount tag, a empty compount tag will be got.

Testing NBT tags
When commands such as, are used to match data tags, or nbt argument in target selector tries to target entity, the game converts SNBT into programmatic NBT object and gets programmatic NBT object from block/entity/storage, then compares the two NBT objects.

They check only for the presence of the provided tags in the target entity/block/storage. This means that the entity/block/storage can have additional tags and still match. This is true even for lists: the order and number of elements in an list a list is not considered, and as long as every requested element is in the list, it matches even if there are additional elements. For example, an entity with data  can be targeted by   or even just   even though the former represents a totally different position and the latter is not a valid position at all. Note that  can't match it, because an empty list can only match empty list.

However, the order and number of elements in an byte/long/int array is acknowledged.

The requested data tags in the target entity/block/storage must match exactly for the provided tags to pass, including the data type (e.g., an int, will not match  , a double). Namespaces also can't omitted because in NBT object it is just a plain string that won't be resolved into a namespaced ID (e.g.  will not match a stone item entity, it must be  ). The same is true for string of JSON text, which must be exactly the same to match the provided tag (e.g.  will not match any entity, it must be   or  ).

NBT file
An NBT file is a zipped Compound tag, with the name and tag ID included. The file in the zip must contain the Compound tag that it is as the first bytes. Some of the files utilized by Minecraft may be uncompressed, but in most cases, the files follow Notch's original specification and are compressed with GZip.

TAG definition
A tag is an individual part of the data tree. The first byte in a tag is the tag type (ID), followed by a two byte big-endian unsigned integer for the length of the name, then the name as a string in UTF-8 format (Note TAG_End is not named and does not contain the extra 2 bytes; the name is assumed to be empty). Finally, depending on the type of the tag, the bytes that follow are part of that tag's payload. This table describes each of the 13 known tags in version 19133 of the NBT format: The List and Compound tags can be and often are recursively nested. It should also be noted that, in a list of lists, each of the sub-lists can list a different kind of tag.

Usage
Minecraft sometimes uses the NBT format inconsistently; in some instances, empty lists may be represented as a list of Byte tags rather than a list of the correct type, or as a list of End tags in newer versions of Minecraft, which can break some older NBT tools. Additionally, almost every root tag has an empty name string and encapsulates only one Compound tag with the actual data and a name. For instance: Additionally, although the original specification by Notch allows for spaces in tag names, and even the example uses spaces in the tag names, Minecraft has no known files where any tags have spaces in their names. There is also inconsistent use of letter case, mostly either camelCase or PascalCase, but sometimes even in all lowercase.
 * The root tag for most Minecraft NBT structures.
 * : The only tag contained within the root tag - it has a name and contains all the actual data.

Uses

 * level.dat is stored in compressed NBT format.
 * .dat files are stored in compressed NBT format.
 * idcounts.dat is stored in compressed NBT format.
 * villages.dat is stored in compressed NBT format.
 * raids.dat is stored in compressed NBT format.
 * map_<#>.dat files are stored in compressed NBT format.
 * servers.dat, which is used to store the list of saved multiplayer servers as uncompressed NBT.
 * hotbar.nbt, which is used to save hotbars as uncompressed NBT format.
 * Chunks are stored in compressed NBT format within Region files.
 * scoreboard.dat is stored in compressed NBT format.
 * Generated structures are stored in compressed NBT format.
 * Saved structures are stored in compressed NBT format.

Official software
Mojang has provided sample Java NBT classes for developers to use and reference as part of the source code for the MCRegion to Anvil file format converter. Since Java Edition 1.13, Minecraft includes a built-in converter between the SNBT format and compressed NBT format, which comes with both the client and official server.

The data generator from Minecraft is able to convert uncompressed Stringified NBT files with .snbt extension in an input folder to GZip compressed NBT format files with .nbt extension in an output folder, and vice versa.

The vanilla data generator can convert any GZip compressed NBT format to SNBT format. The file extension of a file can simply be changed, such as level.dat to level.nbt and put in the input folder, and the generator then decodes the GZip compressed NBT data.

History
The NBT file format was described by Notch in a brief specification.

The original known version was 19132 as introduced in Beta 1.3, and since then has been updated to 19133 with the Anvil file format, which adds the tag. The NBT format dates all the way back to Indev with tags 0 to 10 in use.