Tham chiếu định dạng NBT

Hỗ trợ Minecraft Bedrock Edition và Java Edition — cùng mọi phần mềm máy chủ phổ biến hoặc ít gặp của cả hai: Vanilla, Paper, Spigot, Purpur, Folia, Fabric, Forge, NeoForge, Mohist, Sponge, Bedrock Dedicated Server, PocketMine-MP, Nukkit, PowerNukkitX, Cloudburst, Dragonfly, Endstone, LeviLamina và các phần mềm còn lại. Danh sách đầy đủ.

NBT (Named Binary Tag) là định dạng cây nhị phân của Minecraft: một thẻ gồm kiểu một byte, tên có tiền tố độ dài và payload; các compound lồng nhau cho đến khi byte TAG_End đóng chúng. Có 13 kiểu thẻ và năm kiểu mã hóa đang được dùng trong Java và Bedrock. Trang này mô tả tất cả, còn trình sửa phía trên cho phép kiểm tra bằng tệp thực.

13 kiểu thẻBig-endianLittle-endianVarintgzipzlibSNBT

Thả tệp NBT bất kỳ để kiểm tra vào đây

level.dat · .nbt · .mcstructure · .schem · .schematic · .dat · dữ liệu chunk trích xuất

13 kiểu thẻ

IdThẻPhần dữ liệuSNBT
0TAG_EndKhông có — đóng compound—
1TAG_Byte1 byte, có dấu −128…1271b
2TAG_Short2 byte, có dấu1s
3TAG_Int4 byte, có dấu1
4TAG_Long8 byte, có dấu1L
5TAG_Float4 byte, IEEE 7541.0f
6TAG_Double8 byte, IEEE 7541.0d
7TAG_Byte_Arrayđộ dài int, sau đó là số byte tương ứng[B;1b,2b]
8TAG_Stringđộ dài unsigned short, sau đó là byte UTF-8"text"
9TAG_Listbyte kiểu phần tử, độ dài int, sau đó là payload không có tên[1,2]
10TAG_Compoundlặp kiểu + tên + payload đến TAG_End{a:1}
11TAG_Int_Arrayđộ dài int, sau đó là số int 4 byte tương ứng[I;1,2]
12TAG_Long_Arrayđộ dài int, sau đó là số long 8 byte tương ứng[L;1L,2L]

Một tệp gồm một TAG_Compound gốc: một byte kiểu 0x0A, một tên rồi đến nội dung compound. Thẻ có tên chỉ xuất hiện trong compound — phần tử danh sách chỉ mang payload, vì vậy danh sách phải đồng nhất kiểu.

Năm kiểu mã hóa đang được dùng

Mã hóaSố nguyênĐộ dài chuỗiGốcNơi sử dụng
Java (cổ điển)Độ rộng cố định big-endianBig-endian 2 byteCó tênThế giới Java, cấu trúc, schematic
Mạng Java (1.20.2+)Độ rộng cố định big-endianBig-endian 2 byteKhông tênGiao thức Java
BedrockĐộ rộng cố định little-endianLittle-endian 2 byteCó tênThế giới Bedrock, .mcstructure, giá trị LevelDB
Bedrock level.datĐộ rộng cố định little-endianLittle-endian 2 byteCó tên, sau header 8 byteSiêu dữ liệu thế giới Bedrock
Mạng BedrockZigzag varint cho int và longVarint không dấuCó tênGiao thức Bedrock

Trong mã hóa varint, TAG_Short, TAG_Float và TAG_Double vẫn có độ rộng cố định little-endian; chỉ TAG_Int và TAG_Long trở thành zigzag varint, còn độ dài mảng và danh sách theo cách mã hóa của TAG_Int. Độ dài chuỗi là unsigned varint nên cũng bỏ giới hạn 65535 byte của các kiểu mã hóa cố định.

Chuỗi: UTF-8 sửa đổi và UTF-8

Java tuần tự hóa chuỗi bằng DataOutputStream.writeUTF, tức UTF-8 sửa đổi: ký tự NUL được ghi thành C0 80 thay vì 00, còn ký tự ngoài Basic Multilingual Plane được ghi thành hai nửa surrogate ba byte (CESU-8) thay vì một chuỗi bốn byte. Bedrock dùng UTF-8 tiêu chuẩn. Công cụ dùng một kiểu mã hóa cho cả hai sẽ làm hỏng emoji và một số văn bản CJK khi lưu — trình sửa này mã hóa theo định dạng nên tên thế giới có emoji vẫn nguyên vẹn sau khi ghi lại.

Kiểu nén

Bản thân NBT không được nén; vùng chứa quyết định việc này. Tệp Java thường dùng gzip (magic 1F 8B), payload chunk trong tệp region dùng zlib (magic 78 01, 78 9C hoặc 78 DA), còn Bedrock lưu level.dat và tệp cấu trúc không nén. Công cụ phát hiện bằng magic byte nên cùng một bộ phân tích xử lý cả ba — lưu sai kiểu nén là nguyên nhân phổ biến nhất khiến thế giới sửa thủ công không tải được.

Một tệp tối thiểu, theo từng byte

Tệp chuẩn hello_world.nbt: compound gốc tên hello world chứa một thẻ chuỗi name có giá trị Bananrama. Trong mã hóa big-endian của 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

Cùng tài liệu trong mã hóa little-endian của Bedrock chỉ khác thứ tự byte của hai trường độ dài: 0B 00 thay cho 00 0B. Trong NBT mạng Bedrock, độ dài trở thành byte varint đơn 0B và 04, hoàn toàn không có phần đệm. Thả một trong ba tệp vào trình sửa phía trên để biết công cụ đã nhận kiểu nào.

SNBT

SNBT là NBT được viết dưới dạng văn bản và là định dạng lệnh sử dụng: /data merge entity @s {Invulnerable:1b}. Hậu tố kiểu giúp giữ nguyên dữ liệu — b byte, s short, L long, f float, d double, không hậu tố cho int — còn literal mảng có kiểu được viết là [B;…], [I;…], [L;…]. Trình sửa xuất SNBT từ mọi tệp đã tải để có thể so sánh hai phiên bản thế giới bằng công cụ diff văn bản thông thường.

Câu hỏi thường gặp

Có đặc tả NBT chính thức không?

Mojang không có đặc tả chính thức. Notch mô tả định dạng vào năm 2010 và cộng đồng duy trì từ đó; id cùng bố cục thẻ trên trang này khớp với dữ liệu trò chơi hiện đọc và ghi.

Tại sao Bedrock dùng little-endian?

Engine Bedrock viết bằng C++ và nhắm đến phần cứng little-endian nên lưu giá trị theo thứ tự gốc. Java dùng big-endian vì hợp đồng Java DataOutput quy định như vậy.

Mã hóa zigzag varint là gì?

Đây là cách ghi số nguyên bằng ít byte nhất mà số âm vẫn ngắn: dấu được gấp vào bit thấp, nên −1 được mã hóa thành 1 và 1 thành 2. Giao thức Bedrock dùng nó cho int và long.

TAG_List có thể chứa nhiều kiểu khác nhau không?

Không. Danh sách khai báo một kiểu phần tử và mọi mục phải khớp kiểu đó. Dữ liệu hỗn hợp cần dùng danh sách compound.

Độ dài chuỗi tối đa là bao nhiêu?

65535 byte trong kiểu mã hóa cố định vì trường độ dài là unsigned short. Kiểu mã hóa mạng varint hầu như không có giới hạn thực tế.

Công cụ liên quan