⚡ Движок производительности и ограничения очередей
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 чар) |
| Журналирование | Статические 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 блоков за один такт вызвало бы зависание сервера с задержкой 1000+ мс.
Благодаря распределению обновлений без блокировок по 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$ точек.
- Оптимизация проверки обуви: При наступлении на пашню
GrowthHelper.hasSoftStep()сначала проверяет наличие ботинок. Если слот пуст, тяжелые проверки NBT-тегов не выполняются. - Выход при максимальной зрелости: При ускоренном росте цикл прерывается в момент достижения максимального возраста, экономя операции записи блоков.
💾 Гарантии нулевой записи на диск
- Чтение без изменения чанков: Сканирование поверхности выполняется в режиме только чтения и не вызывает
setBlockState(), сохраняя флагunsaved == false. - Точечная запись блоков: В
ContinuumManager.processCropUpdateзаписьlevel.setBlock()вызывается только при реальном приросте стадии $\Delta \text{age} > 0$. - Защита диска от записи: Нетронутые чанки сохраняют статус
unsaved == false, поэтому ванильныйsave()полностью пропускает сериализацию NBT и запись на диск ($0\text{ дисковых I/O}$).
See also: Континуум (Офлайн-рост), Гидродинамика и ирригация, and Архитектура и миксины.
