ข้อมูลอ้างอิงรูปแบบ 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

วาง ไฟล์ NBT สำหรับตรวจสอบ ที่นี่

level.dat · .nbt · .mcstructure · .schem · .schematic · .dat · ข้อมูลชังก์ที่แยกออกมา

แท็กทั้ง 13 ชนิด

Idแท็กเพย์โหลดSNBT
0TAG_Endไม่มี — ใช้ปิด compound—
1TAG_Byte1 ไบต์ signed −128…1271b
2TAG_Short2 ไบต์ signed1s
3TAG_Int4 ไบต์ signed1
4TAG_Long8 ไบต์ signed1L
5TAG_Float4 ไบต์ IEEE 7541.0f
6TAG_Double8 ไบต์ IEEE 7541.0d
7TAG_Byte_Arrayความยาวแบบ int ตามด้วยไบต์ตามจำนวน[B;1b,2b]
8TAG_Stringความยาวแบบ unsigned short ตามด้วยไบต์ UTF-8"text"
9TAG_Listไบต์ชนิดองค์ประกอบ ความยาวแบบ int แล้วตามด้วยเพย์โหลดที่ไม่มีชื่อ[1,2]
10TAG_Compoundชนิด + ชื่อ + เพย์โหลด ทำซ้ำจนถึง TAG_End{a:1}
11TAG_Int_Arrayความยาวแบบ int ตามด้วย int ขนาด 4 ไบต์ตามจำนวน[I;1,2]
12TAG_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
BedrockLittle-endian ความกว้างคงที่little-endian 2 ไบต์มีชื่อโลก Bedrock, .mcstructure, ค่า LevelDB
Bedrock level.datLittle-endian ความกว้างคงที่little-endian 2 ไบต์มีชื่อ อยู่หลังส่วนหัว 8 ไบต์metadata ของโลก Bedrock
เครือข่าย Bedrockzigzag varint สำหรับ int และ longunsigned 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 ไม่มีขีดจำกัดที่มีผลในทางปฏิบัติ

เครื่องมือที่เกี่ยวข้อง