Minimal Backup 0.1.0 for Minecraft 1.21.1 (fabric)
Curse Maven Snippet
What's new
Changelog
All notable changes to this project are documented here. The format follows Keep a Changelog, and versions follow Semantic Versioning.
[0.1.0] - 2026-10-22
Initial release. Targets 1.20.1 Forge/Fabric and 1.21.1 NeoForge/Fabric.
Added
- Per-target
.zpackvaults: append-only block chains with a FULL first block, zstd dictionary deltas for later blocks, optional keyframes, tombstones, retention, per-file compaction and startup self-healing. - Write capture for chunks,
SavedData, player data andlevel.dat; read capture plus write-time COW for the first value of a target; optionalbackup.fullBaselineimport. - Sparse-read restore: only keys covered by the snapshot are served, everything else passes through to disk; crash marker, pre-restore checkpoint and optional
restore.forceDirty. - Dedicated-server in-process instance replacement on all four nodes: connection hold with an 8-second heartbeat and discard listener, replacement server in the same JVM on the same port, ready packet and automatic reconnect for modded clients. Integrated servers hold the local connection the same way while the old server stops, then the client closes it quietly and reopens the world, so no "connection lost" screen is shown.
- Optional JSON archiving (
backup.copyJson, default off) for world-level*/*.json(advancements, stats) as whole-file zstd copies without diff; the first snapshot also archivesicon.pngat the vault root. Neither participates in the NBT delta chain or restore. /backupcommands:create,list,status,reload,restore(withconfirm),disarm,delete,rename,verify,gc(withconfirm),baseline(withconfirm) andui.- Optional UILib time tree on all four nodes (UILib 0.3.6 + Architectury 9.2.14 on 1.20.1, UILib 9.0.0 + Architectury 13.0.6 on 1.21.1) with create/rename/verify/delete/restore/GC actions. The vanilla list screen was removed; the tree's Config button edits the
ui.*options, and the screen talks to the server throughUiBridge. Below permission level 2 the tree is read-only (list/status); create/restore/rename/delete/verify are disabled in the client and rejected by the server. An unbound-by-default key binding creates a snapshot with the default timestamp title without opening the tree. - Offline CLI:
list,rollback(rebuildsregion/,entities/,poi/and custom-dimension.mcafiles from per-chunk blocks),compactandheal. - Stable codec API:
engine/api/CodecProvider(codecId,compressFull,compressDelta,decompress) plusCodecRegistry; the built-in provider iszstd/1. - Shared
ConfigSchemafor all four loaders: triggers, retention, zstd level/long mode, keyframe interval,captureOnRead,fullBaseline,copyJson,verifyAfterWriteand restore options. - Benchmark harness (
bench/codec-bench.sh) and real chunk/file fixtures underbench/fixtures; modded fixtures underbench/fixtures-modded.
Changed
- Checkpoints skip no-op writes: a non-ABSENT entry whose aligned bytes equal the previous visible block appends no block, and a repeated ABSENT entry appends no tombstone. The previous block stays the target's head, so the new snapshot resolves to the same value.
- The
.zpackindex cache stores only each block header's offset (first absolute, then varint deltas, about 2 B per block). A missing or corrupt cache falls back to a sequential scan. - NBT payloads are canonicalised before hashing and storage: compound keys are sorted, palette containers are lifted only when the round trip is byte-exact, and delta targets are aligned to the previous stored version.
Timelinestampscanon=nbt1; old vaults without the field still load. - 1.20.1
level.datcapture now records the old tag at HEAD and reads the written file back at RETURN, preserving Forge'sfmlsubtree and any other root tags added by mods. - Player-data write capture is present on all four nodes.
- The codec addon surface is the four-method
CodecProviderAPI, registered throughCodecRegistry, instead of overwriting core methods with mixins. The prototype addons are no longer part of this repository and are archived outside it. - Test scripts are consolidated under
tests/; the engine suite remains./build.sh. - Loader-identical sources moved to the shared
src/maintree:FriendlyCodecand theIOWorkerMixin,RegionFileStorageAccessandRegionFileStorageMixincapture mixins. Duplicated vault walks, chunk packing, world-key validation and command identity formatting now reuse the existing helpers. - License: LGPL-3.0-only.
LICENSEcontains the LGPLv3 text andLICENSE.GPL-3.0contains the GPLv3 text it incorporates. - Default zstd compression level is now 9 (was 3).
- Engine settings are an immutable
EngineSettingsvalue built byConfigValuesand passed intoCheckpoint,BlockFile.appendandCodec.compressDelta; the engine keeps no static defaults or setters.CodecProvidergained a default six-argumentcompressDeltaoverload for long-mode hints, so existing four-method providers keep working. Checkpoint.SnapshotInfo.sourceno longer defaults tomanual; callers that need that label pass it explicitly (asBackupServicealready did).- Default values live only in
ConfigSchema: the change-set buffer takes its limits from config, legacy vaults without a codec field useCodecRegistry.DEFAULT_CODEC_ID, and the client keybind falls back to the schema default instead of a second F9 literal.
Removed
- The CLI
checkpointcommand and restore support for its whole-file.mca/.mccsnapshot format. Per-chunk capture and the offlinerollbackwriter supersede it. - Unused config options
backup.nonNbtPolicy,restore.keepPlayerPositions,restore.timeoutSecondsanddebug.dumpCoverStats; none had a reader. ui.keybindand the key field in the mod config screen; the time-tree key is now rebound only through Minecraft'sOptions -> Controlsscreen, so the two paths cannot disagree.ui.animations, which was exposed in the config screen but had no behaviour.- The unimplemented
/backup list [page]argument;/backup listnow matches the command surface. - Unused internal helpers
ConfigValues.raw/snapshot/string,MinimalBackup.isInitialised/backupRoot,BackupRuntime.coverPass/worldChangedOutside,EngineSettings.codecApiVersionandTimeline.lastRollbackAt. - The
STRINGconfig value type; every remaining option is a boolean, integer or long.
Fixed
- 1.20.1 Forge and 1.21.1 Fabric never captured player-data writes because the
PlayerDataStorage.save(Player)hook was missing. - 1.20.1 snapshots lost root-level
level.datsiblings (notably Forge'sfml), which also polluted delta sizes and skipped Forge's mod-mismatch data on restore. - Forge production mixins now name the generated refmap; packaged jars include
minimalbackup.refmap.json. - Fabric loader minimums are per node, so the 1.20.1 jars no longer require a 1.21.1-era loader.
- 1.20.1 Forge clients no longer stop at
LoadingErrorScreenwhenpack.mcmetais missing. TYPE_FILEandTYPE_CHUNKblocks no longer collide at sub-target 0 (chunk(0,0)).- A successful restore now makes the restored slot the timeline head, so the next snapshot branches from it.
- Pre-restore queue draining runs before arming and outside the capture lock, avoiding the save/capture deadlock.
- Fabric config reload now marks the config loaded only after at least one value was read, matching the Forge and NeoForge spec builders.
Notes
- CurseForge publishing runs from
.github/workflows/release.ymlonv*tags; the Modrinth project id and token are still pending. - Non-NBT data is skipped by default.
backup.copyJsoncovers world-level advancements/stats only;serverconfig/,datapacks/and mod-specific stores are out of scope. - Restore is a sparse overlay: keys absent from the snapshot pass through to the current disk.
This mod has no additional files

