Referenz zum NBT-Format

Unterstützt Minecraft Bedrock Edition und Java Edition – einschließlich jedes bekannten oder seltenen Serverkerns: Vanilla, Paper, Spigot, Purpur, Folia, Fabric, Forge, NeoForge, Mohist, Sponge, Bedrock Dedicated Server, PocketMine-MP, Nukkit, PowerNukkitX, Cloudburst, Dragonfly, Endstone, LeviLamina und weitere. Vollständige Liste.

NBT (Named Binary Tag) ist das binäre Baumformat von Minecraft. Ein Tag besteht aus einem Byte für den Typ, einem längenpräfigierten Namen und Nutzdaten. Compounds werden verschachtelt, bis ein Byte TAG_End sie schließt. In Java und Bedrock werden 13 Tag-Typen und fünf Kodierungen verwendet. Diese Seite beschreibt sie; mit dem Editor oben kannst du jede Angabe an einer echten Datei prüfen.

13 Tag-TypenBig-EndianLittle-EndianVarintgzipzlibSNBT

eine beliebige NBT-Datei zum Prüfen hier ablegen

level.dat · .nbt · .mcstructure · .schem · .schematic · .dat · Chunk-Abbilder

Die 13 Tag-Typen

IDTagNutzdatenSNBT
0TAG_EndKeine – schließt ein Compound—
1TAG_Byte1 Byte, vorzeichenbehaftet −128…1271b
2TAG_Short2 Bytes, vorzeichenbehaftet1s
3TAG_Int4 Bytes, vorzeichenbehaftet1
4TAG_Long8 Bytes, vorzeichenbehaftet1L
5TAG_Float4 Bytes, IEEE 7541.0f
6TAG_Double8 Bytes, IEEE 7541.0d
7TAG_Byte_ArrayInt-Länge, danach entsprechend viele Bytes[B;1b,2b]
8TAG_StringShort-Länge ohne Vorzeichen, danach UTF-8-Bytes"text"
9TAG_ListByte für Elementtyp, Int-Länge, dann namenlose Nutzdaten[1,2]
10TAG_CompoundTyp + Name + Nutzdaten wiederholt bis TAG_End{a:1}
11TAG_Int_ArrayInt-Länge, danach entsprechend viele 4-Byte-Integer[I;1,2]
12TAG_Long_ArrayInt-Länge, danach entsprechend viele 8-Byte-Long-Werte[L;1L,2L]

Eine Datei enthält genau ein Root-TAG_Compound: ein Typ-Byte 0x0A, einen Namen und danach den Inhalt des Compounds. Benannte Tags treten nur in Compounds auf. Listenelemente enthalten ausschließlich Nutzdaten; deshalb ist eine Liste homogen.

Fünf verwendete Kodierungen

KodierungGanzzahlenString-LängeRoot-TagVerwendung
Java (klassisch)Big-Endian mit fester Breite2-Byte-Big-EndianBenanntJava-Welten, Strukturen und Schematics
Java-Netzwerk (ab 1.20.2)Big-Endian mit fester Breite2-Byte-Big-EndianNamenlosJava-Protokoll
BedrockLittle-Endian mit fester Breite2-Byte-Little-EndianBenanntBedrock-Welten, .mcstructure, LevelDB-Werte
Bedrock level.datLittle-Endian mit fester Breite2-Byte-Little-EndianBenannt, nach einem 8-Byte-HeaderMetadaten von Bedrock-Welten
Bedrock-NetzwerkZigzag-Varint für Int und LongVarint ohne VorzeichenBenanntBedrock-Protokoll

In der Varint-Kodierung bleiben TAG_Short, TAG_Float und TAG_Double Little-Endian-Werte fester Breite. Nur TAG_Int und TAG_Long werden zu Zigzag-Varints; Array- und Listenlängen folgen der Kodierung von TAG_Int. String-Längen sind Varints ohne Vorzeichen. Dadurch entfällt auch die Obergrenze von 65535 Bytes der Kodierungen mit fester Breite.

Strings: modifiziertes UTF-8 und UTF-8

