NBT格式

来自Minecraft Wiki
跳转至: 导航搜索

Disambig gray.svg  本文章介绍的是NBT文件格式。关于使用NBT命令,请见“教程/NBT命令标签”。

NBT(二进制命名标签Named Binary Tags 格式为Minecraft中用于向文件中存储数据的一种存储格式。Notch在一份规范[1]中为此格式作了简略的介绍。NBT格式以树形结构并配以许多标签的形式存储数据。所有的标签都有一个独立的ID和名称。最早的已知NBT格式版本是Java版Beta 1.3中引入的19132;随着Anvil文件格式的引入,增加了一个整型数组变量,版本号也随之更新至19133。NBT标签的历史最早可以追溯到Indev,当时只有0到10这11个标签可用。

另一种玩家更熟悉的NBT是纯文本形式的,通常在命令里使用。这种格式常被称为SNBT字符串化的二进制命名标签Stringified NBT)。它与JSON格式不同,因此所有在NBT中使用的JSON(例如原始JSON文本)都必须放到字符串标签中。

标签的定义[编辑 | 编辑源代码]

每个标签在数据树中都是独立的一部分。标签的第一个字节为标签类型(ID),后两个字节是名称的长度(以两个字节的大端序无符号整数记录),最后是UTF-8格式字符串存储的标签名称(注:TAG_End没有名称,不包含第二部分的两个字节,故名称被定义为空)。虽然Minecraft自己不会保存有空格的标签名称,但是实际上名称允许包含空格。根据标签类型的不同,名称部分后的部分就是标签的“负载”。下表所示为在19133标签版本中二进制命名标签格式中所有13个已知的标签类型:

ID 图标 标签类型 负载 SNBT格式[仅Java版] 描述 存储容量
0 TAG_End - 用于标记复合标签的结尾。本标签无任何名称所以只有一个零字节。 N/A
1 TAG_Byte 1字节 / 8位,有符号 <number>b<number>B 有符号的整值数据类型,通常用于布尔表达式。 -27到27-1(-128到127)
2 TAG_Short 2字节 / 16位,有符号,大端序 <number>s<number>S 有符号的整值数据类型。 -215到215-1(-32,768到32,767)
3 TAG_Int 4字节 / 32位,有符号,大端序 <number> 有符号的整值数据类型。 -231到231-1(-2,147,483,648到2,147,483,647)
4 TAG_Long 8字节 / 64位,有符号,大端序 <number>l<number>L 有符号的整值数据类型。 -263到263-1(-9,223,372,036,854,775,808到9,223,372,036,854,775,807)
5 TAG_Float 4字节 / 32位,有符号,大端序,IEEE 754-2008标准,binary32 <number>f<number>F 有符号的浮点数据类型。 数据精度根据数值而定,见单精度浮点数
6 TAG_Double 8字节 / 64位,有符号,大端序,IEEE 754-2008标准,binary64 <decimal number><number>d<number>D 有符号的浮点数据类型。 数据精度根据数值而定,见双精度浮点数
7 TAG_Byte_Array TAG_Int的负载size(大小),然后是size个TAG_Byte的负载 [B;<byte>,<byte>,...] 存储TAG_Byte的负载的数组。 根据JVM的不同,数组成员最大数量可能在231 - 9和231 - 1(2,147,483,639和2,147,483,647)之间。
8 TAG_String 类似于TAG_Short但是无符号的负载length(长度)[2],然后是以UTF-8格式存储的字符串,长度为length个字节。 <a-zA-Z0-9 text>"<text>""需使用\"转义)或'<text>''需使用\'转义) UTF-8字符串。没有空结束符。 可解释为UTF-8字符串的最多65,535个字节(见变种UTF-8;ASCII字符均为1字节,大多数中文字符为3字节)
9 TAG_List TAG_Byte的负载tagId(列表标签ID),然后是TAG_Int的负载size(列表的大小),然后是sizetagId类型标签的负载。 [<value>,<value>,...] 一个标签列表,其成员没有标签ID和标签名称。 由于JVM的限制以及ArrayList的实现问题,列表成员最大数量为231 - 9(2,147,483,639)。另外,List和Compound标签的嵌套深度不能超过512。
10 TAG_Compound 一个完整构造好的标签,然后是一个TAG_End {<tag name>:<value>,<tag name>:<value>,...} 一系列完整的标签信息,包括ID、名称以及负载等。任意两个标签都不能有相同的名称。 不像列表,Compound标签内的标签数量没有硬性限制(不过仍受JVM分配的内存限制)。另外,List和Compound标签的嵌套深度不能超过512。
11 TAG_Int_Array TAG_Int的负载size(大小),然后是size个TAG_Int的负载 [I;<integer>,<integer>,...] 存储TAG_Int的负载的数组。 根据JVM的不同,数组成员最大数量可能在231 - 9和231 - 1(2,147,483,639和2,147,483,647)之间。
12 TAG_Long_Array TAG_Int的负载size(大小),然后是size个TAG_Long的负载 [L;<long>,<long>,...] 存储TAG_Long的负载的数组。 根据JVM的不同,数组成员最大数量可能在231 - 9和231 - 1(2,147,483,639和2,147,483,647)之间。

