Package net.minecraft.nbt


package net.minecraft.nbt
The Named Binary Tag (NBT) data format.

NBT is a simple data structure format used in Minecraft's in-game data serialization. Data stored on disks, modified by commands, and transported via packets are usually in this format. In most cases, NBT is not the runtime form of data; data are instead written to Java class fields using Java types, and during serialization (as part of saving or network transportation) or modification by commands, the code will write the fields to NBT data. NBT data is also known as "NBT element".

Types

There are 13 NBT element types, as shown below. Each NBT type has its own class, and a NbtType instance used during deserialization in the TYPE static field. They also have the "numeric ID" used during serialization and at NbtCompound.getList(String, int) method. The ID of the element's type can be obtained via the NbtElement.getType() method. There is also a special ID, NbtElement.NUMBER_TYPE, which indicates the read value can be any of the six numeric types; this cannot be used as the list's held type.

NBT types
Class Numeric ID Immutable? Default Description
NbtEnd
0x0 Yes (none) Internal type used during serialization, should not be used directly
NbtByte 0x1 Yes 0 Corresponds to byte
NbtShort 0x2 Yes 0 Corresponds to short
NbtInt 0x3 Yes 0 Corresponds to int
NbtLong 0x4 Yes 0L Corresponds to long
NbtFloat 0x5 Yes 0.0f Corresponds to float
NbtDouble 0x6 Yes 0.0 Corresponds to double
NbtByteArray 0x7 No Empty array Corresponds to byte[]
NbtString 0x8 Yes "" Corresponds to String
NbtList 0x9 No Empty list List of NBT elements with the same type
NbtCompound 0xa No Empty compound Hash map-like object with string keys that can store any NBT elements
NbtIntArray
0xb No Empty array Corresponds to int[]
NbtLongArray 0xc No Empty array Corresponds to long[]

NbtEnd

NbtEnd is a special sentinel used to indicate the end of lists and compounds. This is also used as the type of empty lists.

Numeric types

NBT offers 6 numeric types (4 for integers and 2 for decimals), all corresponding to Java equivalents. There is no unsigned type or char equivalent. These inherit AbstractNbtNumber. To create an instance of these, use the of static method, and to obtain the value as the Java primitive value, use the typeValue() method.


   NbtInt nbt = NbtInt.of(100);
   int value = nbt.intValue();
 

One thing to note here is that NBT lacks the boolean type; instead NbtByte is used when boolean values are needed. See also NbtByte.of(boolean) method.

NBT typed arrays

There are 3 typed arrays in NBT: NbtByteArray, NbtIntArray, and NbtLongArray. There are no array types for shorts, floats or doubles. While they are arrays internally, they also support adding items at runtime. Like Java arrays, out of bounds access is forbidden and will throw ArrayIndexOutOfBoundsException.

NbtList

NbtList is a list of a specific type of NBT elements. Empty lists always have the type set as NbtEnd. NbtList.add(int, net.minecraft.nbt.NbtElement) throws when the type is incompatible, while NbtList.addElement(int, net.minecraft.nbt.NbtElement) does nothing and returns false in that case. There are type-specific getters which can be used to get the value. They return the default value when type mismatch occurs or when the index is out of bounds. Note that they do not cast the value at all.


   NbtList list = new NbtList();
   list.addElement(0, NbtFloat.of(0.5f));
   float firstItem = list.getFloat(0); // 0.5f
   float secondItem = list.getFloat(1); // 0.0f (default value)
   double firstItemDouble = list.getDouble(0); // 0.0 (no casting)
   list.addElement(1, NbtDouble.of(1.0)); // returns false, does nothing
   list.add(NbtDouble.of(2.0)); // throws UnsupportedOperationException
 

NbtCompound

NbtCompound is a hash map-like key-value storage object. It also acts as the root object for serialized NBTs. The keys are always strings, while the values can be of any type, and multiple value types can be mixed in a single compound. The order of items is not guaranteed. There are generic NbtCompound.put(java.lang.String, net.minecraft.nbt.NbtElement) and NbtCompound.get(java.lang.String) methods, and there also exist type-specific getters and putters. Like the list getters mentioned above, they return the default value when the key is missing or type mismatch occurs. However, unlike lists, they attempt to cast numeric values.


   NbtCompound compound = new NbtCompound();
   compound.put("Awesomeness", NbtInt.of(90));

   // Don't do this! This will crash if the type is incompatible,
   // even if they can be casted!
   NbtInt awesomenessNbt = (NbtInt)compound.get("Awesomeness");

   compound.putLong("Awesomeness", 100L);
   int awesomeness = compound.getInt("Awesomeness"); // 100 (after casting)
   int evilness = compound.getInt("Evilness"); // 0 (default value)

   // Shortcuts for getting and putting a boolean value
   // (internally represented as a byte)
   compound.putBoolean("Awesome", true);
   boolean awesome = compound.getBoolean("Awesome");
   compound.put("awesome", NbtDouble.of(1.0)); // key is case-sensitive
 

Using NBT

As noted before, NBT is a serialized format, not runtime format. Unrecognized custom data stored inside NBT will be lost once the game loads it and saves. Therefore, modifying NBT is usually not the solution for attaching custom data to objects like entities. For this purpose it is recommended to use third-party APIs or use Mixin to add a field to the class.

With that said, here is how to use NBT in the vanilla code:

Methods named readNbt will read the values from the element, modifying the current instance. Static methods named fromNbt will create a new instance of the class with values from the element. Methods named writeNbt will add the NBT data to the passed element. Methods named toNbt will create and return a new element with the data.

There are several helper classes for NBTs:

  • NbtHelper contains methods for reading and writing game profiles, block states, UUIDs, and block positions. It also contains a method for comparing elements.
  • NbtIo contains methods for reading and writing NBT compounds on a file.
  • NbtOps is the class defining interactions with the DataFixerUpper library. The library abstracts operations between data formats (such as JSON or NBT) using "ops". Use NbtOps.INSTANCE to decode the NBT data using DataFixerUpper.
  • StringNbtReader reads the stringified NBT (SNBT) and converts to NBT.
  • NbtElementVisitor and its subclasses allow converting NBT elements to string or Text.
  • NbtScanner scans the NBT data without reading the whole data at once, allowing efficient decoding when only parts of the data are needed.

NBT compounds can also be transported using PacketByteBuf.writeNbt(net.minecraft.nbt.NbtCompound) and PacketByteBuf.readNbt().