第一百二十章 區(qū)塊加載器
在第九十七章,作者講到了JAVA版可以使用forceload指令來創(chuàng)建一個常加載區(qū)塊。
但那個指令是在1.13.1版本添加的??!
可是現(xiàn)在大部分人最常用的版本仍然是1.12.2,那么這些人該怎么辦呢?
很簡單,我們知道JAVA版他本來就自帶了一個常加載區(qū)塊,也就是世界出生點區(qū)塊。
把命令方塊放在世界出生點區(qū)塊內(nèi),就可以一直運行了。
那么怎樣設(shè)置世界出生點呢?
額,在第三十四章不是講過了嗎,使用/setworldspawn就可以在當(dāng)前位置設(shè)置出生點了。
?。ń棠阋徽?,實際上你只需要輸入一個/set,然后按兩次Tab就可以了)
就這么簡單。
但是如果要設(shè)置多個呢?
很抱歉,沒有這個指令。
那么該怎么辦呢?
這個時候我們就要引入一個新的概念:區(qū)塊加載器。
什么是區(qū)塊加載器?
這其實并不是一個指令。
也并不是一個方塊。
那應(yīng)該是什么?
紅石機(jī)械?。?p> 沒錯,雖然這件事你不可能只用指令做到。但是你可以只用紅石做到!
這說明什么?你的刷鐵機(jī)有救了!
區(qū)塊加載器根據(jù)實際用法大致有兩個類別:加載當(dāng)前區(qū)塊的和加載指定區(qū)塊的。
你可以在B站上搜到一大堆的視頻教程,我相信你看完這些教程一定能做出來的。
(實際上有一個MOD是專門解決這個問題的,如果不想要麻煩的話去下個MOD也行)
我們可以在這里稍微了解一下這個技術(shù)的原理。
為了了解這個技術(shù)的原理,我們還要了解一下區(qū)塊加載的原理:
當(dāng)玩家從一個區(qū)塊移動到另一個區(qū)塊,玩家視距內(nèi)的區(qū)塊都會被加載,同時游戲會根據(jù)玩家現(xiàn)在的位置來加載一些新的區(qū)塊,同時也卸載掉一些舊的區(qū)塊,讓游戲保持流暢。
但實際上,不只是玩家,紅石、火焰以及漏斗都會加載區(qū)塊。
那么這些區(qū)塊什么時候會被卸載呢?
實際上不只是你,連你正在玩的Minecraft都不知道。
但你正在玩的Minecraft可比你要聰明一點,它知道它自己不知道該何時卸載掉這些區(qū)塊,所以它想到了另一種方法:每隔45秒,它自己就會檢查所有正在加載的區(qū)塊,并標(biāo)記那些玩家不在的那些區(qū)塊,等待一個好的時機(jī)把它們卸載掉。
這就是區(qū)塊加載的基本原理。
而區(qū)塊加載器的原理就簡單了,我們知道不僅是玩家,漏斗、火焰以及紅石也會加載區(qū)塊。所以我們只需要讓那些機(jī)械不斷的去加載區(qū)塊,不就行了嗎?
那么到底該怎么做呢?
別忘了,我們只知道區(qū)塊加載的基本原理??!我們還不知道那些漏斗什么的是怎么加載區(qū)塊的。
其實很簡單,我們拿漏斗舉例。
假設(shè),有一個漏斗在一個加載的區(qū)塊邊緣,它要漏的方向是對面沒有加載的區(qū)塊,而這個漏斗里面有一個物品。
然后這個漏斗就會嘗試把這個物品給漏到對面的方塊,但是對面是個還未加載的區(qū)塊,它不知道它指向了什么方塊。
于是它告訴游戲,讓游戲加載這個區(qū)塊。于是這個區(qū)塊被加載了。
而這個漏斗終于發(fā)現(xiàn)它指向了一個錘子,漏不出來,所以它就完成了自己的使命。
這個時候你就成功加載了一個新的區(qū)塊,而且不是玩家加載的。
而最簡單的區(qū)塊加載器,就是運用了這種原理,那么具體是怎么做的呢?
接著上文。這個漏斗完成了自己的使命,然鵝此時游戲發(fā)現(xiàn):哎呀怎么新加載的區(qū)塊還有一個裝著物品的漏斗啊,于是游戲告訴這個新的漏斗,叫它趕緊漏。
然鵝這個漏斗發(fā)現(xiàn)不行啊,對面是未加載區(qū)塊,咋漏,于是叫游戲加載這個新的區(qū)塊。
加載好了,這個漏斗發(fā)現(xiàn)漏不了,就完成了自己的使命。而此時游戲又發(fā)現(xiàn)——臥槽怎么新加載的區(qū)塊還有一個新的裝著物品的漏斗。
于是又是漏,又加載,又漏,又加載,直到漏斗沒有了。
但玩家肯定不想讓游戲把這些區(qū)塊給卸載,于是玩家們決定升級一下這個區(qū)塊加載器,讓其一直加載。
這時候,就要涉及到區(qū)塊的卸載原理了。
區(qū)塊的卸載有兩種觸發(fā)方式:
1.玩家遠(yuǎn)離區(qū)塊那一刻
2.每45秒的檢查
而不管是哪種觸發(fā)方式,卸載的方法都相同:
1.游戲會將這些要卸載的區(qū)塊都添加進(jìn)一個表格,即哈希表。
2.游戲會按照哈希表的順序來逐個卸載,然鵝這個順序不一定是區(qū)塊加載的順序。
3.在每一刻的最后,游戲會進(jìn)入?yún)^(qū)塊卸載模式,但游戲每一次最多只能卸載100個區(qū)塊,剩下的區(qū)塊會等待下一次卸載。
這些險些被卸載的區(qū)塊都還會正常運作,但游戲已經(jīng)把它們貼在了卸載表上,相當(dāng)于加上了一個死亡倒計時。
這些區(qū)塊還有救嗎?有救,只需要在下一次卸載之前,漏斗能提前加載那些區(qū)塊,就可以將那個區(qū)塊從卸載表上扯下來,讓區(qū)塊繼續(xù)運作。
那么,我們就可以選擇哈希表靠后的區(qū)塊,我們就有機(jī)會它一直被漏斗加載。
沒錯,但是你該怎么知道哪個區(qū)塊在哈希表靠后的地方?
其實哈希表的排序并不是隨機(jī)的,而是有規(guī)律的。哈希表并不是單純的一個表格,它是由哈希鍵索引的各種桶組合在一起的。而每一個區(qū)塊的哈希鍵,由這個區(qū)塊的X和Z來決定。也就是說,每個區(qū)塊的卸載順序,由這個區(qū)塊的X和Z來決定。(注:一個區(qū)塊的XZ為這個區(qū)塊的中心位置,即在F3調(diào)試界面區(qū)塊坐標(biāo)XZ都為8的地方。
那么該怎么計算?
我們以世界原點(0,0)舉個例子。
首先,游戲會將世界原點的X和Z軸轉(zhuǎn)換成2進(jìn)制,然后組合在一起,變成一個長8字節(jié)的2進(jìn)制數(shù)字。而每個字節(jié)由8個2進(jìn)制數(shù)字組成,所以這個8字節(jié)的二進(jìn)制數(shù)字,就長達(dá)64個位數(shù)。即:
0000000000000000000000000000000000000000000000000000000000000000
?。▽嶋H上這就是典型的64位,即64個位數(shù),這下子你應(yīng)該知道了這個64和32位操作系統(tǒng)的區(qū)別了吧)
然后游戲就會把這串?dāng)?shù)字交給JAVA處理。JAVA首先會把這個數(shù)字分成兩半,即:
00000000000000000000000000000000-00000000000000000000000000000000
?。ㄟ@其實有些像我們以前講過的UUID)
接著JAVA會把這串分成兩半的數(shù)字左邊跟右邊做一次異或運算(即上面和下面的數(shù)字相同,輸出0,不同,輸出1),也就是:
00000000000000000000000000000000
00000000000000000000000000000000
得出來的結(jié)果是32位數(shù):
00000000000000000000000000000000
你以為這就完了嗎?其實還沒完,JAVA會再把這串?dāng)?shù)字分兩半,再異或,即:
0000000000000000-0000000000000000(32位)
—異或—
0000000000000000(16位)
然后把這個16位的二進(jìn)制數(shù)字轉(zhuǎn)化成10進(jìn)制,即:0。
這就代表著這個區(qū)塊的卸載順序為0。
現(xiàn)在我們換一個坐標(biāo),換(3,3)吧:
3-3(10進(jìn)制)
—轉(zhuǎn)2進(jìn)制—
00000000000000000000000000000011-00000000000000000000000000000011
—異或—
0000000000000000-0000000000000000
—異或—
0000000000000000
—轉(zhuǎn)10進(jìn)制—
0
3,3坐標(biāo)竟然還是0。
所以我們可以得出一個結(jié)論:由于對角線的坐標(biāo)X和Z的數(shù)字相同,導(dǎo)致異或后肯定為0,所以對角線的坐標(biāo)在哈希表里的排序肯定為0。
緊接著,我們就可以通過這個結(jié)論,來反推出坐標(biāo)里有一個數(shù)值為0的坐標(biāo)(比如5,0)排序是最靠后的,數(shù)值為0的坐標(biāo)即正東西南北方向。
而我們還可以通過上面的轉(zhuǎn)化過程知道,轉(zhuǎn)化的最大XZ值不能超過4294967295,最小也不能小于-4294967295。
但是為了讓大家更直觀的了解區(qū)塊加載順序,作者就去計算了以原點為中心,16×16的區(qū)塊的公式結(jié)果并制成了圖片,最終結(jié)果可以加一下群看(群相冊),不嫌麻煩的話.......
也可以前往這個網(wǎng)址查看:a1.qpic.cn/psc?/V12hBLHP1rg0d7/ruAMsa53pVQWN7FLK88i5uzvbLxLD58OVyNzZou1uUu8F0RYkSv9jxcNhY89sjOb*ocTak2*reWHtk36CouBeWGWoNgPtREr6YPKYgR*ZRY!/b&ek=1&kp=1&pt=0&bo=OAQ4BAAAAAABFzA!&tl=3&vuin=3240737199&tm=1596549600&sce=60-2-2&rf=viewer_4(注意要加http)
這張圖片區(qū)塊顏色越紅,結(jié)果數(shù)字越小,優(yōu)先級越高;越白,結(jié)果數(shù)字越大,優(yōu)先級越低。
而且如果深入研究,還是有很多規(guī)律的:
1.其實不難發(fā)現(xiàn),這張圖片只看顏色是對稱的,而且上下對稱,左右對稱。
2.很明顯就可以發(fā)現(xiàn),這張圖片看起來好像很復(fù)雜,其實是有層次的——第一層是每個區(qū)塊(1x1),第二層是每4個區(qū)塊(4x4),而更巧的是如果以4x4來看待這張圖片,就會發(fā)現(xiàn)其實只有兩種4x4的方形,只不過它們有些被鏡像化了。
同時這張圖片也證明了我們上面的說法:.....來反推出坐標(biāo)里有一個數(shù)值為0的坐標(biāo)(比如5,0)排序是最靠后的,數(shù)值為0的坐標(biāo)即正東西南北方向。
說了這么多,區(qū)塊的卸載順序大致也搞懂了吧?但是此時又有一個新的問題出現(xiàn)了:如果一個“桶”里裝了很多個區(qū)塊,比如優(yōu)先量都為0的區(qū)塊全部裝在一個桶里,這該怎么辦?
其實也不需要太深究,這些已經(jīng)夠了。
接下來,讓我們回到Minecraft。了解了上面這些東西后,下面這些東西就已經(jīng)很簡單了。
我們知道每刻游戲最多卸載掉100個區(qū)塊,那么我們就可以找100多個沒用的優(yōu)先級高的區(qū)塊,比如全部找對角線的區(qū)塊,讓它們卸載了再加載,再卸載,不就可以了?
沒錯,這是一個很棒的想法,實際上區(qū)塊加載器的原理也差不多就是這樣。我們得一直運行100多個加載區(qū)塊才能讓特定區(qū)塊保持加載。
別擔(dān)心,這個工程只不過有點耗肝,腦袋配置較低稍微有點肝的話也能做得出來的。
(只不過除了肝,還有億點耗鐵)
大致方法已經(jīng)敲定了,接下來就是細(xì)節(jié)了。
我們遇到的第一個問題就是:怎樣讓那些占哈希表的區(qū)塊卸載了再加載,再卸載?
很簡單,我們可以把旁邊的區(qū)塊也一起用上幫助加載。
我們以下面這個2x1的區(qū)塊為一個例子:
0,16
你只需要準(zhǔn)備兩個漏斗和一些方塊就可以搞定這個計算結(jié)果為0的區(qū)塊。
參照上面的漏斗加載例子,你需要在0區(qū)塊在對著16區(qū)塊的邊緣處放一個朝向16區(qū)塊的漏斗,16區(qū)塊那邊也在對著0區(qū)塊的邊緣處放置一個對著0區(qū)塊的漏斗,兩個漏斗都放置一些物品。
那么這是怎么運作的呢?
假設(shè)你已經(jīng)成功的按照上面的步驟制作出了100個常加載的0區(qū)塊,那么你就會發(fā)現(xiàn)這個的運作原理是這樣的:
1.在清除那一刻,0區(qū)塊被卸載,而16區(qū)塊繼續(xù)運作,只不過被打上了死亡標(biāo)簽。
而下一刻,16區(qū)塊的漏斗激活了0區(qū)塊,0區(qū)塊激活后其漏斗又把16區(qū)塊給拉出了死亡表里。
45秒后,0區(qū)塊又卸載,16區(qū)塊漏斗又激活0區(qū)塊,然后0區(qū)塊漏斗又加載16區(qū)塊,兩區(qū)塊又是這么平安無事。
就是這么個原理。
搞定了那100多個常被殺區(qū)塊后,接下來你就可以來自由的設(shè)置你的常加載區(qū)塊了。
?。ㄖ徊贿^處在對角線的要加載區(qū)塊最好還是把里面的設(shè)施搬走吧,換一個區(qū)塊)
假設(shè)你要不斷加載相鄰的4個區(qū)塊(2x2)該怎么辦?
在四個區(qū)塊的交界處弄一個2x2的漏斗循環(huán)。
假設(shè)你要搞定相鄰的兩個區(qū)塊該怎么辦?
照著那100個常被殺區(qū)塊那樣做就行了。
假設(shè)你只需要弄好一個區(qū)塊該怎么辦?
很簡單,其相鄰的4個區(qū)塊每一個都弄一個朝向該區(qū)塊的漏斗。
這就是最簡單的區(qū)塊加載器做法。
?。ㄊ聦嵣线€有更高級的維度加載器,通過維度加載器,可以同時加載兩個三個甚至2147483647個維度,但那個裝置更加的復(fù)雜)
但這些區(qū)塊加載器仍然有被卸載的危險。
這個危險不是每45秒的卸載,而是玩家離開那一刻的區(qū)塊卸載。如果玩家離開那一刻兩個區(qū)塊都同時被卸載。那就糟糕了。
?。▽α?,按下F3+G可以打開區(qū)塊調(diào)試界面,這個時候就可以看見區(qū)塊的邊界了,不再需要按F3一步一步試探)
現(xiàn)在,你已經(jīng)知道怎么讓多個區(qū)塊同時加載了。如果你經(jīng)常玩純生存服務(wù)器,那么這個裝置肯定會幫到你的自動化機(jī)器的,讓其掛機(jī)也有收益。
只不過腐竹會不會找你算賬那就不一定了。