Skip to content

NBT深度解析

本页面镜像自
BedrockWiki

根据原始项目协议授权。本文经过AI翻译处理,如有内容遗漏,可以提交PR进行补充。

NBT(命名二进制标签)是一种二进制层级的编码格式,正如你熟悉的基于文本层级的JSON格式。因此我们可以用JSON格式举例说明,你可能也注意到Minecraft本身在命令中使用JSON来表示NBT(如Java版命令或简化的基岩版命令/give/replaceitem)。详见NBT命令。本文将深入解析NBT的运作原理、读取方式以及Minecraft BE如何应用它,其详细程度远超你在命令中接触的NBT表象。

NBT标签与数据类型

与JSON类似,NBT具备类型识别系统。例如JSON通过{}符号识别复合对象,通过"识别字符串。要理解NBT,需要掌握复合对象的起始标记和各类型的读取方式。

NBT基于二进制操作,最小单位为8位字节。各类型占用固定字节数,不存在半字节情况。注意类型名称可能有不同叫法,但二进制标识符(ID)始终由1字节表示。

名称二进制ID二进制大小描述
字节0x011字节(8位)单字节类型
Int16(短整型)0x022字节(16位)双字节类型
Int32(整型)0x034字节(32位)四字节类型
Int64(长整型)0x048字节(64位)八字节类型
浮点0x054字节(32位)常规精度浮点数
双精度0x068字节(64位)高精度浮点数
字符串0x08预定义长度UTF-8编码文本,前接2字节长度标识
列表0x09预定义长度元素类型统一,前接4字节元素数量
复合标签0x0A (10)未定义长度通过遍历键值对读取,直到遇到结束标记
复合标签结束标记0x000字节仅作为复合标签结束标识
字节列表0x07预定义长度基岩版不常用
整型列表0x0B (11)预定义长度基岩版不常用
长整型列表0x0C (12)预定义长度基岩版不常用

注意NBT没有布尔类型,需用字节类型的1/0表示true/false。

NBT标签读写方法

所有数值类型按字节长度读取,基岩版采用小端序编码,与Java版的大端序相反。

类型读取

始终读取1字节确定后续数据类型。

数值读取

根据类型确定字节数(如类型3读取4字节)。所有数值使用小端序处理。

字符串读取

先读取2字节长度标识(Int16),再按对应字节数读取UTF-8编码内容。

列表读取

  1. 读取列表元素类型(1字节)
  2. 读取元素数量(Int32,4字节)
  3. 按数量循环读取元素

注意:字节列表/整型列表/长整型列表的读取方式不同

复合标签读取

  1. 读取类型标记:
    • 0x00:结束读取
    • 其他类型:继续读取键值对
  2. 读取键名字符串
  3. 读取对应类型值

基岩版NBT文件解析

注意文件开头的基岩版NBT文件头,如.mcstructure文件无此头而level.dat有。根元素需作为匿名属性处理(即使键名为空)。

json
"":{
    "format_version":1,
    "size":[],//...
    "structure":{},//...
    "structure_world_origin":[]//..
}

WARNING

此示例表明即使根元素键名通常为空,仍需进行读取操作。

NBT写入规范

写入流程与读取逆向操作,需先掌握读取原理。

基岩版NBT文件头

包含两个4字节数值:

  1. 固定值8(0x08000000)
  2. NBT结构体字节数(不含头部的8字节)

示例:

  • 08 00 00 00 - bf 00 00 00
  • <固定值8> <NBT结构体大小>

小端序

数字按字节逆序存储的编码方式:

  • Int16 0x5a72 → 字节数组 [0x72, 0x5a]
  • Int64 0x11223344aabbccdd → 存储为 dd cc bb aa 44 33 22 11

读取时反向转换即可还原数值。单字节类型不受影响。