第一百三十五章 真正深入了解NBT-1
在之前的第一百章——“深入地了解一下NBT”中,其中的80%都有水的成分。所以今天,我们就真正深入地了解一下NBT。
——第一节:NBT的格式
在之前,我们已经讲了很多NBT。这些NBT内容都不一样,但它们都有一个共同点:
最外层都是使用“{}”包裹起来的。
没错,NBT和JSON的格式并不一样。JSON最外层使用“[]”和“{}”都可以,NBT却只能使用“{}”。
这是NBT的基本格式。
而NBT里面,是由N个标签组成的。每个标签之间必须用英文的半角逗号来区分。标签里包含标签名称和值,它两使用英文的半角冒号分隔:
{标签:值,标签:值,标签:值}
(注:阅读平台会自动把半角改成全角,所以这里的符号是全角符号,实际上在写的时候是全是半角)
而这个标签中的标签名称,它不是什么都能写的,而是有一个规则:
1.标签名称中只能出现字母a-z和A-Z、数字0~9、下划线“_”。
2.标签名称中不允许出现空格(空格都以下划线替代)、中文以及特殊符号
3.标签名称对大小写敏感。
当违反了上述规则的时候,就会报错(或者是被游戏理解为另外一种意思)。
而标签的值,大家应该都知道标签的值类型是同标签中的标签名称或由另一个标签决定的,所以不同的标签名称,填的值格式都是不同的。
但实际上,值并不是直接写上内容就行了。当标签名称决定值的类型为特定类型时,值实际上还会有一个可填可不填的格式,我们待会就会讲到。
——第二节:NBT数据类型
在之前,我们已经提到了很多NBT数据类型的名词:
单精度浮点型
双精度浮点型
整形(整数)
复合标签({})
列表([])
整型数组([I;1,2,3,4])
字符串
可以发现,NBT的数据类型和JSON的并不一样,而且类型还比JSON多。
其实并不是类型多,而是NBT的类型分得比较细,实际上你搞个分类,就和JSON差不多了。
好的,现在请你拿出你的笔记本,并坐好,做一下心理准备,我们的车马上就要开动了!
3
2
1
GO!
NBT一共有14种数据类型,分别是:
[字符]
字符串(String)
[数值]
{整形}
字节型(Byte:B)
短整型(Short:S)
整型(Int:I)
长整型(Long:L)
{浮点型(小数)}
单精度浮点型(Float:F)
双精度浮点型(Double:D)
[数据]
复合标签(Combr /ound)
列表(List)
[数组]
字节型数组(Byte Array:[B])
整型数组(Int Array:[I])
长整型数组(Long Array:[L])
我们从字符串(String)这个最简单的类型入手。众所周知,字符串类型的值其外层需要使用英文的半角双引号(““)来包括。当引号里的值要写上引号时,就需要使用转义符号(\)放在引号前面转义。要在里面写上反斜杠(\)时也一样。比如:
{text:“我叫\“小明\“,这是反斜杠:\\“}
你知道吗?其实NBT的字符串并不一定需要使用双引号来包括,单引号也可以,只不过这是1.14版本才更新的:
{text:'我叫\'小明\',这是反斜杠:\\'}
如上面这个例子,要在值里面写上单引号,也是需要使用转义符号(\)的。
而这个字符串还远远不止那么简单。字符串的存储上线是32767个字节,可以含有中文、空格和特殊字符,编码形式为UTF-8。所以这就是为什么命令方块其字符上限就是32767,因为这就是字符串类型的值上线了。
只不过我们都知道,就连最基础的汉字也要占用2字节的空间,而UTF-8作为万国码,存储的字符就更多了。所以UTF-8的基础汉字一个就是3字节,而字符串的上限是32767字节,并不是32767个字符。所以更准确的来说,命令方块的储存上限是:
32767字节(UTF-8编码)
而不是32767个字符,这种说法是错误的。
总之,字符串的特性就是:
1.值大小上限为32767字节
2.使用UTF-8编码
3.文本可含有中文、空格和特殊字符
4.需用双引号(““)或单引号('')(1.14版本及以后)包裹。
5.如需要在文本里写上引号或反斜杠,需在其前面加上转义符号(\)
然后是我们的数值:
{整形}
字节型(Byte:B)
短整型(Short:S)
整型(Int:I)
长整型(Long:L)
{浮点型(小数)}
单精度浮点型(Float:F)
双精度浮点型(Double:D)
可以发现,NBT的数值细分到了整数和浮点数(小数)。我们先从整数入手,整数类型的类型有:
字节型(Byte:B)
短整型(Short:S)
整型(Int:I)
长整型(Long:L)
实际上这些都是存储整数。它们的明显差别只不过是名字的不同和数值上下限的不同。
最小的字节型(Byte:B),其值是存储一个绝对值很小的整数,范围是:
-128~127「-(2⁷)~2⁷-1」
很简单对吧?
其实不简单。在第一节的最后,作者提到特定类型的值还有可填可不填的格式。这个字节型就是其中之一,其格式其实是这样的:
{Byte:数值b}
没错,字节型的值需要你在填完数值之后再加上一个特定的字母,通常是这个类型其英文缩写的小写形式,比如字节型的Byet缩写就是B,再小写一下就是b。
为什么要这样呢?其实这就是起到一个区分的作用,实际上你不在最后面写b也是可以的,游戏大部分情况会自动帮你加上去。当出现错误时可能才需要用到。短整型和长整型以及其他的一些类型也是数值后面有类型字母的,当然大部分情况它们不填也是可以的。
实际上Byte类型值不仅仅是个数值,它还有另一种值:
布尔值(false|true)
没错,Byte值也是布尔值,这个布尔值一般是数字形式的:
1和0
也有些情况下是true和false。
当为字母形式时,就不用填最后的b了,只需要类似于字符串那样加上引号就可以了(好像不加也可以)。
这就是Byte类型。按理来说一个普通的MC指令教程说到这就可以了,但这本书并不普通。所以接下来我们要研究一个问题:
为什么这个值类型叫做“字节型”呢?
其实答案很简单。刚才的数值范围大家也都知道,是:
-128~127,
也就是-(2⁷)~2⁷-1(二的七次幂的相反数到二的七次幂减一的差)
我们的一个字节,也就是:
8bit(8个二进制数字)
字节型数值的绝对值最大值是128,即2⁷,转换成二进制就是10000000,刚好一字节。
这就是字节型这个名称的由来,是不是灰常简单?
总之,字节型(Byte:B)的特性就是:
1.值为整数或布尔值
2.当值为数值时,数值范围为-128~127
3.当值为数值时,需要在值最后加上类型字母b
4.占用空间只有1字节
(唉,为什么最大值不是11111111,即511?)
(有补码懂不懂?有补码才能区分正负!)
比字节型范围稍大的短整型(Short:S),在上面就有提到其也是有类型字母的。而这个类型字母就是:s,具体这个放在哪里大家都应该知道的。
短整形的数值范围是:
-32768~32767「-(2¹⁵)~2¹⁵-1」(占用2字节)
是不是很熟悉?没错,1.13版本以下附魔的等级值就是短整形,所以当时的附魔最大等级才是32767。
所以我们可以根据这个附魔的标签来举个例子:
{ench:[{lvl:32767s,id:18s}]}——这就是短整形的最大值,也就是附魔等级的最大值
{ench:[{lvl:-32768s,id:18s}]}——这就是短整形的最小值,也是附魔等级的理论最小值(LV.-32767?)
(细心的朋友可能注意到了,1.13以前的id其值也是短整形)
到了1.13以后,情况就不一样了。Mojang把lvl值类型改成了int整形,附魔的上限也就升级到了2147483647。但实际上,在新版本,lvl其值是int和Short混用的。具体是这样的:
用附魔台附魔或战利品表生成的,是Short短整形,但是读取时是按照int整形的时候来读取的。其他的就直接是int了。
只不过这些东西,我们以后再说。现在回到正题。
Short的内容就是这么多。总的来说,Short短整形的特性就是:
1.值范围是-32768~32767(整数)
2.类型字母为s
3.占用空间2字节
OK NBT标签的内容就暂且到这里了,我们下一章再见。
(补码是什么啊?)
(简单来说,这八位的第一位是表示正负号,0为正,1为负。所以负值最小可以到-128即10000000,正值最大可以到127即01111111。)
(哦懂了懂了)
(不光byte有补码,Minecraft的十四种NBT数据类型中,除了字符串、复合标签、列表这三样,其他都有补码)
(对了,byte作为布尔值时是没有补码的。实际上在Java语言中,byte数值没有布尔值这个用途,表示布尔值的是一个叫boolean的数据类型,Minecraft的NBT中Mojang把boolean的功能合并到了byte中,所以这就是为什么byte还有一个挺突兀的布尔值功能)