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 | 二进制大小 | 描述 |
---|---|---|---|
字节 | 0x01 | 1字节(8位) | 单字节类型 |
Int16(短整型) | 0x02 | 2字节(16位) | 双字节类型 |
Int32(整型) | 0x03 | 4字节(32位) | 四字节类型 |
Int64(长整型) | 0x04 | 8字节(64位) | 八字节类型 |
浮点 | 0x05 | 4字节(32位) | 常规精度浮点数 |
双精度 | 0x06 | 8字节(64位) | 高精度浮点数 |
字符串 | 0x08 | 预定义长度 | UTF-8编码文本,前接2字节长度标识 |
列表 | 0x09 | 预定义长度 | 元素类型统一,前接4字节元素数量 |
复合标签 | 0x0A (10) | 未定义长度 | 通过遍历键值对读取,直到遇到结束标记 |
复合标签结束标记 | 0x00 | 0字节 | 仅作为复合标签结束标识 |
字节列表 | 0x07 | 预定义长度 | 基岩版不常用 |
整型列表 | 0x0B (11) | 预定义长度 | 基岩版不常用 |
长整型列表 | 0x0C (12) | 预定义长度 | 基岩版不常用 |
注意NBT没有布尔类型,需用字节类型的1/0表示true/false。
NBT标签读写方法
所有数值类型按字节长度读取,基岩版采用小端序编码,与Java版的大端序相反。
类型读取
始终读取1字节确定后续数据类型。
数值读取
根据类型确定字节数(如类型3读取4字节)。所有数值使用小端序处理。
字符串读取
先读取2字节长度标识(Int16),再按对应字节数读取UTF-8编码内容。
列表读取
- 读取列表元素类型(1字节)
- 读取元素数量(Int32,4字节)
- 按数量循环读取元素
注意:字节列表/整型列表/长整型列表的读取方式不同
复合标签读取
- 读取类型标记:
- 0x00:结束读取
- 其他类型:继续读取键值对
- 读取键名字符串
- 读取对应类型值
基岩版NBT文件解析
注意文件开头的基岩版NBT文件头,如.mcstructure
文件无此头而level.dat
有。根元素需作为匿名属性处理(即使键名为空)。
"":{
"format_version":1,
"size":[],//...
"structure":{},//...
"structure_world_origin":[]//..
}
WARNING
此示例表明即使根元素键名通常为空,仍需进行读取操作。
NBT写入规范
写入流程与读取逆向操作,需先掌握读取原理。
基岩版NBT文件头
包含两个4字节数值:
- 固定值8(0x08000000)
- 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
读取时反向转换即可还原数值。单字节类型不受影响。