Java serialisiert Strings mit DataOutputStream.writeUTF, also modifiziertem UTF-8. Ein NUL-Zeichen wird als C0 80 statt 00 geschrieben. Zeichen außerhalb der Basic Multilingual Plane werden als zwei Drei-Byte-Surrogathälften (CESU-8) statt als eine Vier-Byte-Sequenz gespeichert. Bedrock verwendet normales UTF-8. Ein Werkzeug, das für beide Formate dieselbe Kodierung annimmt, beschädigt beim Speichern Emojis und bestimmte CJK-Zeichen. Dieser Editor kodiert passend zum jeweiligen Format, sodass auch ein Weltname mit Emoji unverändert bleibt.

Komprimierung

NBT selbst ist nicht komprimiert; dies legt der Container fest. Java-Dateien verwenden meist gzip (Magic Bytes 1F 8B), Chunk-Nutzdaten in Regionsdateien zlib (Magic Bytes 78 01, 78 9C oder 78 DA). Bedrock speichert level.dat und Strukturdateien unkomprimiert. Die Erkennung erfolgt anhand der Magic Bytes, sodass derselbe Parser alle drei Varianten verarbeitet. Eine Datei mit falscher Komprimierung ist der häufigste Grund, warum eine manuell bearbeitete Welt nicht lädt.

Eine Minimaldatei, Byte für Byte

Die kanonische Datei hello_world.nbt enthält ein Root-Compound namens hello world mit einem String-Tag name und dem Wert Bananrama. In Javas Big-Endian-Kodierung:

0A                          TAG_Compound
00 0B 68 65 6C 6C 6F 20 77 6F 72 6C 64   name length 11, "hello world"
   08                       TAG_String
   00 04 6E 61 6D 65        name length 4, "name"
   00 09 42 61 6E 61 6E 72 61 6D 61      value length 9, "Bananrama"
00                          TAG_End

Dasselbe Dokument unterscheidet sich in Bedrocks Little-Endian-Kodierung nur durch die Byte-Reihenfolge der beiden Längenfelder: 0B 00 statt 00 0B. In Bedrock-Netzwerk-NBT werden die Längen zu einzelnen Varint-Bytes 0B und 04, ganz ohne Padding. Lege eine der drei Varianten im Editor oben ab; er zeigt die empfangene Kodierung an.

SNBT

SNBT ist als Text geschriebenes NBT und wird von Befehlen verarbeitet: /data merge entity @s {Invulnerable:1b}. Typ-Suffixe machen das Format verlustfrei: b für Byte, s für Short, L für Long, f für Float, d für Double und kein Suffix für Int. Typisierte Array-Literale werden als [B;…], [I;…] und [L;…] geschrieben. Der Editor exportiert jede geladene Datei als SNBT. So lassen sich zwei Versionen einer Welt mit einem normalen Text-Diff vergleichen.

Häufig gestellte Fragen

Gibt es eine offizielle NBT-Spezifikation?

Nein, keine formale Spezifikation von Mojang. Das Format wurde 2010 von Notch beschrieben und seitdem von der Community dokumentiert. Die Tag-IDs und Strukturen auf dieser Seite entsprechen den Daten, die das Spiel heute liest und schreibt.

Warum verwendet Bedrock Little-Endian?

Die Bedrock-Engine ist in C++ geschrieben und zielt auf Little-Endian-Hardware, weshalb Werte in nativer Reihenfolge gespeichert werden. Javas Serialisierung ist Big-Endian, weil der Java-Vertrag für DataOutput dieses Format vorgibt.

Was ist eine Zigzag-Varint-Kodierung?

Sie schreibt Ganzzahlen mit möglichst wenigen Bytes und hält zugleich negative Zahlen kurz. Das Vorzeichen wird in das niedrigste Bit gefaltet, sodass −1 als 1 und 1 als 2 kodiert wird. Das Bedrock-Protokoll verwendet sie für Integer und Long-Werte.

Kann eine TAG_List gemischte Typen enthalten?

Nein. Eine Liste legt genau einen Elementtyp fest, dem jeder Eintrag entsprechen muss. Gemischte Daten benötigen eine Liste aus Compounds.

Wie lang darf ein String maximal sein?

Bei Kodierungen mit fester Breite 65535 Bytes, weil das Längenfeld ein Short ohne Vorzeichen ist. Die Varint-Netzwerkkodierung besitzt keine praktische Grenze.

Verwandte Werkzeuge