此錯誤未必對所有版本有效。該錯誤被修復後,下文所述的資訊將不再適用。
請慎重對待。
更新抑制(Update Suppression)是強制遊戲跳過方塊更新的做法,更新抑制器(Update Suppressor)是用於完成更新抑制的機器。更新抑制可用於切門、複製方塊、物品分身、可控崩潰、方塊實體替換,或將方塊放置在其它不可能的位置,例如漂浮在空中的告示牌或火把以及不在泥土等方塊上的花。
記憶體溢出更新抑制
記憶體溢出(Out of Memory,簡稱OOM)更新抑制是透過填滿記憶體,讓遊戲拋出記憶體溢出異常的更新抑制方式。
原理
為了進行更新抑制,我們需要恰到好處地填充遊戲記憶體,這樣當我們需要時,記憶體就能不夠用。我們可以使用放在未載入的區塊中的亂碼書和方塊事件列表來填滿記憶體。
填充方塊事件列表有幾種方式:使用活塞陣列填充和使用飛行器填充。如果使用活塞陣列,我們就需要約37萬個活塞。使用飛行器則省去了大量活塞,但需要掛機一會。
強轉抑制
強轉抑制(Cast Suppression或CCE Suppression)是透過讓遊戲在玩家更新時拋出ClassCastException類型轉換異常的更新抑制方式。
該更新抑制方法一般需要先將講台進行方塊實體替換,替換為界伏盒,需要使用更新抑制進行。因為這個界伏盒是打不開的,又具有更新抑制的能力,有時我們也稱這個界伏盒為魔法盒。
原理
類型轉換異常(ClassCastException,簡稱CCE),是Java的一個執行時異常,當一個對象被強制類型轉換到一個它不符合的類型的時候被拋出。因此,如果我們可以透過玩家操作拋出一個CCE,也可以用來實現更新抑制。一般而言,我們並不會有這樣的機會。但是方塊實體替換給了我們這樣的希望。
比如說,如果將一個儲物箱的方塊實體換到一個發射器上,當發射器執行發射動作的時候,它會取得自己位置的方塊實體,然後不加判斷地將其強制轉換為一個發射器方塊實體。但是我們換了一個儲物箱的方塊實體上去,就拋出了ClassCastException,會導致遊戲崩潰甚至是存檔損壞。
這個CCE的位置太危險了,但是也給了我們新的希望——也許代碼裡面有別的類似地不加判斷的強制類型轉換,可以讓我們透過玩家操作瞬時地拋出一個CCE?
當一個界伏盒計算自己的比較器輸出的時候,它會獲得自己的方塊實體,強制類型轉換為一個物品欄,然後丟進calculateComparatorOutput()這個函數。實際上,函數calculateComparatorOutput()裡面已經包括了安全的類型轉換的邏輯,Mojang寫在這裡的這一處不加判斷的類型轉換是完全沒有必要的,也是危險的。甚至界伏盒之外的別的容器,比如儲物箱計算自己的比較器輸出的時候都沒有這個轉換。
但是這一處強制類型轉換是可以利用的——我們如果能夠讓一個界伏盒擁有一個非物品欄的方塊實體,那麼每當比較器想要計算它的輸出的時候,就會拋出CCE。那麼如果我們將一個比較器從這樣的界伏盒裡面輸出,那麼每次更新這個比較器,比較器就會重新計算一次自己該輸出的能量以判斷是否應該更新自己的狀態,於是就會計算這個界伏盒的輸出,然後就拋異常了!這個界伏盒加上這個比較器,就構成了一個沒有狀態、不需要重設的更新抑制器。
製作
為了實現方塊實體替換,我們要找到合適的帶有方塊實體的方塊,它被破壞的時候,在刪除自己的方塊實體之前會發出一次更新,方便我們用別的更新抑制方法打斷邏輯,跳過刪除方塊實體這一步。同時,為了界伏盒可以發出CCE,我們需要換上去的方塊實體不能有物品欄。講台(1.14及以上)和唱片機(1.11-1.13)可以滿足我們的要求。
當講台上面的書被翻頁的時候,會發出一個2gt長的紅石訊號,這個時候講台處於啟動狀態。當啟動狀態的講台被破壞的時候,會更新自己下方的毗鄰。
我們翻書的時候,下面的動力鐵軌亮起,觸發了更新抑制。這是早於講台啟動狀態解除的計劃刻被計劃的,那麼這個計劃刻就不再有了,講台變成了一個常亮的狀態,這個時候我們等抑制器復位,然後直接拆掉講台就可以了。這種方法適合1.18以下的版本。因為此時棧溢出更新抑制仍然適用,我們可以承擔一次額外的更新抑制。
在1.15和1.18之間的某個版本
1.18中直接拆掉對著更新抑制器的浮空比較器邊上的有書的講台也可以
現在,我們在保留方塊實體地拆掉講台之後,在那個位置放一個界伏盒上去,就可以得到一個有講台方塊實體的界伏盒了。這就是我們的強轉抑制器的核心,更新一個從它這裡取輸出的比較器,就會觸發基於CCE的更新抑制。
應用
當物品被放進投擲器,投擲器物品欄發生變化,發出比較器更新,抑制器中的那個比較器重新計算自己的能量,更新抑制觸發。我們就完成了一次物品分身。連續這樣操作,我們就可以以極為快速的方式製作物品分身,這是目前已知的最好的物品分身製作的方法。
強轉抑制器是無狀態的,更新到比較器就拋異常,但是這也不絕對。異常的觸發是在計算界伏盒輸出的時候發生的,那麼如果比較器受到更新可以不計算這個輸出,就不會拋出異常了。我們可以對比較器後面的紅石導體充能到15訊號強度,這樣的話,比較器看到15訊號強度就不再會檢測容器,就不會拋異常了,強轉抑制器就被關閉了。
如圖所示,燈亮,抑制器啟動;燈滅,抑制器關閉。另外,強轉抑制器的工作是需要用比較器從界伏盒取輸出的,所以說如果把比較器拆了,只有界伏盒在那裡,也是安全的,不會觸發更新抑制。
棧溢出更新抑制
棧溢出(Stack Overflow)更新抑制是透過填滿棧,讓遊戲拋出棧溢出異常的更新抑制方式。
原理
這種更新抑制器會在一個遊戲刻中引起足夠的方塊更新來導致棧溢出,此時遊戲會拋出棧溢出異常。如果更新是由玩家直接引起的,則不會使遊戲崩潰,並成功更新抑制。但如果透過其他方式完成,它將使遊戲崩潰。
極簡更新抑制器
該更新抑制/跳略器最初起源於一個Discord上的截圖。
在木地板門上要放置紅石線。
使用這個機器前建議打開遊戲聲音。使用機器需要先打開地板門,之後敲擊音階盒B。若敲擊音階盒時機器未發出地板門聲,則可關閉地板門,進行更新抑制。
歷史
在22w11a中,更新的儲存從棧變更為隊列了,更新順序不再顛倒,因此棧溢出更新抑制被修復,這在MC-249082中被認為是按預期工作。然而,這個更新已在22w12a中修復,並在一個單獨但相關的錯誤報告MC-249181中說這個「錯誤」已經在這個快照中修復了,取而代之的是更新跳略。我們現在常使用記憶體溢出更新抑制或強轉抑制的方法進行更新抑制。
影片
參見
參考
- ↑ BV1zu411p7vy(00:31)
- ↑ 部分影片中兩個內容都有講解
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||