ข้อมูลอ้างอิงรูปแบบ NBT
รองรับ Minecraft Bedrock Edition และ Java Edition — รวมถึงซอฟต์แวร์เซิร์ฟเวอร์ทุกแบบของทั้งสองรุ่น ไม่ว่าจะเป็นที่นิยมหรือเฉพาะทาง: Vanilla, Paper, Spigot, Purpur, Folia, Fabric, Forge, NeoForge, Mohist, Sponge, Bedrock Dedicated Server, PocketMine-MP, Nukkit, PowerNukkitX, Cloudburst, Dragonfly, Endstone, LeviLamina และอื่น ๆ ดูรายการทั้งหมด.
NBT (Named Binary Tag) เป็นรูปแบบโครงสร้างต้นไม้แบบไบนารีของ Minecraft แท็กประกอบด้วยชนิดหนึ่งไบต์ ชื่อที่มีความยาวนำหน้า และเพย์โหลด โดย compound ซ้อนกันจนพบ TAG_End หนึ่งไบต์เพื่อปิดโครงสร้าง มีแท็ก 13 ชนิดและการเข้ารหัสห้าแบบที่ใช้ใน Java และ Bedrock หน้านี้อธิบายทั้งหมด และโปรแกรมด้านบนใช้ตรวจสอบกับไฟล์จริงได้
แท็ก 13 ชนิดBig-endianLittle-endianVarintgzipzlibSNBT
แท็กทั้ง 13 ชนิด
| Id | แท็ก | เพย์โหลด | SNBT |
| 0 | TAG_End | ไม่มี — ใช้ปิด compound | — |
| 1 | TAG_Byte | 1 ไบต์ signed −128…127 | 1b |
| 2 | TAG_Short | 2 ไบต์ signed | 1s |
| 3 | TAG_Int | 4 ไบต์ signed | 1 |
| 4 | TAG_Long | 8 ไบต์ signed | 1L |
| 5 | TAG_Float | 4 ไบต์ IEEE 754 | 1.0f |
| 6 | TAG_Double | 8 ไบต์ IEEE 754 | 1.0d |
| 7 | TAG_Byte_Array | ความยาวแบบ int ตามด้วยไบต์ตามจำนวน | [B;1b,2b] |
| 8 | TAG_String | ความยาวแบบ unsigned short ตามด้วยไบต์ UTF-8 | "text" |
| 9 | TAG_List | ไบต์ชนิดองค์ประกอบ ความยาวแบบ int แล้วตามด้วยเพย์โหลดที่ไม่มีชื่อ | [1,2] |
| 10 | TAG_Compound | ชนิด + ชื่อ + เพย์โหลด ทำซ้ำจนถึง TAG_End | {a:1} |
| 11 | TAG_Int_Array | ความยาวแบบ int ตามด้วย int ขนาด 4 ไบต์ตามจำนวน | [I;1,2] |
| 12 | TAG_Long_Array | ความยาวแบบ int ตามด้วย long ขนาด 8 ไบต์ตามจำนวน | [L;1L,2L] |
ไฟล์หนึ่งไฟล์มีรากเดียว TAG_Compound: ไบต์ชนิดหนึ่งไบต์ 0x0A, ชื่อ และเนื้อหาของ compound แท็กที่มีชื่อจะอยู่ภายใน compound เท่านั้น ส่วนองค์ประกอบ list มีเฉพาะเพย์โหลด จึงต้องเป็นชนิดเดียวกันทั้งรายการ
การเข้ารหัสห้าแบบที่ใช้งานจริง
| การเข้ารหัส | จำนวนเต็ม | ความยาวสตริง | ราก | ใช้โดย |
| Java (แบบดั้งเดิม) | Big-endian ความกว้างคงที่ | big-endian 2 ไบต์ | มีชื่อ | โลก โครงสร้าง และ schematic ของ Java |
| เครือข่าย Java (1.20.2+) | Big-endian ความกว้างคงที่ | big-endian 2 ไบต์ | ไม่มีชื่อ | โปรโตคอล Java |
| Bedrock | Little-endian ความกว้างคงที่ | little-endian 2 ไบต์ | มีชื่อ | โลก Bedrock, .mcstructure, ค่า LevelDB |
Bedrock level.dat | Little-endian ความกว้างคงที่ | little-endian 2 ไบต์ | มีชื่อ อยู่หลังส่วนหัว 8 ไบต์ | metadata ของโลก Bedrock |
| เครือข่าย Bedrock | zigzag varint สำหรับ int และ long | unsigned varint | มีชื่อ | โปรโตคอล Bedrock |
ในการเข้ารหัส varint TAG_Short, TAG_Float และ TAG_Double ยังเป็น little-endian ความกว้างคงที่ มีเพียง TAG_Int และ TAG_Long ที่เปลี่ยนเป็น zigzag varint ส่วนความยาว array และ list ใช้รูปแบบเดียวกับ TAG_Int ความยาวสตริงใช้ unsigned varint จึงไม่มีเพดาน 65535 ไบต์ของการเข้ารหัสแบบความกว้างคงที่
สตริง: modified UTF-8 เทียบกับ UTF-8
Java แปลงสตริงเป็นไบต์ด้วย DataOutputStream.writeUTF ซึ่งเป็น แบบดัดแปลง UTF-8 โดยเขียนอักขระ NUL เป็น C0 80 แทน 00, และอักขระนอก Basic Multilingual Plane จะเขียนเป็น surrogate สองส่วน ส่วนละสามไบต์ (CESU-8) แทนลำดับสี่ไบต์หนึ่งชุด Bedrock ใช้ UTF-8 มาตรฐาน เครื่องมือที่ใช้การเข้ารหัสเดียวกันทั้งสองแบบจะทำให้อีโมจิและข้อความ CJK บางส่วนเสียเมื่อบันทึก โปรแกรมนี้เข้ารหัสตามรูปแบบ ชื่อโลกที่มีอีโมจิจึงคงเดิมเมื่อบันทึกกลับ
การบีบอัด
NBT เองไม่บีบอัด แต่คอนเทนเนอร์เป็นตัวกำหนด ไฟล์ Java มักใช้ gzip (magic 1F 8B) เพย์โหลดชังก์ในไฟล์ Region ใช้ zlib (magic 78 01, 78 9C หรือ 78 DA) และ Bedrock เก็บ level.dat และไฟล์โครงสร้างโดยไม่บีบอัด ระบบตรวจหาจาก magic byte ตัวแยกข้อมูลเดียวจึงรองรับทั้งสามแบบ และการบันทึกด้วยการบีบอัดผิดเป็นสาเหตุที่พบบ่อยที่สุดที่ทำให้โลกซึ่งแก้ด้วยมือโหลดไม่ได้
ตัวอย่างไฟล์ขั้นต่ำทีละไบต์
ตัวอย่างมาตรฐาน hello_world.nbt: root compound ชื่อ hello world ที่มีแท็กสตริงหนึ่งแท็ก name และค่า Bananrama. เมื่อเข้ารหัสแบบ big-endian ของ 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
เอกสารเดียวกันในรูปแบบ little-endian ของ Bedrock ต่างกันเฉพาะลำดับไบต์ของฟิลด์ความยาวสองจุด 0B 00 แทน 00 0B. ใน NBT เครือข่ายของ Bedrock ความยาวจะเป็นไบต์ varint เดี่ยว 0B และ 04, โดยไม่มี padding วางไฟล์แบบใดในสามแบบลงในโปรแกรมด้านบน แล้วระบบจะแจ้งรูปแบบที่ได้รับ
SNBT
SNBT คือ NBT ในรูปข้อความและเป็นรูปแบบที่คำสั่งใช้ /data merge entity @s {Invulnerable:1b}. suffix ของชนิดทำให้เก็บข้อมูลได้ครบ — b byte, s short, L long, f float, d double ส่วน int ไม่มี suffix และ typed array literal เขียนเป็น [B;…], [I;…], [L;…]. โปรแกรมส่งออก SNBT จากไฟล์ที่โหลดได้ทุกแบบ ทำให้เปรียบเทียบโลกสองเวอร์ชันด้วย text diff ปกติได้
คำถามที่พบบ่อย
มีข้อกำหนด NBT อย่างเป็นทางการหรือไม่?
Mojang ไม่มีข้อกำหนดอย่างเป็นทางการ Notch บันทึกรูปแบบไว้ในปี 2010 และชุมชนดูแลต่อมา id แท็กและโครงสร้างในหน้านี้ตรงกับข้อมูลที่เกมอ่านและเขียนในปัจจุบัน
ทำไม Bedrock จึงใช้ little-endian?
เอนจิน Bedrock เขียนด้วย C++ และทำงานบนฮาร์ดแวร์ little-endian จึงเก็บค่าตามลำดับดั้งเดิม ส่วนการแปลงข้อมูลของ Java เป็น big-endian ตามข้อกำหนด Java DataOutput
การเข้ารหัส zigzag varint คืออะไร?
วิธีเขียนจำนวนเต็มโดยใช้ไบต์น้อยที่สุดและยังเก็บค่าลบให้สั้น โดยพับเครื่องหมายไว้ในบิตต่ำสุด ทำให้ −1 เข้ารหัสเป็น 1 และ 1 เข้ารหัสเป็น 2 โปรโตคอล Bedrock ใช้กับ int และ long
TAG_List เก็บข้อมูลหลายชนิดรวมกันได้หรือไม่?
ไม่ได้ list ระบุชนิดองค์ประกอบเดียวและทุกรายการต้องตรงกัน ข้อมูลหลายชนิดต้องใช้ list ของ compound
สตริงมีความยาวสูงสุดเท่าใด?
65535 ไบต์ในการเข้ารหัสแบบความกว้างคงที่ เพราะฟิลด์ความยาวเป็น unsigned short ส่วนการเข้ารหัสเครือข่ายแบบ varint ไม่มีขีดจำกัดที่มีผลในทางปฏิบัติ