Référence du format NBT

Compatible avec Minecraft Bedrock Edition et Java Edition, ainsi qu'avec tous leurs logiciels serveur, courants ou non : Vanilla, Paper, Spigot, Purpur, Folia, Fabric, Forge, NeoForge, Mohist, Sponge, Bedrock Dedicated Server, PocketMine-MP, Nukkit, PowerNukkitX, Cloudburst, Dragonfly, Endstone, LeviLamina et les autres. Liste complète.

NBT (Named Binary Tag) est le format d'arborescence binaire de Minecraft : une balise se compose d'un type sur un octet, d'un nom précédé de sa longueur et d'une charge utile ; les composés s'imbriquent jusqu'à l'octet TAG_End qui les ferme. Treize types de balises et cinq encodages sont utilisés dans Java et Bedrock. Cette page les décrit tous ; l'éditeur ci-dessus permet de vérifier chaque point dans un fichier réel.

13 types de balisesGros-boutistePetit-boutisteVarintgzipzlibSNBT

Déposez un fichier NBT à examiner ici

level.dat · .nbt · .mcstructure · .schem · .schematic · .dat · extractions de chunks

Les 13 types de balises

IdBaliseCharge utileSNBT
0TAG_EndAucune — ferme un composé—
1TAG_Byte1 octet signé, −128…1271b
2TAG_Short2 octets signés1s
3TAG_Int4 octets signés1
4TAG_Long8 octets signés1L
5TAG_Float4 octets, IEEE 7541.0f
6TAG_Double8 octets, IEEE 7541.0d
7TAG_Byte_ArrayLongueur Int, suivie d'autant d'octets[B;1b,2b]
8TAG_StringLongueur Short non signée, puis octets UTF-8"text"
9TAG_ListOctet du type d'élément, longueur Int, puis charges utiles sans nom[1,2]
10TAG_CompoundType + nom + charge utile répétés jusqu'à TAG_End{a:1}
11TAG_Int_ArrayLongueur Int, puis autant d'entiers de 4 octets[I;1,2]
12TAG_Long_ArrayLongueur Int, puis autant de valeurs Long de 8 octets[L;1L,2L]

Un fichier possède une seule racine TAG_Compound : un octet de type 0x0A, un nom, puis le contenu du composé. Les balises nommées n'apparaissent qu'à l'intérieur des composés. Les éléments d'une liste ne portent que leur charge utile, ce qui impose un type homogène.

Les cinq encodages utilisés

EncodageEntiersLongueur de chaîneRacineUtilisé par
Java (classique)Largeur fixe gros-boutiste2 octets gros-boutistesNomméeMondes Java, structures, schémas
Réseau Java (1.20.2+)Largeur fixe gros-boutiste2 octets gros-boutistesSans nomProtocole Java
BedrockLargeur fixe petit-boutiste2 octets petit-boutistesNomméeMondes Bedrock, .mcstructure, valeurs LevelDB
level.dat BedrockLargeur fixe petit-boutiste2 octets petit-boutistesNommée, après un en-tête de 8 octetsMétadonnées des mondes Bedrock
Réseau BedrockVarint zigzag pour Int et LongVarint non signéNomméeProtocole Bedrock

Dans l'encodage varint, TAG_Short, TAG_Float et TAG_Double restent petit-boutistes à largeur fixe. Seuls TAG_Int et TAG_Long deviennent des varints zigzag, et les longueurs des tableaux et listes suivent l'encodage de TAG_Int. Les longueurs des chaînes sont des varints non signés, ce qui supprime aussi la limite de 65535 octets des encodages fixes.

Chaînes : UTF-8 modifié ou UTF-8

Java sérialise les chaînes avec DataOutputStream.writeUTF, qui utilise un UTF-8 modifié : un caractère NUL est écrit sous la forme C0 80 au lieu de 00, et les caractères hors du plan multilingue de base sont écrits comme deux demi-substituts de trois octets (CESU-8), au lieu d'une séquence de quatre octets. Bedrock utilise l'UTF-8 standard. Un outil qui suppose le même encodage pour les deux altère les emoji et certains textes CJK à l'enregistrement. Cet éditeur encode selon le format, afin qu'un nom de monde contenant un emoji résiste à un aller-retour.

Compression

Le NBT lui-même n'est pas compressé ; le conteneur détermine la compression. Les fichiers Java utilisent généralement gzip (signature 1F 8B), les charges utiles de chunks dans les fichiers de région utilisent zlib (signature 78 01, 78 9C ou 78 DA) et Bedrock stocke level.dat et les fichiers de structure sans compression. La détection repose sur les octets de signature : le même analyseur gère ainsi les trois cas. Un fichier enregistré avec la mauvaise compression est la cause la plus fréquente du refus d'un monde modifié manuellement.

Un fichier minimal, octet par octet

Le fichier canonique hello_world.nbt : un composé racine nommé hello world qui contient une balise String name de valeur Bananrama. Dans l'encodage gros-boutiste de Java :

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

Le même document en encodage petit-boutiste Bedrock ne diffère que par l'ordre des octets des deux champs de longueur : 0B 00 au lieu de 00 0B. Dans le NBT réseau Bedrock, les longueurs deviennent des octets varint uniques, 0B et 04, sans aucun remplissage. Déposez l'une des trois variantes dans l'éditeur ci-dessus pour savoir laquelle il a reçue.

SNBT

Le SNBT est du NBT écrit sous forme de texte, et c'est ce que consomment les commandes : /data merge entity @s {Invulnerable:1b}. Les suffixes de type évitent toute perte : b pour Byte, s pour Short, L pour Long, f pour Float, d pour Double et aucun pour Int. Les littéraux de tableaux typés s'écrivent [B;…], [I;…], [L;…]. L'éditeur exporte tout fichier chargé au format SNBT, ce qui permet de comparer deux versions d'un monde avec un outil de comparaison textuelle ordinaire.

Questions fréquentes

Existe-t-il une spécification NBT officielle ?

Il n'existe aucune spécification formelle de Mojang. Notch a documenté le format en 2010 et la communauté le maintient depuis. Les identifiants et la structure des balises présentés ici correspondent à ce que le jeu lit et écrit actuellement.

Pourquoi Bedrock utilise-t-il le petit-boutiste ?

Le moteur de Bedrock est écrit en C++ et cible du matériel petit-boutiste ; il stocke donc les valeurs dans l'ordre natif. La sérialisation Java est gros-boutiste conformément au contrat Java DataOutput.

Qu'est-ce que l'encodage varint zigzag ?

Il permet d'écrire les entiers avec le moins d'octets possible tout en gardant les valeurs négatives courtes : le signe est replié dans le bit de poids faible, donc −1 s'encode en 1 et 1 en 2. Le protocole Bedrock l'utilise pour les valeurs Int et Long.

Une TAG_List peut-elle contenir plusieurs types ?

Non. Une liste déclare un seul type d'élément et chaque entrée doit lui correspondre. Des données mixtes exigent une liste de composés.

Quelle est la longueur maximale d'une chaîne ?

65535 octets dans les encodages fixes, car le champ de longueur est un Short non signé. L'encodage réseau varint n'impose aucune limite pratique.

Outils associés