Riferimento al formato NBT

Supporta Minecraft Bedrock Edition e Java Edition e ogni core server per entrambe, diffuso o meno: Vanilla, Paper, Spigot, Purpur, Folia, Fabric, Forge, NeoForge, Mohist, Sponge, Bedrock Dedicated Server, PocketMine-MP, Nukkit, PowerNukkitX, Cloudburst, Dragonfly, Endstone, LeviLamina e gli altri. Elenco completo.

NBT (Named Binary Tag) è il formato binario ad albero di Minecraft: un tag contiene un tipo di un byte, un nome preceduto dalla lunghezza e un payload; i compound possono essere annidati finché un byte TAG_End non li chiude. Tra Java e Bedrock sono in uso 13 tipi di tag e cinque codifiche. Questa pagina li documenta tutti e l'editor permette di verificarli su un file reale.

13 tipi di tagBig-endianLittle-endianVarintgzipzlibSNBT

Trascina qualsiasi file NBT da esaminare qui

level.dat · .nbt · .mcstructure · .schem · .schematic · .dat · dump di chunk

I 13 tipi di tag

IdTagPayloadSNBT
0TAG_EndNessuno — chiude un compound—
1TAG_Byte1 byte, con segno −128…1271b
2TAG_Short2 byte, con segno1s
3TAG_Int4 byte, con segno1
4TAG_Long8 byte, con segno1L
5TAG_Float4 byte, IEEE 7541.0f
6TAG_Double8 byte, IEEE 7541.0d
7TAG_Byte_Arraylunghezza int, poi il numero indicato di byte[B;1b,2b]
8TAG_Stringlunghezza short senza segno, poi byte UTF-8"text"
9TAG_Listbyte del tipo degli elementi, lunghezza int, poi payload senza nomi[1,2]
10TAG_Compoundtipo + nome + payload ripetuti fino a TAG_End{a:1}
11TAG_Int_Arraylunghezza int, poi il numero indicato di int da 4 byte[I;1,2]
12TAG_Long_Arraylunghezza int, poi il numero indicato di long da 8 byte[L;1L,2L]

Un file contiene un solo TAG_Compound radice: un byte di tipo 0x0A, un nome e poi il contenuto del compound. I tag con nome compaiono solo nei compound; gli elementi degli elenchi contengono soltanto i payload, perciò un elenco è omogeneo.

Cinque codifiche in uso

CodificaInteriLunghezza stringaRadiceUtilizzata da
Java (classica)Big-endian a larghezza fissaBig-endian a 2 byteCon nomeMondi Java, strutture, schematic
Rete Java (1.20.2+)Big-endian a larghezza fissaBig-endian a 2 byteSenza nomeProtocollo Java
BedrockLittle-endian a larghezza fissaLittle-endian a 2 byteCon nomeMondi Bedrock, .mcstructure, valori LevelDB
level.dat BedrockLittle-endian a larghezza fissaLittle-endian a 2 byteCon nome, dopo un'intestazione di 8 byteMetadati del mondo Bedrock
Rete BedrockVarint zigzag per int e longVarint senza segnoCon nomeProtocollo Bedrock

Nella codifica varint, TAG_Short, TAG_Float e TAG_Double restano little-endian a larghezza fissa; solo TAG_Int e TAG_Long diventano varint zigzag, mentre le lunghezze di array ed elenchi seguono la codifica di TAG_Int. Le lunghezze delle stringhe sono varint senza segno, eliminando anche il limite di 65535 byte imposto dalle codifiche a larghezza fissa.

Stringhe: UTF-8 modificato e UTF-8

Java serializza le stringhe con DataOutputStream.writeUTF, cioè in UTF-8 modificato: un carattere NUL viene scritto come C0 80 invece di 00, mentre i caratteri esterni al piano multilingue di base vengono scritti come due metà surrogate da tre byte (CESU-8), anziché come un'unica sequenza da quattro byte. Bedrock usa UTF-8 standard. Uno strumento che applica la stessa codifica a entrambi danneggia al salvataggio le emoji e alcuni testi CJK; questo editor usa la codifica del formato, quindi un nome del mondo con emoji resta intatto dopo apertura e salvataggio.

Compressione

NBT non è compresso di per sé: lo stabilisce il contenitore. I file Java usano in genere gzip (firma 1F 8B), i payload dei chunk nei file regione usano zlib (firma 78 01, 78 9C o 78 DA) e Bedrock archivia level.dat e i file struttura senza compressione. Il rilevamento usa i byte della firma, quindi lo stesso parser gestisce tutti e tre i casi. Salvare con la compressione errata è la causa più comune del mancato caricamento di un mondo modificato manualmente.

Un file minimo, byte per byte

Il file canonico hello_world.nbt: un compound radice chiamato hello world che contiene un tag stringa name con valore Bananrama. Nella codifica big-endian di 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

Lo stesso documento nella codifica little-endian di Bedrock differisce solo per l'ordine dei byte nei due campi di lunghezza: 0B 00 invece di 00 0B. Nell'NBT di rete Bedrock le lunghezze diventano singoli byte varint, 0B e 04, senza alcun riempimento. Trascina una qualsiasi delle tre versioni nell'editor per sapere quale codifica è stata rilevata.

SNBT

SNBT è la rappresentazione testuale di NBT, usata dai comandi: /data merge entity @s {Invulnerable:1b}. I suffissi dei tipi evitano perdite di informazione — b byte, s short, L long, f float, d double, nessuno per int — mentre gli array tipizzati si scrivono [B;…], [I;…], [L;…]. L'editor esporta in SNBT qualsiasi file caricato, permettendo di confrontare due versioni di un mondo con un normale diff testuale.

Domande frequenti

Esiste una specifica NBT ufficiale?

Non esiste una specifica formale di Mojang. Il formato fu documentato da Notch nel 2010 e da allora è mantenuto dalla comunità; gli id dei tag e la struttura descritti qui corrispondono a ciò che il gioco legge e scrive oggi.

Perché Bedrock usa il formato little-endian?

Il motore di Bedrock è scritto in C++ e usa hardware little-endian, quindi archivia i valori nell'ordine nativo. La serializzazione Java è big-endian perché lo specifica il contratto Java DataOutput.

Che cos'è la codifica varint zigzag?

È un modo per scrivere interi con il minor numero possibile di byte mantenendo brevi i valori negativi: il segno viene inserito nel bit meno significativo, quindi −1 è codificato come 1 e 1 come 2. Il protocollo Bedrock la usa per int e long.

Un TAG_List può contenere tipi diversi?

No. Un elenco dichiara un solo tipo di elemento e ogni voce deve corrispondervi. Per dati di tipi diversi serve un elenco di compound.

Qual è la lunghezza massima di una stringa?

65535 byte nelle codifiche a larghezza fissa, perché il campo della lunghezza è uno short senza segno. La codifica varint di rete non ha un limite pratico.

Strumenti correlati