Skip to content

⚡ 效能最佳化與佇列節流引擎

Agrarian Reform 專為高乘載伺服器打造,即使面對超大型農業農場也不會造成瞬卡、看門狗超時或 TPS 下降。


📊 效能技術指標資訊框

PropertyValue
Global Throttling BudgetCROPS_PER_TICK = 5
Queue Implementationjava.util.concurrent.ConcurrentLinkedQueue
Sub-Chunk Palette FilterhasOnlyAir() & maybeHas(AgrarianCropRules::isCropBlock)
水分搜尋機制柴比雪夫同心環方塊掃描 ($r=1 \to \text{maxRange}$,近水源極速判定)
鞋子最佳化防抖赤足快速判斷 ($0.0001\mu\text{s}$,跳過耗時的附魔檢查)
診斷日誌機制靜態 SLF4J 記錄器,受暫態遊戲規則 agrarian_reform:debug_mode 控管

🧠 架構設計與快速略過流水線

┌─────────────────────────────────────────────────────────────┐
│                    CHUNK LOAD SCAN EVENT                    │
│ Palette Pre-Filter: section.hasOnlyAir() & maybeHas()       │
│ Rejects 85%+ empty non-crop sub-chunks in O(1) time         │
└──────────────────────────────┬──────────────────────────────┘


┌──────────────────────────────┴──────────────────────────────┐
│             ConcurrentLinkedQueue<CropUpdateTask>           │
│ Lock-free thread-safe task buffer                           │
└──────────────────────────────┬──────────────────────────────┘


┌──────────────────────────────┴──────────────────────────────┐
│                  ServerTickEvents.END_SERVER_TICK           │
│ Polls at most 5 tasks per tick                              │
│ Updates block states smoothly across consecutive game ticks │
└─────────────────────────────────────────────────────────────┘

為什麼每刻處理 5 處作物?

當玩家在離開含有 10,000 處作物的農場 24 小時後重返,若在單一刻內同時觸發 10,000 次方塊更新,將導致伺服器產生超過 1000ms 的嚴重凍結。

透過無鎖且以每刻 5 處作物的速率分散更新:

  • 區塊載入期間伺服器 TPS 依然維持在極穩定的 20 TPS
  • 10,000 處作物在後台平緩經過 2,000 刻(約 100 秒)即可全部計算完畢,完全不影響遊玩體驗。

🏎️ 核心快速略過與演算法最佳化

  1. 子區塊調色盤極速判斷:不同於逐一檢查區塊內 $98,304$ 個方塊座標,CropScanner 直接讀取子區塊調色盤。若一個 $16 \times 16 \times 16$ 子區塊不含農業方塊,整片區域將在 $0.0001\mu\text{s}$ 內直接略過。
  2. 柴比雪夫同心環由內向外掃描:耕地水分計算由最近的方形環($r = 1 \to \text{maxRange}$)逐步向外。因多數耕地緊鄰水源($r=1$),在第一層即完成判定,無須遍歷 $17 \times 17$ 格。
  3. 赤足踩踏防抖:實體接觸耕地時,GrowthHelper.hasSoftStep() 首先檢查腳部裝備是否為空。若為空,直接跳過複雜的 NBT 附魔遍歷。
  4. 最大成熟期立即中斷:在高倍率生長循環中,一旦作物達到最大成熟度,循環立刻中斷,省去無謂的方塊寫入運算。

💾 零磁碟寫入保障與髒狀態維護

  1. 唯讀區塊表面掃描:初始載入掃描 100% 為唯讀,絕不呼叫 LevelChunk.setBlockState(),確保區塊內部 unsaved 旗標維持 false
  2. 精確方塊寫入:在 ContinuumManager.processCropUpdate 中,僅在生長增量 $\Delta \text{age} > 0$ 時才呼叫 level.setBlock()
  3. 原生零磁碟寫入防護:未改動的區塊維持 unsaved == false,Minecraft 原生 ChunkMap.save() 會直接跳過 NBT 序列化與磁碟寫入($0\text{ 磁碟寫入開銷}$)。

See also: 時空連續體 (離線生長模擬), 水動力學與灌溉系統, and 架構設計與 Mixin 注入參考.

Official documentation & web portal for Dasik Igaijinn mods.