扫码在手机阅读
手机阅读《Minecraft指令手册》
Minecraft指令手册

第120章区块加载器

区块加载器根据实际用法大致有两个类别:加载当前区块的和加载指定区块的。

你可以在B站上搜到一大堆的视频教程,我相信你看完这些教程一定能做出来的。

(实际上有一个MOD是专门解决这个问题的,如果不想要麻烦的话去下个MOD也行)

但那个指令是在版本添加的啊!

可是现在大部分人最常用的版本仍然是,那么这些人该怎么办呢?

很简单,我们知道JAVA版他本来就自带了一个常加载区块,也就是世界出生点区块。

当玩家从一个区块移动到另一个区块,玩家视距内的区块都会被加载,同时游戏会根据玩家现在的位置来加载一些新的区块,同时也卸载掉一些旧的区块,让游戏保持流畅。

但实际上,不只是玩家,红石、火焰以及漏斗都会加载区块。

那么这些区块什么时候会被卸载呢?

实际上不只是你,连你正在玩的Minecraft都不知道。

但你正在玩的Minecraft可比你要聪明一点,它知道它自己不知道该何时卸载掉这些区块,所以它想到了另一种方法:每隔45秒,它自己就会检查所有正在加载的区块,并标记那些玩家不在的那些区块,等待一个好的时机把它们卸载掉。

这就是区块加载的基本原理。

而区块加载器的原理就简单了,我们知道不仅是玩家,漏斗、火焰以及红石也会加载区块。所以我们只需要让那些机械不断的去加载区块,不就行了吗?

那么到底该怎么做呢?

别忘了,我们只知道区块加载的基本原理啊!我们还不知道那些漏斗什么的是怎么加载区块的。

其实很简单,我们拿漏斗举例。

假设,有一个漏斗在一个加载的区块边缘,它要漏的方向是对面没有加载的区块,而这个漏斗里面有一个物品。

然后这个漏斗就会尝试把这个物品给漏到对面的方块,但是对面是个还未加载的区块,它不知道它指向了什么方块。

于是它告诉游戏,让游戏加载这个区块。于是这个区块被加载了。

而这个漏斗终于发现它指向了一个锤子,漏不出来,所以它就完成了自己的使命。

这个时候你就成功加载了一个新的区块,而且不是玩家加载的。

而最简单的区块加载器,就是运用了这种原理,那么具体是怎么做的呢?

接着上文。这个漏斗完成了自己的使命,然鹅此时游戏发现:哎呀怎么新加载的区块还有一个装着物品的漏斗啊,于是游戏告诉这个新的漏斗,叫它赶紧漏。

然鹅这个漏斗发现不行啊,对面是未加载区块,咋漏,于是叫游戏加载这个新的区块。

加载好了,这个漏斗发现漏不了,就完成了自己的使命。而此时游戏又发现——卧槽怎么新加载的区块还有一个新的装着物品的漏斗。

于是又是漏,又加载,又漏,又加载,直到漏斗没有了。

但玩家肯定不想让游戏把这些区块给卸载,于是玩家们决定升级一下这个区块加载器,让其一直加载。

这时候,就要涉及到区块的卸载原理了。

区块的卸载有两种触发方式:

1.玩家远离区块那一刻

2.每45秒的检查

而不管是哪种触发方式,卸载的方法都相同:

1.游戏会将这些要卸载的区块都添加进一个表格,即哈希表。

2.游戏会按照哈希表的顺序来逐个卸载,然鹅这个顺序不一定是区块加载的顺序。

3.在每一刻的最后,游戏会进入区块卸载模式,但游戏每一次最多只能卸载100个区块,剩下的区块会等待下一次卸载。

这些险些被卸载的区块都还会正常运作,但游戏已经把它们贴在了卸载表上,相当于加上了一个死亡倒计时。

这些区块还有救吗?有救,只需要在下一次卸载之前,漏斗能提前加载那些区块,就可以将那个区块从卸载表上扯下来,让区块继续运作。

那么,我们就可以选择哈希表靠后的区块,我们就有机会它一直被漏斗加载。

没错,但是你该怎么知道哪个区块在哈希表靠后的地方?

