⚡ パフォーマンスとキュー調整エンジン
Agrarian Reformは高負荷サーバー向けに最適化されており、大規模なメガ農場でも瞬間的なラグやTPS低下を引き起こしません。
📊 パフォーマンスインフォボックス
| Property | Value |
|---|---|
| Global Throttling Budget | CROPS_PER_TICK = 5 |
| Queue Implementation | java.util.concurrent.ConcurrentLinkedQueue |
| Sub-Chunk Palette Filter | hasOnlyAir() & maybeHas(AgrarianCropRules::isCropBlock) |
| 水源探索アルゴリズム | チェビシェフ同心円状探索($r=1 \to \text{maxRange}$、近接水源の即時判定) |
| 履物チェック高速化 | 素足時の即時判定($0.0001\mu\text{s}$、重いNBTエンチャント確認を回避) |
| 診断ログ出力 | 一時的なGameRule agrarian_reform:debug_modeで制御される静的SLF4Jロガー |
🧠 アーキテクチャ設計と早期離脱パイプライン
┌─────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────┘なぜ1ティックあたり5作物なのか?
プレイヤーが10,000作物を植えた農場を24時間アンロードした後に再訪した際、1ティックで10,000ブロックを一度に更新すると1000ms以上のサーバーフリーズが発生します。
ロックフリーで1ティックあたり5作物に分散して処理することで:
- チャンクロード中もサーバーは安定した 20 TPS を維持できます。
- 10,000作物がバックグラウンドで2,000ティック(約100秒)かけて円滑に追いつき、ゲームプレイに支障を与えません。
🏎️ コア高速判定とアルゴリズム最適化
- サブチャンクパレットによる事前判定:チャンク内の$98,304$座標を全探索する代わりに、
CropScannerは$16 \times 16 \times 16$のパレットを直接確認します。農作物が含まれていない場合は$0.0001\mu\text{s}$で即スキップされます。 - チェビシェフ同心円状の探索:耕地の水分判定は内側の正方形リング($r = 1 \to \text{maxRange}$)から行われます。通常は隣接水源($r=1$)で即座に完了し、$17 \times 17$の全探索を防ぎます。
- 素足判定による高速化:エンティティが耕地を踏んだ際、まず足装備が空か確認します。素足の場合は時間のかかるNBTエンチャント探索を完全にスキップします。
- 最大成長時の即時終了:高倍率成長ループ時、作物が最大段階に達した瞬間にループを即座に抜け出し、不要なブロック書き込みを防ぎます。
💾 ディスク書き込みゼロ保証とダーティ状態保護
- 読み取り専用サーフェス走査:初回スキャンは完全に読み取り専用で、ブロック変更を行わないためチャンクの
unsavedフラグはfalseのまま維持されます。 - 必要な場合のみブロック更新:
ContinuumManager.processCropUpdateでは、成長段階の増分 $\Delta \text{age} > 0$ の場合のみブロック書き込みを行います。 - 無駄なディスク書き込み防止:手つかずのチャンクは
unsaved == falseを保つため、バニラの自動セーブ処理がNBT変換とディスク書き込みを安全にスキップします($0\text{ ディスクI/O}$)。
See also: コンティニュアム (オフライン成長持続), 水力学と灌漑システム, and アーキテクチャと Mixin ターゲット.