复合标签的列表常以嵌套递归的方式出现。另外还需注意,在一个包含List的List中,每个List可以包含不同类型的数据。

文件格式[编辑 | 编辑源代码]

NBT文件是经过压缩的复合标签,其中包括名称和标签ID。压缩文件必须以复合标签的字节开始。在Minecraft中使用的某些文件有可能未经压缩,但是大多数文件仍然遵循Notch最初的叙述以GZip压缩。

在Minecraft中的应用[编辑 | 编辑源代码]

NBT文件格式在Minecraft的应用十分不一致。在某些情况下,空列表可能表示为字节标签列表而不是正确标签类型的列表,或者在较新的Minecraft版本中表示为一系列的End标签(这会导致较旧的NBT工具出现错误)。另外,几乎所有的根标签的名称都是空字符串,并包含唯一一个复合标签存储实际的数据和名称,如下所示:

  • 在Minecraft NBT结构中最常看到的根标签。
    •  SomeName: 在根标签下的唯一一个标签——这一标签拥有名称和实际的数据。

另一点值得注意的是,尽管Notch最初所述允许在标签名称中出现空格,甚至是在例子中也出现了包含空格的标签名称,但是Minecraft目前并没有使用带有空格的标签名称。字母大小写的使用也不一致,多数时候是小驼峰(camelCase)和大驼峰(PascalCase),但有时甚至会使用全部小写字母的方式。

应用[编辑 | 编辑源代码]

  • level.dat以压缩后的NBT格式存储。
  • <player>.dat以压缩后的NBT格式存储。
  • idcounts.dat以压缩后的NBT格式存储。
  • map_<#>.dat以压缩后的NBT格式存储。
  • servers.dat以未压缩的NBT格式存储多人服务器列表。
  • 区块以压缩后的NBT格式存储区域文件。
  • scoreboard.dat以压缩后的NBT格式存储。
  • 生成结构以压缩后的NBT格式存储。
  • 保存的结构以压缩后的NBT格式存储。

官方软件[编辑 | 编辑源代码]

参见:教程/运行数据生成器

Mojang已经公布了Java中的NBT示例类文件,并将其作为Region至Anvil格式转换器源代码的一部分使用。[3]Java版1.13起,Minecraft内置了SNBT和压缩后的NBT文件的转换器,且通常与官方服务端一同发布。[4]

来自Minecraft的数据生成器能够将输入文件夹中扩展名为.snbt的未压缩字符串化NBT文件转换为输出文件夹中扩展名为.nbt的GZip压缩NBT格式文件,反之亦然。

原版数据生成器可以将任何GZip压缩的NBT格式转换为SNBT格式。只需将文件的扩展名(如level.dat)更改为level.nbt并将其放入输入文件夹,然后生成器将对GZip压缩的NBT数据进行解码。

历史[编辑 | 编辑源代码]

Java版
1.0.02011年9月28日Notch致力于“用物品实例来存储任意信息”。
1.12?加入了Long数组标签。
1.1318w01a为Minecraft Client和默认的多人游戏软件添加了数据生成器。
1.1419w08a"外,字符串标签现在可以写在'之间。[5]

外部链接[编辑 | 编辑源代码]

  • wiki.vg上的NBT条目
  • NBTExplorer,一个用于查看和编辑NBT文件的工具
  • webNBT,一个在线的查看和编辑NBT文件的工具

参考[编辑 | 编辑源代码]