NBT

前言(?)

NBT(二进制命名标签)格式为Minecraft中用于向文件中存储数据的一种存储格式。
NBT格式以树形结构并配以许多标签的形式存储数据。所有的标签都有一个独立的ID和名称。
...

等等! 我们不是在说命令么?怎么跑了去编程了?教练我不要学这个!

其实NBT有两个意思:NBT文件格式以及命令中的NBT格式,两者表达方式是不同的,然而内里的数据是相同的。
本文只会介绍命令中的NBT的表达方式,对NBT文件格式(二进制的)有兴趣的朋友可以参考 http://wiki.vg/NBT

同时,部分标签的修改不能通过游戏内命令达成,需要使用外置修改器修改存档中的部分NBT文件,在此推荐 NBTExplorer 这个外置修改器

下载地址:
http://www.mcbbs.net/thread-306895-1-1.html

NBT文件储存了很多重要资料,如存档资料、实体资料、方块资料等。
通过命令中的NBT,我们能够修改并检查实体(玩家除外)、物品、方块实体的属性,也能检查玩家的部分属性。
看完本章,你不会知道NBT的完整格式,然而你会知道最好的写法,最不容易出现错误的写法。

NBT简介

NBT和JSON类似,是由标签(Tag)组成的。而每个标签都有它们的数值。

标签有不同的种类,我们可以大致分为四大类(前三类可以当作基本数值类(simple)):

  • 数值类(详细分类会包括整数和浮点数,里面又可以根据不同的大小、精度再分类)
  • 字串类(没错,字串是自成一类的)
  • 数组类(虽然数组也能包括多个数值,然而其特性和List有明显不同,之后将会详细解释,但并不常用)
  • 集合类(包括compound及list,将会在下方详述)
    集合类的数值为一个集合,也就是说能够储存另外的一些标签在里面
    故此,NBT的结构是一个结构

Tag_End算不算一个Tag....我觉得那比较算是Tag_Compound的格式之一(二进制的时候),
而且那只会在NBT文件里使用,因此就不需要理会了。

接下来我们会看看NBT的大致结构,基本数值类的标签将会在之后的章节逐一说明。

集合

NBT前三者只是简单的数值类,不能储存更多标签,因此对整体结构没啥影响。
这里就统一把它们的类型写作simple,方便阅读。

集合类的NBT有两种,分别为Compound以及List,它们在资料储存方式和实际应用也有很大分别。
我们首先来看看Compound

Compound

Compound,其实和JSON的物件非常类似。
Compound里的每个标签都有一个名字(key),里面的标签类型不必一样。
Compound里的标签名字非常重要,因为游戏依靠标签名字查找资料。
故此,一个Compound内的标签不能重名

技术说明到此为止,我们来看看一个例子。

说例子前先说说这章例子的格式
标签: 种类 名称: 数值
种类有: simple, compound, list
格式为"某"的就是字串,和数值不同
compound和list的子标签会缩排(对齐缩进),以与其他标签分开

compound a:
    simple aa: 123
    simple ab: 456
    simple ac: "23333"

    compound ad:
        simple aa: 123
        simple ab: 456
        simple ac: "23333"

可以看到,a这个compound里同时有数字、字串及另一个compound。

然而在ad里,出现了和compound a里重名的标签!这不是违反了我们上面说的“一个Compound内的标签不能重名”?
其实这不算重名,因为在a里叫aa的只有1个,另一个在a的ad里,分属于不同的compound


那么我们来看看下一个例子

compound a:
    simple aa: 123456
    simple aa: 1234

这个例子就有错误了!
a里有两个aa,所以我们指定a的aa是要数值为123456的呢,还是1234那个?没人知道。

所以重复名称是不允许的。

此外,Compound是不注重次序的(同一Compound内的子标签是没有前后次序之分的)
对Compound来说最重要的是结构,也就是谁是谁的子标签
故此,在命令里不需要理会Compound的子标签次序,只需要理会结构就好。

格式

现在来让我们看看命令里是怎么写Compound的。

Compound的数值格式为:

{ 子标签 }

子标签需要名字,并且以,分隔。

而子标签需要名字,名字是这么写的:

名字:数值
或
"名字":数值

当名字包含不是a-z A-Z 0-9 _ .的字符时就需要用""了(出现空格的话也需要),如果出现\"字符则需要转义,详见之后的字串章节(正常人也不会在名字里加入这奇奇怪怪的东西吧233333)。

注:数值前后及名字前后(如果名字需要"""名字")的空格都会被忽略


例子(把例子1的格式转为命令里的NBT写法):

a:{aa:123,ab:456,ac:"23333",ad:{aa:123,ab:456,ac:"23333"}}

假设把第一个ab的名称改为a b,我们就得这么写了:

a:{aa:123,"a b":456,ac:"23333",ad:{aa:123,ab:456,ac:"23333"}}

记得开了{就得关掉}
修改NBT时只会修改指定了的NBT,不会清空整个Compound。
检测亦如是,只会检测指定NBT。比如检查{}只能检查此compound是否存在,不能检查是否一个空的compound。
更多的例子将会在之后的NBT命令实战一章介绍。

List

List就是一个列表,和Compound类似,也能储存多个tag,然而也有很大的分别。

  1. 一旦被命令修改,之前的List就会被清空。(特例会在实战部分讲解)
  2. 子标签没有名字,并且重视次序
  3. 每个List只能储存一种标签。比如储存List,储存字串,储存Compound等等。(但里面的List可以储存不同种类的子标签,只要确保同一个List内的标签全部类型一致即可)

一般提及List的时候,我们也会提及这List储存的类型,说法是List of <类型>(中文就是<类型>的列表

例子:

compound a:
    <List of simple> b:
        simple : 123
        simple : 456
        simple : 123

错误例子:

compound a:
    <List of simple> b:
        simple a: 123
        compound b:
            simple a: 123

错误的原因有两个:

  • List里的子标签应该是没有名字的。
  • List里的子标签应该是同一类型的。(甚至即使它们都是基本类型也不行,需要类型完全一样,之后将会介绍基本类型的分类)

格式

现在来让我们看看命令里是怎么写List的。

数值格式:

[ 子标签 ]

子标签没有名字,之间以,分隔。

例子1

a:{b:[123,456,123]}

例子2

{a:[{a:123},{a:456},{a:789}]}

例子2外面那个无名的Compound在实际命令非常常见。
检测的时候不会循序检测,只会看看目标列表里有没有这几个标签,不论次序。
简单来说就是你无法控制次序

设置为[]会直接清空列表。
直接检查[]会检查该列表是否一个空的列表。

之后的NBT命令实战一章将会有更多例子。


下一个章节将会仔细将基本数值里面的数值类型。
数值类型在MC里大量使用,NBT里最多的也是数值类型。
数值类型有一些比较方便的写法,然而某些情况会失效,因此我们不会介绍那写法,而是介绍标准写法。如果需要学习便捷写法的话请自行寻找相关教程。

results matching ""

    No results matching ""