13種類のタグ型
| Id | タグ | ペイロード | SNBT |
| 0 | TAG_End | なし — Compoundを閉じる | — |
| 1 | TAG_Byte | 1バイト、符号付き −128…127 | 1b |
| 2 | TAG_Short | 2バイト、符号付き | 1s |
| 3 | TAG_Int | 4バイト、符号付き | 1 |
| 4 | TAG_Long | 8バイト、符号付き | 1L |
| 5 | TAG_Float | 4バイト、IEEE 754 | 1.0f |
| 6 | TAG_Double | 8バイト、IEEE 754 | 1.0d |
| 7 | TAG_Byte_Array | int長、その後に指定数のbyte | [B;1b,2b] |
| 8 | TAG_String | unsigned short長、その後にUTF-8バイト列 | "text" |
| 9 | TAG_List | 要素型byte、int長、その後に名前なしペイロード | [1,2] |
| 10 | TAG_Compound | TAG_End まで型 + 名前 + ペイロードを反復 | {a:1} |
| 11 | TAG_Int_Array | int長、その後に指定数の4バイトint | [I;1,2] |
| 12 | TAG_Long_Array | int長、その後に指定数の8バイトlong | [L;1L,2L] |
1ファイルは単一のルート TAG_Compound です。型byte 0x0A、名前、Compound内容の順です。名前付きタグが現れるのはCompound内だけで、List要素はペイロードだけを持つため、List内の型はすべて同じです。
実際に使われる5種類のエンコード
| エンコード | 整数 | 文字列長 | ルート | 用途 |
| Java(従来形式) | 固定長ビッグエンディアン | 2バイトビッグエンディアン | 名前付き | Javaワールド、構造物、スキーマティック |
| Java ネットワーク (1.20.2+) | 固定長ビッグエンディアン | 2バイトビッグエンディアン | 名前なし | Javaプロトコル |
| Bedrock | 固定長リトルエンディアン | 2バイトリトルエンディアン | 名前付き | Bedrockワールド、.mcstructure、LevelDB値 |
Bedrock level.dat | 固定長リトルエンディアン | 2バイトリトルエンディアン | 8バイトヘッダー後に名前付き | Bedrockワールドメタデータ |
| Bedrock ネットワーク | intとlongはZigzag varint | 符号なし可変長整数 | 名前付き | Bedrockプロトコル |
varint形式でも TAG_Short、TAG_Float、TAG_Double は固定長リトルエンディアンです。TAG_Int と TAG_Long だけがzigzag varintになり、配列とListの長さも TAG_Int と同じ方式です。文字列長はunsigned varintなので、固定長形式の65535バイト上限もありません。
文字列: 修正版UTF-8とUTF-8
Javaは DataOutputStream.writeUTF の修正版UTF-8を使います。NULは C0 80 として書かれ、通常の 00 は使いません。基本多言語面外の文字は1つの4バイト列ではなく2つの3バイトサロゲート(CESU-8)で書きます。Bedrockは標準UTF-8です。両方を同じエンコードとして扱うツールは、保存時に絵文字や一部のCJK文字を壊します。このエディターは形式ごとに正しくエンコードします。
圧縮
NBT自体は圧縮されず、コンテナーが圧縮方式を決めます。Javaファイルは通常gzip(マジック 1F 8B)、リージョン内のチャンクはzlib(78 01、78 9C、78 DA)、Bedrockの level.dat と構造物ファイルは非圧縮です。マジックバイトで判定するため同じパーサーで処理できます。誤った圧縮方式で保存すると、手動編集したワールドを読み込めない主な原因になります。
最小ファイルをバイト単位で確認
標準例 hello_world.nbt は、名前 hello world のルートCompoundに、文字列タグ name が1つあり、その値は Bananrama です。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
同じ文書のBedrockリトルエンディアン形式では、2つの長さフィールドのバイト順だけが異なり、0B 00 となり、Javaの 00 0B とは逆です。BedrockネットワークNBTでは長さが1バイトvarintの 0B と 04 になり、パディングはありません。3形式のいずれをドロップしても自動判定します。
SNBT
SNBTはNBTのテキスト表現で、コマンドが受け取る形式です: /data merge entity @s {Invulnerable:1b}。型を失わないよう、byteは b、shortは s、longは L、floatは f、doubleは d、intは接尾辞なしで表し、型付き配列は [B;…]、[I;…]、[L;…] と書きます。任意のファイルをSNBTへ出力すると、通常のテキストdiffでワールドの2バージョンを比較できます。
よくある質問
公式のNBT仕様はありますか?
Mojangによる正式仕様はありません。2010年にNotchが記録し、その後コミュニティが維持しています。このページのタグIDと配置は現在のゲームが読み書きする形式に対応します。
Bedrockがリトルエンディアンなのはなぜですか?
BedrockエンジンはC++でリトルエンディアンのハードウェアを対象とし、値をネイティブ順で保存します。JavaはDataOutputの仕様に従いビッグエンディアンです。
zigzag varintエンコードとは何ですか?
負数も短く保ちながら整数を少ないバイトで書く方式です。符号を最下位ビットへ折り込むため、−1は1、1は2としてエンコードされます。Bedrockプロトコルはintとlongに使います。
TAG_Listに複数の型を混在できますか?
できません。Listは1つの要素型を宣言し、すべての項目が一致する必要があります。混合データにはCompoundのListを使います。
文字列の最大長は?
固定長形式では長さフィールドがunsigned shortなので65535バイトです。varintネットワーク形式には実用上の制限がありません。