其实哈希表的排序并不是随机的,而是有规律的。哈希表并不是单纯的一个表格,它是由哈希键索引的各种桶组合在一起的。而每一个区块的哈希键,由这个区块的X和Z来决定。也就是说,每个区块的卸载顺序,由这个区块的X和Z来决定。(注:一个区块的XZ为这个区块的中心位置,即在F3调试界面区块坐标XZ都为8的地方。

那么该怎么计算?

我们以世界原点(0,0)举个例子。

首先,游戏会将世界原点的X和Z轴转换成2进制,然后组合在一起,变成一个长8字节的2进制数字。而每个字节由8个2进制数字组成,所以这个8字节的二进制数字,就长达64个位数。即:

0000000000000000000000000000000000000000000000000000000000000000

(实际上这就是典型的64位,即64个位数,这下子你应该知道了这个64和32位操作系统的区别了吧)

然后游戏就会把这串数字交给JAVA处理。JAVA首先会把这个数字分成两半,即:

00000000000000000000000000000000-00000000000000000000000000000000

(这其实有些像我们以前讲过的UUID)

接着JAVA会把这串分成两半的数字左边跟右边做一次异或运算(即上面和下面的数字相同,输出0,不同,输出1),也就是:

00000000000000000000000000000000

00000000000000000000000000000000

得出来的结果是32位数:

00000000000000000000000000000000

你以为这就完了吗?其实还没完,JAVA会再把这串数字分两半,再异或,即:

0000000000000000-0000000000000000(32位)

—异或—

0000000000000000(16位)

然后把这个16位的二进制数字转化成10进制,即:0。

这就代表着这个区块的卸载顺序为0。

现在我们换一个坐标,换(3,3)吧:

3-3(10进制)

—转2进制—

00000000000000000000000000000011-00000000000000000000000000000011

—异或—

0000000000000000-0000000000000000

—异或—

0000000000000000

—转10进制—

3,3坐标竟然还是0。

所以我们可以得出一个结论:由于对角线的坐标X和Z的数字相同,导致异或后肯定为0,所以对角线的坐标在哈希表里的排序肯定为0。

紧接着,我们就可以通过这个结论,来反推出坐标里有一个数值为0的坐标(比如5,0)排序是最靠后的,数值为0的坐标即正东西南北方向。

而我们还可以通过上面的转化过程知道,转化的最大XZ值不能超过4294967295,最小也不能小于-4294967295。

但是为了让大家更直观的了解区块加载顺序,作者就去计算了以原点为中心,16x16的区块的公式结果并制成了图片,最终结果可以加一下群看(群相册),不嫌麻烦的话.......

也可以前往这个网址查看:sc?/V12hBLHP1rg0d7/ruAMsa53pVQWN7FLK88i5uzvbLxLD58OVyNzZou1uUu8F0RYkSv9jxcNhY89sjOb*ocTak2*reWHtk36uBeWGWoNgPtREr6YPKYgR*ZRY!/b&ek=1&kp=1&pt=0&bo=OAQ4BAAAAAABFzA!&tl=3&vuin=3240737199&tm=1596549600&sce=60-2-2&rf=viewer_4(注意要加http)

这张图片区块颜色越红,结果数字越小,优先级越高;越白,结果数字越大,优先级越低。

而且如果深入研究,还是有很多规律的:

1.其实不难发现,这张图片只看颜色是对称的,而且上下对称,左右对称。

2.很明显就可以发现,这张图片看起来好像很复杂,其实是有层次的——第一层是每个区块(1x1),第二层是每4个区块(4x4),而更巧的是如果以4x4来看待这张图片,就会发现其实只有两种4x4的方形,只不过它们有些被镜像化了。

同时这张图片也证明了我们上面的说法:.....来反推出坐标里有一个数值为0的坐标(比如5,0)排序是最靠后的,数值为0的坐标即正东西南北方向。

说了这么多,区块的卸载顺序大致也搞懂了吧?但是此时又有一个新的问题出现了:如果一个“桶”里装了很多个区块,比如优先量都为0的区块全部装在一个桶里,这该怎么办?

其实也不需要太深究,这些已经够了。

接下来,让我们回到Minecraft。了解了上面这些东西后,下面这些东西就已经很简单了。

我们知道每刻游戏最多卸载掉100个区块,那么我们就可以找100多个没用的优先级高的区块,比如全部找对角线的区块,让它们卸载了再加载,再卸载,不就可以了?

没错,这是一个很棒的想法,实际上区块加载器的原理也差不多就是这样。我们得一直运行100多个加载区块才能让特定区块保持加载。

别担心,这个工程只不过有点耗肝,脑袋配置较低稍微有点肝的话也能做得出来的。

(只不过除了肝,还有亿点耗铁)

大致方法已经敲定了,接下来就是细节了。

我们遇到的第一个问题就是:怎样让那些占哈希表的区块卸载了再加载,再卸载?

很简单,我们可以把旁边的区块也一起用上帮助加载。

我们以下面这个2x1的区块为一个例子:

0,16

你只需要准备两个漏斗和一些方块就可以搞定这个计算结果为0的区块。

参照上面的漏斗加载例子,你需要在0区块在对着16区块的边缘处放一个朝向16区块的漏斗,16区块那边也在对着0区块的边缘处放置一个对着0区块的漏斗,两个漏斗都放置一些物品。

那么这是怎么运作的呢?

假设你已经成功的按照上面的步骤制作出了100个常加载的0区块,那么你就会发现这个的运作原理是这样的:

1.在清除那一刻,0区块被卸载,而16区块继续运作,只不过被打上了死亡标签。

而下一刻,16区块的漏斗激活了0区块,0区块激活后其漏斗又把16区块给拉出了死亡表里。

45秒后,0区块又卸载,16区块漏斗又激活0区块,然后0区块漏斗又加载16区块,两区块又是这么平安无事。

就是这么个原理。

搞定了那100多个常被杀区块后,接下来你就可以来自由的设置你的常加载区块了。

(只不过处在对角线的要加载区块最好还是把里面的设施搬走吧,换一个区块)

假设你要不断加载相邻的4个区块(2x2)该怎么办?

在四个区块的交界处弄一个2x2的漏斗循环。

假设你要搞定相邻的两个区块该怎么办?

照着那100个常被杀区块那样做就行了。

假设你只需要弄好一个区块该怎么办?

很简单,其相邻的4个区块每一个都弄一个朝向该区块的漏斗。

这就是最简单的区块加载器做法。

(事实上还有更高级的维度加载器,通过维度加载器,可以同时加载两个三个甚至2147483647个维度,但那个装置更加的复杂)

但这些区块加载器仍然有被卸载的危险。

这个危险不是每45秒的卸载,而是玩家离开那一刻的区块卸载。如果玩家离开那一刻两个区块都同时被卸载。那就糟糕了。

(对了,按下F3+G可以打开区块调试界面,这个时候就可以看见区块的边界了,不再需要按F3一步一步试探)

现在,你已经知道怎么让多个区块同时加载了。如果你经常玩纯生存服务器,那么这个装置肯定会帮到你的自动化机器的,让其挂机也有收益。

只不过腐竹会不会找你算账那就不一定了。

把命令方块放在世界出生点区块内,就可以一直运行了。

那么怎样设置世界出生点呢?

没错,虽然这件事你不可能只用指令做到。但是你可以只用红石做到!

这说明什么?你的刷铁机有救了!

这其实并不是一个指令。

在第九十七章,作者讲到了JAVA版可以使用forceload指令来创建一个常加载区块。

额,在第三十四章不是讲过了吗,使用/setworldspawn就可以在当前位置设置出生点了。

(教你一招,实际上你只需要输入一个/set,然后按两次Tab就可以了)

那么该怎么办呢?

也并不是一个方块。

那应该是什么?

红石机械啊!

但是如果要设置多个呢?

很抱歉,没有这个指令。

我们可以在这里稍微了解一下这个技术的原理。

为了了解这个技术的原理,我们还要了解一下区块加载的原理:

这个时候我们就要引入一个新的概念:区块加载器。

什么是区块加载器?

就这么简单。

  • 加入收藏
  • 目录
  • A+
  • A-