
BetterAutoSave
BetterAutoSave - серверный мод для Forge 1.20.1 и NeoForge 1.21.1, который выносит автосохранение чанков, сущностей и SavedData в фоновые потоки. Убирает лаг-спайки от автосейва и телепортов.
BetterAutoSave (BAS) - серверный мод для Майнкрафт, который убирает лаг-спайки от автосохранения мира. Весь смысл в том, что сериализация и запись на диск уезжают в фоновые потоки, а основной поток сервера занимается только снапшотом данных.
Какую проблему решает BetterAutoSave
Ванильный сервер Minecraft автосейвится каждые 5 минут. И в этот момент главный поток обязан сериализовать все изменённые чанки и записать их на диск - сервер буквально замирает. На пустом сервере ты этого не заметишь. А вот на сервере с кучей модов и игроков пауза легко тянется от 200 мс до нескольких секунд, и лагают все сразу.
Но периодический автосейв - не единственный источник фризов. То же самое происходит:
- при телепортах игроков и выгрузке больших областей чанков (чанк обязан сохраниться до того, как уйдёт из памяти)
- в местах, забитых сущностями - большие фермы, моб-грайндеры
- при сохранении глобальных данных вроде деревень и рейдов (ванильный SavedData), где один крупный файл бьёт по диску
BetterAutoSave решает это так: главный поток делает только то, что обязано случиться на месте - снимает независимый снапшот данных. Сериализация и ввод-вывод уходят в фоновые потоки. Фон работает с копиями, поэтому основному потоку не мешает: тот отпускает данные сразу после снапшота.
Через этот пайплайн проходят чанки, сущности и saved data. Когда серверу тяжело, BAS сам сбрасывает скорость, но форсирует полную перед следующим циклом автосейва, чтобы очередь никогда не накапливалась.
Требования и установка
Обе ветки собираются из одного исходника. Мод серверный на обоих загрузчиках, клиенту ставить не нужно.
- Forge 1.20.1: Forge 47.3.22 или новее (линии 47.3 и 47.4 обе рабочие), Java 17+
- NeoForge 1.21.1: ветка NeoForge 21.1, Java 21+
Скачай jar под свой загрузчик и закинь в папку mods/ на сервере:
- Для Forge бери jar с суффиксом
-all(имя вродеshinoyuki_betterautosave-<версия>-all.jar) - в нём уже лежат MixinExtras и прочие зависимости. Тонкий jar без зависимостей крашится при загрузке. - Для NeoForge - файл
shinoyuki_betterautosave-neoforge-<версия>.jar.
После первого запуска конфиг создаётся по пути config/Shinoyuki-Optimize/shinoyuki_betterautosave/common.toml. Дефолты рабочие из коробки, большинству серверов менять ничего не нужно.
Совет из практики: если сервер только переезжает на 1.21.1, ставь NeoForge-сборку и не тащи туда Forge-конфиг - набор настроек у них разный, автоподхвата не будет.
Потеряются ли данные мира
Нет. BAS проектировался с одним принципом: он не должен быть менее безопасным, чем ванильный Minecraft.
- При выключении мод ждёт, пока каждый незавершённый сейв долетит до диска, и только потом даёт серверу выйти. Финальное сохранение идёт через ванильный синхронный путь.
- BAS никогда не "откладывает сейвы на потом" - чанк уходит в фоновую обработку в тот момент, когда ему положено сохраниться. Нет окна в стиле "ничего не сохранялось минутами, краш - и всё пропало" (у некоторых похожих модов такая беда есть).
- Если фоновая запись падает, мод ретраит её автоматически и не делает вид, что всё ок. Чанки и saved data откатываются на ванильную синхронную запись после исчерпания ретраев. У сущностей очереди восстановления нет: ванилла их уже выгрузила из памяти, поэтому исчерпанный ретрай логирует ERROR и теряет свежий инкремент сущностей этого чанка - ровно тот же исход, что и в ванилле (там у сохранения сущностей тоже нет ни ретраев, ни синхронного фолбэка, BAS лишь пробует на пару раз больше).
Помимо этого, Forge-сборка чинит три ванильных пути, которые молча теряют данные: сбой чтения данных игрока, обрезающие записи в advancements и статистику, а также level.dat, у которого есть лишь один бэкап. Эти фиксы включены по умолчанию.
Основные настройки
| Ключ | По умолчанию | Что делает |
|---|---|---|
general.enabled | true | Главный выключатель; off - ванильное поведение, будто мода нет |
throttle.chunksPerTickBase | 4 | Максимум чанков, которые главный поток снапшотит за тик |
throttle.adaptiveEnabled | true | Автоматически сбавлять обороты при перегрузке; лучше не трогать |
workers.chunkWorkerThreads | 2 | Фоновые потоки под чанки |
workers.entityWorkerThreads | 2 | Фоновые потоки под сущности |
workers.savedDataWorkerThreads | 1 | Фоновые потоки под saved data; подними до 2, если моды активно пишут ванильный SavedData |
compat.eventCompatMode | PARTIAL | Уровень совместимости событий; не меняй, если не уверен |
У Forge-сборки 43 настройки, у NeoForge - 26. Каждая опция, причина дефолта и рекомендованный путь внедрения расписаны в CONFIGURATION.en.md - там про защиту данных игрока, целостность level.dat, async-загрузку чанков, мониторинг через Prometheus и работу с бэкап-инструментами.
Различия между сборками
Сборки не идентичны. Часть дыр появилась потому, что NeoForge починил проблему на своей стороне, и опция там просто не нужна. Что-то сделано сначала для Forge и ещё не перенесено симметрично.
| Фича | Forge 1.20.1 | NeoForge 1.21.1 |
|---|---|---|
| Асинхронный сейв (чанки / сущности / SavedData) | да | да |
Асинхронная загрузка чанков (секция [load]) | да | нет (секции нет, load-side миксинов в NeoForge-сборке вообще нет) |
| Кэш реестра level.dat | да | не нужен (в 1.21 таблицу вынесли из level.dat) |
| Проверка level.dat на старте | да | не нужна (1.21 и так откатывается и карантинит при сбое чтения) |
| Бэкап level.dat на старте / верификация после записи | да | нет (в 1.21 аналога тоже нет; порт в очереди) |
| Фолбэк чтения playerdata | да | не нужен (пофикшено в 1.21) |
| Атомарная запись advancements / stats | да | нет (1.21 всё ещё обрезает при записи; порт в очереди) |
| Пропуск чистых advancements, разнесённое сохранение игроков | да | нет (только производительность; порт в очереди) |
| Диагностика синхронных загрузок / пауз между тиками | да | да |
Команды в игре
Нужны права оператора (уровень 2).
| Команда | Действие |
|---|---|
/betterautosave status | Статус одной строкой |
/betterautosave metrics | Сводка метрик одной строкой |
/betterautosave debug | Полная диагностика: глубина очередей, тайминги по стадиям, счётчики |
/betterautosave flush | Слить все незавершённые сейвы на диск. Команда возвращается сразу и опрашивает фон, пока не завершит или не выйдет по таймауту (safety.shutdownTimeoutSeconds) |
/betterautosave drain-unload | Дождаться, пока все зависшие чанки долетят; так же опрашивает в фоне и отвечает сразу |
/betterautosave hottest-chunks [count] | Список самых медленных на сохранение чанков (по умолчанию 10, от 1 до 50), чтобы найти хотспоты |
/betterautosave force-async | Форсировать один фоновый проход сейва по всем чанкам текущего измерения (диагностика) |
/betterautosave diagnose [count] | Список источников синхронной загрузки чанков на главном потоке и статистика пауз между тиками (по умолчанию 10, от 1 до 50) |
/betterautosave diagnose reset | Очистить обе таблицы выше (кумулятивные счётчики сохраняются) |
Дорогие по стоимости чанки обычно там, где плотно стоят block entities: крупные автоматические фермы, панели модовых магазинов, навороченный редстоун.
Паузы, которых не видит обычный мониторинг
Два вида стопоров вообще не отражаются на обычном дашборде. С версии 0.20.0 BAS фиксирует оба сам - только наблюдает, никогда не вмешивается, включено по умолчанию.
Синхронная загрузка чанков на главном потоке. Когда чанка нет в памяти, а что-то на главном потоке просит его напрямую, главный поток ждёт на месте, пока не закончится чтение с диска, а при необходимости - и генерация мира. Сервер всё это время заморожен. На одном продакшн-стресс-тесте с 74 игроками замерено одиночное ожидание в 5.2 секунды. BAS пишет каждое ожидание дольше 50 мс (порог настраивается): сколько блокировало, координаты чанка, измерение и первый не-ванильный класс в стеке вызовов.
Долгие паузы между тиками. MSPT меряет только время внутри игрового тика, а ожидание между двумя тиками не считается. На том же стресс-тесте были паузы 17.1 и 14.8 секунды, невидимые ни на графике TPS, ни на дашборде - всё выглядело здоровым, пока игроки отваливались по таймауту. BAS берёт по одной метке времени в начале и в конце каждого тика и записывает любой разрыв больше 1 секунды (настраивается). Опциональный глубокий режим (по умолчанию выкл.) приписывает разрыв конкретной задаче, которая его вызвала.
Цена: проба синхронной загрузки живёт на ветке после промаха ванильного четырёхслотового кэша чанков, то есть на кэш-хите вообще не достигается. На промахе она добавляет лишь два наносекундных чтения, а стек снимается только когда ожидание превысило порог - в обычной работе никогда. Проверка разрыва тиков - два наносекундных чтения за тик.
Про атрибуцию: детектор сообщает, на какой цепочке вызовов случился блок, а не кто виноват. Обычно такие стопоры отражают паттерн вызовов другого мода. Синхронно запросить чанк во многих ситуациях абсолютно нормально, а его цена просто масштабируется от размера сервера, дальности прорисовки и скорости диска. Так что это не доказательство бага в том моде. Считай это началом расследования, а не его итогом.
Смотри всё через /betterautosave diagnose или снимай четыре новых Prometheus-метрики (bas_sync_load_stalls_total, bas_tick_gap_max_seconds и ещё две). Восемь настроек и полный пример вывода команды - в секции 8 CONFIGURATION.en.md.
Конфликты и совместимость
- Нельзя ставить вместе (все перехватывают один и тот же путь сохранения): Fast Async World Save (
fastasyncworldsave, BAS пишет WARN, когда его находит), Smooth Chunk Save и прочие async / per-tick сейв-моды. - C2ME / C2ME-Forge: разводи по фичам. Сторона сохранения - только один из двух. Параллельная загрузка совместима с дефолтным конфигом BAS, но становится либо-либо, если включить async-загрузку BAS. Генерация мира совместима всегда.
- Совместимы: Starlight, Radium / Canary, Modernfix, FerriteCore и подобные.
Важный нюанс: мод заточен на максимальную сохранность данных, поэтому часть агрессивных оптимизаций он сознательно не делает. Если хочется выжать побольше и не жалко совместимости - это уже про C2ME, а не про BAS. Кстати, релиз 0.20.1 починил краш при старте рядом с Lithium-подобными модами (Radium, Canary, Harium), так что на старых 0.20.x с ними лучше не запускаться.
Правила настройки под свой сервер
Простой откат, если что-то пошло не так. Все три варианта сохраняют данные мира целыми:
- Отключить временно: поставь
general.enabledвfalse, перезапусти или сделай/reload. Мод остаётся установленным, но вся логика пропускается - чистый ванильный Minecraft. - Удалить полностью: убери jar из
mods/и перезапусти. Данные мира защищены ванильным сохранением, при удалении ничего не теряется. - Настроить вместо удаления: если подозреваешь настройку производительности, сначала крути
chunksPerTickBase(1-64) или переключиeventCompatModeнаFULL- сносить мод не нужно.
Сборка и разработка
./gradlew build # компиляция + все тесты (common / forge / neoforge)
./gradlew :forge:runServer # запуск дев-сервера Forge 1.20.1
./gradlew :neoforge:runServer # запуск дев-сервера NeoForge 1.21.1
Структура модулей: common/ (чистое ядро без Minecraft, source-merged в оба загрузчика - главная стейт-машина сохранения живёт здесь одна, без форков) + forge/ (1.20.1) + neoforge/ (1.21.1). Версии и обзор возможностей - в ROADMAP.md, детали порта на две версии - в archive/MULTIVERSION_PLAN.md.
Лицензия
AGPL-3.0-or-later с двумя дополнениями к секции 7 (LICENSE-EXCEPTION.md): исключение на распространение в сборках модов - неизменённые официальные релизные jar можно включать дословно в модпаки и серверные сборки, обязуясь лишь сохранить имя проекта и ссылку на репозиторий - плюс исключение на линковку с Minecraft, явно разрешающее сочетание с самой игрой и LGPL-загрузчиками модов. Изменённые версии мода остаются под полной AGPL, включая сетевые условия секции 13.
Стоит ли ставить BetterAutoSave
Если у тебя Forge 1.20.1 или NeoForge 1.21.1 сервер с модами и хотя бы десятком игроков - по факту must-have. Это один из немногих модов оптимизации, где во главу угла поставлена сохранность данных, а не голые цифры FPS. Ты получаешь асинхронный автосейв, диagnostiku тех пауз, которые раньше были невидимы, и экспорт метрик в Prometheus для нормального мониторинга. Скачать BetterAutoSave можно под нужный загрузчик - и забыть про лаг-спайки от автосейва, телепортов и выгрузки областей.
Как поиграть с друзьями с модом BetterAutoSave?
Мод BetterAutoSave куда интереснее в компании: поднимите сервер Майнкрафт с уже установленным модом, позовите друзей и играйте по своим правилам. Хостинг Майнкрафт для мода BetterAutoSave будет готов за пару минут - BungeeHost сделает всё за вас.
