本來昨天想看區塊加載/卸載和怪物despawn部分的源碼的,但是眼賤看到了庄主接受挑戰的視頻,雖然說挑戰發起者不是我,不過這個設計思路跟我之前發的帖子基本一樣,而且原帖我正好路過庄主貼吧的時候看到並且插了幾句嘴,於是對刷石機這個問題瞬間又提起了興趣,於是一天都在查這方面的源碼。
刷石機設計
刷石的基本原理是利用岩漿和水的相互作用:
- 當岩漿流向下方的水時,水變為石頭
![[圖]岩漿遇水下落變成石頭][] - 當岩漿源其他方向是水時,岩漿變為黑曜石
![[圖]岩漿源遇水變黑曜石][] - 當非源岩漿(級數<=4)其他方向是水時,岩漿變為圓石
![[圖]非源岩漿與水相互作用][]
岩漿源的級數是0,在主世界每走一格級數+2,末地和下界每走一格級數+1,下落的岩漿級數=原級數+8。
由於挖掘圓石的速度比挖掘石頭要慢,而且石頭是選擇挖成石頭還是圓石的,所以高速刷石機一般采用岩漿在上水在下的方式。又因為站着不動挖掘最多能挖5格,所以一般都是5個刷石單元並排作為一組形成一個刷石機。
![[圖]5聯刷石機][]
為了達到高速刷石的效果,刷出的石頭應該盡快“讓位”,即把刷石位空出來,於是需要設計活塞電路,將新刷出的石頭推出。各種設計不同的高速刷石機主要區別就在這里。
刷石機故障分析
現在是時候說一下刷石機的“隱患”了。
D大刷石機
首先來看D大的刷石機設計,有一個顯而易見的問題:當刷出的石頭沒有及時處理,以致不能再被B組活塞推出時,刷石點下方的格子會被石頭堵住,下次開始刷石時就會推掉岩漿:
![[圖]D大刷石機崩潰][]
D大為此做了一個快捷關閉機器的壓力板,一定程度緩解了這個問題,但用戶體驗仍不夠好,每次開關機器前后要先把石頭挖一下。
ET刷石機
我在設計刷石機時令A組活塞平時處於推出狀態,這樣一來B組活塞推不動的石頭會直接被A組活塞推上去阻塞刷石位,阻止新石頭的刷出,從而不會出現D大刷石機的問題。但這樣一來卻引發了新的問題。
我們來看一下岩漿把水變成石頭的過程。
理想情況,因為水的流速比岩漿快,一般情況下應該是水先流進刷石位,然后岩漿流下把水變成石頭。
但有時候會事與願違,岩漿可能會先流下,這時候,下流的岩漿由於級數>8,不會變成圓石,另一方面,水是不能流向岩漿的,這格岩漿會一直存在。
但是岩漿可以流向水並把水替換掉,於是之后岩漿會流進水的格子,如果旁邊還有別的水,岩漿就會變成圓石。
![[圖]圓石故障][]
在D大的設計中,由於A組活塞平時是關閉的,會留出一個空位讓岩漿往下流而不會影響水源,而在下一個周期中C組活塞就會把刷石位的岩漿清空,讓機器恢復正常運行。
![[圖]D大刷石機故障處理][]
但是我的刷石機就不能幸免了,輕則無法刷石
![[圖]ET刷石機故障后果1][]
重則毀掉整個機器(這還不算最嚴重的……)
![[圖]ET刷石機故障后果2][]
我的這個刷石機雖然跟D大的很類似,但是實際上是我自己想出來的,出了這樣的問題非常令人不爽(然后才看到了D大的帖子並且學D大加了C組活塞)。想了各種辦法解決,但一直無功而返。
那么這個問題究竟是如何產生的?又有沒有什么解決的方式呢?
要徹底搞清楚這個問題,我們必須了解一件事:MC中液體流動是怎么計算的?是固定若干時間流動一次?還是周圍有空格后多少秒流動一格?
看了液體流動有關的代碼后得知,當液體接受到方塊更新后,會加入一個優先隊列,根據液體的流速,在若干游戲刻后進行一次流動(比如水的流速是5,那就是在5刻后流動),同時,如果這塊液體已經在隊列中排隊准備流動了,那么不會再次排隊。
既然液體流動的時間和收到的方塊更新有關,這樣一來,就有了一個新的問題,在我們的刷石機中,液體(即水和岩漿)什么時候會收到方塊更新?
為了簡化問題,我們在主世界以刷出單個石頭的刷石單元為例,並暫時去掉與刷石無關的C組活塞;
![[圖]ET刷石機主要部分][]
可以看到,由於玻璃是不會發出方塊更新的,那唯一影響水和岩漿的就只有活塞了,具體來說,那活塞什么時候會發出方塊更新?
我看完了活塞的代碼(看吐了),並做了一些實驗。
發現活塞接受到紅石信號改變並完全伸出/收回活塞臂共需要3個游戲刻(1.5 ticks),用0,1,2標號這三個游戲刻,那么和活塞運動有關的位置發出方塊更新的時刻如下圖:
![[圖]活塞更新規律][]
對照上圖,可以得到岩漿和水收到更新的時刻表格:
| 時間(游戲刻) | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| 水 | 是 | 是 | 否 | 是 | 是 | 是 | 是 |
| 岩漿 | 是 | 否 | 否 | 否 | 否 | 是 | 否 |
而由於只能進隊一次,那么假設在上個周期的最后5個游戲刻水和岩漿都沒有收到過更新,那進隊情況如下:
| 時間(游戲刻) | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| 水 | 是 | 否 | 否 | 否 | 否 | 是 | 否 |
| 岩漿 | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
這樣一來在每個周期的第5游戲刻水流會流下,1-4刻便是岩漿流下的“危險期”。由於在主世界岩漿的流速是30游戲刻,那么如果機器的周期是30游戲刻的整數倍,那么岩漿始終會在30的整數倍時刻收到更新,並在刷石位有空位的時候流下;否則,在一個周期中岩漿流下的時刻不固定,很容易在“危險期”先於水流流下來。
(嚴格說應該是周期的游戲刻數和30的最大公約數>5就可以避開“危險期”)
那么是否只要周期設置的安全就可以完全避免這個問題呢?很不幸,這個答案是否定的。
我為此糾結了很久。后來發現,游戲中會隨機對某些方塊進行random tick,隨機選擇方塊來做某些操作,這種機制主要用來控制作物生長(D大介紹過),但是如果選的方塊是排過隊的液體方塊,那么就會對這塊液體進行一次流動!(不會從隊列中刪除,即原來設定的流動時間還會再流動一次)
這樣一來,在隊列中的液體隨時都有流動的可能;對於我的刷石機來說,在危險期內,岩漿隨時都可能流下。(關於第0游戲刻是否危險:MC運行的順序是處理液體正常流動、處理random tick、處理活塞。在0刻時,先岩漿流下把水變成石頭,然后random tick什么都做不成,然后活塞把石頭拉出,所以0刻不會發生故障。)
如果使用C組活塞,能否解決問題?
好消息是,基本可以滿足要求。
簡單來說,活塞在第x游戲刻接受到n ticks的信號,活塞臂可以在第x+1~x+2*n游戲刻之間阻擋液體流動。那么我們在0刻給C組活塞2 ticks的信號,即可以把危險期完全覆蓋!當然其他2組活塞的時序也要對應改一下,改動后的時序如下圖:
![[圖]ET刷石機改良][]
這里使用了一個2.5 ticks的負脈沖限制器,圖片來源於Minecraft英文wiki。
![[圖]2.5T負脈沖限制器][]
壞消息是,機器還是有可能會出現故障。
在第5游戲刻的時候,系統會先判定C組活塞已經完全收回,不阻塞刷石位,於是水流出,如果就在這一游戲刻岩漿被random tick了,就會產生石頭。如果這時石頭都已經刷滿沒被采集,那么這個新刷出的石頭就會被推上一格,堵塞岩漿。
![[圖]ET刷石機新故障][]
這種情況出現的概率確實很低,但不能說一點可能性都沒,用的時間長了總會有出問題的時候。
庄主刷石機
現在來看一下庄主的刷石機,按照現在的時序,岩漿可能提前下落的時間為第1-9游戲刻。根據庄主現在的時序,A的活塞臂阻擋岩漿的時間為第1-2游戲刻,第5-8游戲刻,危險期為第3-4游戲刻和第9游戲刻。雖然活塞二次推出可以清空在3-4刻下落的岩漿,但有極低的概率岩漿和水在3-4刻連續受到random tick影響而相遇。
而庄主的設計卻巧妙地避開了此問題帶來的副作用,即使岩漿下落,並且把水變成了圓石,也不會阻塞機器,下一個周期只要不再被random tick影響,就會恢復正常。
![[圖]庄主刷石機故障處理][]
完美刷石機設計
看到這里強迫症表示不服,就沒有完美的刷石機么?既不會刷出圓石,也不會機器崩潰的?
好!滿足你!
實際上,只要把庄主的刷石機的時序改一下就可以了:將A組活塞的伸出時長改為4.5 ticks即可覆蓋全部危險期;為了讓水流第一時間流出,B組必須在1 ticks推出,時長必須為1 ticks(1.5也可,但麻煩);C組的時序就比較隨意了,2刻之后推一下就可以:
![[圖]庄主刷石機時序改良][]
產生4.5 ticks脈沖的電路和上面2.5 ticks脈沖電路類似:
![[圖]4.5T脈沖限制器][]
刷石機效率分析
增加刷石機產出的方法
至此,刷石機的各種(已知)故障算是完美解決。於是我們可以來談談效率問題了。
上文說到過岩漿在主世界流動的速度為30,故而在主世界中,單排刷石機的時鍾周期最低也要30,否則不能每個時鍾周期都刷出石頭。
而為了進一步提高效率,就可以通過增加刷石機組數的方式了,比如這樣:
![[圖]D大雙核][]
甚至這樣:
![[圖]ET4核][]
信標式刷石機效率分析
由於刷石機可以增加組數,效率的瓶頸成為了石頭的處理速度。對於信標式刷石機來說,效率的瓶頸來自史蒂夫的挖掘速度。
先對各位路人解釋一下什么叫信標式刷石機吧。這個概念應該最先由D大提出(至少我是最先從他的這個帖子接觸的),利用高速刷石機產生石頭,然后利用鑽石鎬附魔效率V(因為wiki的信息和1.8不符所以不貼地址了)+信標急迫II效果,達到極快的破壞方塊速度,快速采集石頭。
![[圖]快速采集][]
很多朋友不理解為什么要用鑽石鎬采集不用凋零,對這類機器噴的很厲害。我總結原因有這么幾點:
- 凋零頭打起來看RP。
- 困住凋零不容易,很危險,特別是在1.8。
- 凋零工廠建造更麻煩。
- 實際上信標式刷石機主體部分和凋零式一樣的,只是處理石頭方式不一樣。
- 這種機器本身就是一種樂趣。(其實上面4條都是編的_(:зゝ∠)_
那究竟多少組是史蒂夫挖掘速度的上限呢?帶着這個問題我又看了一下關於挖掘速度的代碼,具體信息我會另寫帖子,在這里只寫結論:在鑽石鎬+效率V+信標急迫II效果下,可以達到每游戲刻破壞1個方塊的速度,也是游戲中破壞方塊的最高速度。
那么在主世界中,理論上“6核”可以達到最高效率,為1200石頭/分鍾(5*6=30)。而在末地,因為岩漿流速為10,只要相當於每個“核”“超頻”了3倍,只要“雙核”就可以達到最高效率。
凋零式刷石機效率討論(TODO)
當然上面所說的效率僅限信標式刷石機,凋零式刷石機應該同理,效率瓶頸在於凋零破壞方塊的速度。我還沒有研究過凋零,暫時無法給出結論。
結語
於是到此我們的討論可以暫告一段落了。這篇文章前前后后寫了整整2天多,大量時間對着代碼看,腦子有時候會亂,如果有錯誤請指出,多多包涵。
[[圖]信標式刷石機]: https://images0.cnblogs.com/blog/552320/201502/050243257038972.png
[[圖]岩漿遇水下落變成石頭]: https://images0.cnblogs.com/blog/552320/201502/050245554537255.png
[[圖]岩漿源遇水變黑曜石]: https://images0.cnblogs.com/blog/552320/201502/050251135464034.png
[[圖]非源岩漿與水相互作用]: https://images0.cnblogs.com/blog/552320/201502/050251399532569.png
[[圖]5聯刷石機]: https://images0.cnblogs.com/blog/552320/201502/050252007342183.png
[[圖]D大刷石機]: https://images0.cnblogs.com/blog/552320/201502/050252199379982.png
[[圖]ET刷石機]: https://images0.cnblogs.com/blog/552320/201502/050252395786084.png
[[圖]庄主刷石機]: https://images0.cnblogs.com/blog/552320/201502/050252554995581.png
[[圖]D大刷石機崩潰]: https://images0.cnblogs.com/blog/552320/201502/050253159215853.png
[[圖]圓石故障]: https://images0.cnblogs.com/blog/552320/201502/050314234689096.png
[[圖]D大刷石機故障處理]: https://images0.cnblogs.com/blog/552320/201502/050254253594333.png
[[圖]ET刷石機故障后果1]: https://images0.cnblogs.com/blog/552320/201502/050253485782964.png
[[圖]ET刷石機故障后果2]: https://images0.cnblogs.com/blog/552320/201502/050254088745964.png
[[圖]ET刷石機主要部分]: https://images0.cnblogs.com/blog/552320/201502/050258170154706.png
[[圖]活塞更新規律]: https://images0.cnblogs.com/blog/552320/201502/050259098437545.png
[[圖]ET刷石機改良]: https://images0.cnblogs.com/blog/552320/201502/050259331873076.png
[[圖]2.5T負脈沖限制器]: https://images0.cnblogs.com/blog/552320/201502/050327029688860.png
[[圖]ET刷石機新故障]: https://images0.cnblogs.com/blog/552320/201502/050300583744469.png
[[圖]庄主刷石機故障處理]: https://images0.cnblogs.com/blog/552320/201502/050259588747225.png
[[圖]庄主刷石機時序改良]: https://images0.cnblogs.com/blog/552320/201502/050300301879890.png
[[圖]4.5T脈沖限制器]: https://images0.cnblogs.com/blog/552320/201502/050321544373503.png
[[圖]D大雙核]: https://images0.cnblogs.com/blog/552320/201502/050324357498251.png
[[圖]ET4核]: https://images0.cnblogs.com/blog/552320/201502/050324487342018.png
[[圖]快速采集]: https://images0.cnblogs.com/blog/552320/201502/050328546714587.png
