
BetterAutoSave
BetterAutoSave - серверный мод для Forge 1.20.1 и NeoForge 1.21.1, который выносит автосохранение чанков, сущностей и SavedData в фоновые потоки. Убирает лаг-спайки от автосейва и телепортов.
Shinoyuki-BetterAutoSave 0.13.0-beta.1
Список изменений
v0.13.0-beta.1 — Async chunk load (experimental, off by default)
This beta adds async chunk loading — moving the deserialization of a chunk from its on-disk bytes back into game objects off the main thread. It is the load-side counterpart to the existing async save. The feature is off by default and opt-in, and is still in public testing; this beta ships a Forge 1.20.1 build only (the NeoForge 1.21.1 port comes later). Back up your entire world folder before enabling it
What it does
- Vanilla deserializes a loading chunk's on-disk bytes into game objects (
ChunkSerializer.read) on the main thread; with a high view-distance and players moving or teleporting fast, this becomes a main-thread burden - When enabled, the pure deserialization runs on a background load worker; the main thread keeps only what must run there: POI consistency, light sections, and
ChunkDataEvent.Loadreplay - The real payoff is on production servers (view-distance 10-12 + many players): the freed main-thread time becomes TPS headroom, smoother loading, room for more players
- It is not a flight-speed silver bullet: single-player flying at max view-distance is bound by vanilla's single-threaded chunk pipeline, which off-thread deserialization cannot help — that part cannot be parallelized without breaking mod compatibility
What it does not touch
- This optimizes the disk serialization boundary of existing chunks (read from disk, written to disk), not worldgen. Generating never-before-seen terrain is untouched: brand-new chunks never pass through
ChunkSerializer.read, so async load only kicks in for chunks that were previously generated and saved
Configuration ([load] section, off by default)
load.enabled(default false): master switch for async loading, independent of the save-sidegeneral.enabledload.loadEventCompatMode(default PARTIAL): PARTIAL = deserialize on a worker, POI/light/event back on the main thread; FULL = the entire read stays on the main thread (equivalent to the feature being off, zero behavior delta — a per-config fallback if a mod misbehaves)load.maxInFlight(default 128): cap on deserializations submitted to workers concurrently, so a batch finishing at once cannot land all its main-thread replay in a single tick; raise per server until a burst reappearsload.loadMaxRetries(default 1): worker-thread re-attempts after a parse throws, before falling back to a vanilla main-thread readworkers.loadWorkerThreads(default 2): load worker count; deserialization is largely single-thread bound, 2 covers typical loads
Safety and compatibility
- Data safety: if an off-thread parse fails, the same bytes are re-read on the main thread as a fallback — no data is lost in any case
- One-flag kill switch:
loadEventCompatMode=FULLorload.enabled=falsereturns to vanilla load behavior instantly; config hot-reloads, no restart needed - Mixin compatibility: every chunk-read injection point uses
@WrapOperation, coexisting with mods (e.g. architectury) that touch the same instructions rather than claiming them exclusively - Pick one against other mods that also load chunks off-thread (C2ME-Forge); all other mods are orthogonal and do not conflict
Why it is a beta
- Verified on a real 138-mod heavyweight pack (Create / MTR / immersive vehicles and other block-entity-dense content): with async loading on, zero worker errors, zero degrade, zero data-loss signals
- But "repeated save/reload in dense areas" and "concurrent multiplayer" are not yet exhaustively verified, hence off by default and marked pre-release — back up first, roll out to a small group, and report issues
Upgrading
Drop-in jar replacement; async loading stays off and does not change existing save behavior. To try the new feature, set load.enabled to true — and back up your world first
