Singleplayer-first build history for saving, comparing, branching, restoring, and recovering Minecraft projects.
Lumi is a Fabric mod for Minecraft 1.21.11.
It gives builders a project-oriented safety history for the current dimension or build area.
You can save builds, see changes, restore earlier states, try alternate branches, export/import portable history packages, review imported branches before combining them back into your build, partially restore selected regions, and recover pending edits after a crash.
Lumi's UI operations are intended for the local world owner. On dedicated servers, mutating Lumi actions require operator-level permissions; in singleplayer integrated worlds, builder edits are captured for history and live undo/redo immediately.
The normal UI uses builder terms:
Build HistorySave buildBranchesSee changesRestoreImport / ExportRecovered work
Use Lumi if you want to:
- try a redesign without losing the stable version
- check what changed since the last save
- go back to an older state without copying full save folders
- keep separate branches for alternate build directions
- recover work after a crash or bad edit
| Term | Meaning | Stored in |
|---|---|---|
Project |
Tracked area in one dimension | project.json |
Version |
Saved history node with message, stats, preview, and payload refs | versions/*.json |
Variant |
Named branch-like head pointer | variants.json |
History tombstones |
Soft-deleted save and branch ids hidden from normal history | history-tombstones.json |
Compare |
Diff between two saved states, or between a saved state and the live game state | DiffService |
Restore |
Apply a chosen version back into the map and move the active head to it | RestoreService |
Partial restore |
Apply a bounded restore from an older save as a new save on the active branch, either inside a selection or everywhere except it | RestoreService |
Import / Export |
Portable branch or project history packages for review and combine workflows | HistoryShareService, ProjectArchiveService |
Recovery |
Crash-safe draft storage | recovery/draft.* |
- automatic dimension projects
- builder-first Build History UI built around
Save build,See changes, recent saves, andBranches, with maintenance tools kept in the sidebarMoreroute - one-time interactive onboarding wizard that explains safe save, undo/redo, restore, branch, compare, recovery, and import/export workflows, shows remapped shortcuts as pixel key icons, continues over the Lumi workspace after the open shortcut, and can be replayed from
Moreor/lumi-onboarding - localized UI resources for English, Russian, French, Spanish, German, and Finnish
- lightweight save, branch, import/export, settings, storage cleanup, and advanced navigation with a persistent left workspace menu and live background-operation refresh while screens stay open
- patch-first history with checkpoint snapshots
- remappable quick-save chord, default
Left Alt+S, that opens a standalone save-name dialog without entering Build History - dedicated save screen with optional
Replace latest save - save details screen with isometric preview, restore, see-changes, rename, soft-delete, and branch actions
- See Changes screen for saved states, branches, and the current build, with manual raw-reference compare available under
More - live undo and redo for the last tracked builder actions with default
Left Alt+Z/Left Alt+Ybindings through the remappable Lumi action button; changing the action button changes these chords too. WorldEdit and FAWE actions route those chords through the tools' native undo/redo commands, while captured Axiom capability actions replay through Lumi so tool-assisted breaks and placements use the state Lumi recorded. - short-lived secondary fallout near the latest tracked action is folded into that same undo/redo step when it settles right after the edit; undo/redo drains already-dirty stabilization chunks first so poured fluid, contact-created source blocks, and falling-block deltas from whole-dimension sessions can join before the action is selected, and this passive fallout does not discard an available redo
- item drops produced by explosions, fluid, falling blocks, or nearby block-update fallout are captured only for the matching undo/redo action; undo removes those dropped item entities and redo respawns them without storing them in recovery drafts or saved versions
- undo/redo replays stored block states without immediate redstone neighbor updates or placement physics, so restored TNT beside powered redstone is visible but not auto-primed by the replay
- runtime-only redstone state flips and piston animation blocks are ignored so active mechanisms do not pollute pending history or the recent action overlay
- hard restore that moves the active branch head
- region-scoped partial restore from save details as a primary save action, written back as a new
PARTIAL_RESTOREsave, withOnly selected areaandEverything except selectionmodes using optional wooden-sword selected bounds or manual XYZ bounds. The applied partial restore is also recorded as a live undo/redo action. - runtime-only wooden-sword region selection with
cornersandextendmodes, long loaded-chunk targeting, Lumi action button + scroll mode switching, Lumi action button + right click deselect, and an in-world highlighted cuboid overlay - history editing: rename saves, soft-delete safe saves, soft-delete inactive branches, and merge another local branch into the current branch as a new
MERGEsave - soft-deleted save files remain accessible from the More screen's deleted saves section
- recovery drafts with WAL compaction and a direct recovery screen prompt only when a project opens with interrupted persisted draft work from a previous session
- optional
AUTO_CHECKPOINTsaves before large vanilla/fillor/clonecommands, WorldEdit sessions, and Axiom block-buffer edits when a pending draft exists; the setting is off by default - client-rendered textured isometric preview images auto-framed from changed blocks with safe context padding
- material delta summaries and integrity checks under focused details and support screens
- zip import/export from the workspace sidebar, including branch-scoped packages in the game-root
lumi-projectsfolder with optional previews - imported review projects with deletion, cached combine review, and same-area overlays for shared branches
- optional WorldEdit edit-session capture when WorldEdit is present, without a hard runtime dependency
- conservative external builder-tool capture for WorldEdit, FAWE-style chunk placement, Axiom block buffers, Axion, AutoBuild, SimpleBuilding, Effortless Building, Litematica/Tweakeroo placement paths, and known tool stacks that reach Minecraft block or entity mutation paths
- conservative cleanup for orphaned snapshots, previews, cache files, and stale operation drafts
- capture of player edits plus builder-relevant entity spawn/remove/update and supported explosion edits, including TNT damage tied back to the action that primed it
- temporary action-button preview for the latest 10 undo actions, or redo actions while the Lumi action button plus redo is held, with translucent exposed sides for small edits and merged volume blobs for dense edits when compare highlight is not active
- A mixin, guarded external-tool adapter, known-tool stack fallback, direct section fallback, or entity lifecycle/update hook catches a block or entity change.
HistoryCaptureManagerfinds matching projects.- Explicit builder-driven sources can bootstrap a dimension project on demand, but ambient world-settling sources do not.
WorldMutationCapturePolicydrops piston animation sources, transient piston blocks, and runtime-only redstone state flips before they can enter drafts or live undo/redo.EntityMutationCapturePolicyrejects non-entity-history sources before Lumi asks Minecraft to serialize entity NBT, so transient falling-block or mob internals cannot crash capture.- Whole-dimension sessions keep a causal chunk envelope rooted in explicit builder edits. The root chunk defines a one-chunk halo envelope, and Lumi captures per-chunk baselines lazily when a chunk inside that envelope first needs stabilization.
- Ambient fallout such as fluid spread and falling blocks no longer append directly into the live draft for whole-dimension workspaces. They only re-mark chunks inside that causal envelope as dirty.
- Related item drops from explosions, water flow, falling blocks, and block-update fallout are attached to the latest nearby undo/redo action only; they are deliberately excluded from recovery drafts and saved versions.
TrackedChangeBuffermerges explicit and targeted realtime block changes by position and entity changes by UUID immediately.- First-touch whole-dimension baseline capture copies compact chunk section payloads on the server thread and writes the compressed baseline file later on a dedicated low-priority capture-maintenance executor.
- Before draft snapshots, idle flushes, save, amend, undo/redo selection, or freeze persist or consume anything, Lumi reconciles dirty envelope chunks on the server thread against the current world and stores the final stabilized diff on top of the live pending chunk buffer.
- Recovery draft data flushes on an interval, but the WAL append and compaction run asynchronously on that same capture-maintenance executor.
VersionServiceconsumes the active draft.- Patch payloads are prepared off-thread.
- Metadata is written after payload files exist.
- Amend-on-head preserves block and entity diffs from the replaced head.
- Preview generation queues a lightweight request in project storage.
- The client later fulfills that request with a textured isometric off-screen render and updates the version metadata.
HistoryEditServiceowns save rename, save soft-delete, and branch soft-delete rules.- Soft delete writes tombstones only; version manifests, patches, snapshots, previews, and baseline files stay on disk.
- Deleting a branch head save moves that branch metadata back to the parent before hiding the save, while root, ambiguous multi-head, and non-leaf deletes are blocked.
- Local branch merge compares the source branch against the current active branch, applies the resolved changes through
WorldOperationManager, and writes a newMERGEsave on the active branch. The source branch is unchanged.
- Active capture is frozen first.
- Lumi shows confirmation for initial/root restores with a lightweight restore-plan summary.
- Lumi tries direct patch replay first, including same-lineage rollback/replay and divergent branch transitions through a shared saved ancestor.
WORLD_ROOTfallback uses tracked baseline chunks when direct replay is not valid.- Snapshot fallback is used for normal versions when direct replay is not valid.
- Tick-thread apply uses bounded chunk batches with pre-decoded block states, dense safe section rewrites or native section loops when available, direct loaded-section commits for sparse changes, and prepared entity batches.
- Restore replay completes paired block halves such as beds, doors, and tall plants before apply.
- A full restore moves the active branch head to the restored version after apply completes; when a Lumi selection exists, the confirmation also offers
Only selected areaandEverything except selection. - Partial restore writes a new save on the active branch and records the applied change in the live undo/redo stack. The form can consume the current Lumi wooden-sword selection and marks that request as
LUMI_REGION.
- JSON parsing, LZ4 decompression, and block-state decoding stay off the tick-thread apply path.
- Recovery WAL writes, WAL compaction, and baseline chunk compression stay off the server-tick capture path.
- Snapshot capture copies compact loaded-chunk payloads, including entity snapshots, on the server thread, then writes them asynchronously through storage.
- Storage repositories read and write payloads; Minecraft-layer preparers build tick-ready apply batches.
- Large WorldEdit/Axiom edits avoid block-entity NBT serialization for ordinary blocks, and capture project matching uses a cached dimension/chunk index.
Only selected areapartial restore can seek directly to selected chunks in new patch payloads instead of decoding the whole patch file.Everything except selectionplans the same restore path but filters out selected blocks after loading the relevant changes.- Auto checkpoints save any existing pending draft before large external edits; if no draft exists, the current branch head is already the checkpoint and Lumi does nothing.
- Restore apply uses adaptive tick budgets, safe dense section rewrites, native or direct section writes with vanilla fallback, batched section packets, capped block-entity/entity tail work per tick, and progress for entity-only batches.
- One map operation is expected at a time per save.
- Progress is exposed through operation state. The in-world action bar uses short status text and only shows a compact ASCII progress bar for larger active operations.
- Lumi screens do not pause the game.
- Detached old versions stay on disk for safety and remain visible in Build History after a reset-style restore; tombstoned saves and branches stay on disk but are hidden from normal UI and lineage.
| Layer | Responsibility | Main types |
|---|---|---|
| Bootstrap | Fabric wiring, diagnostic commands, ticking, flushes | LumaMod |
| Domain model | persisted records and runtime state | BuildProject, ProjectVersion, TrackedChangeBuffer |
| Domain service | product logic | VersionService, RestoreService, HistoryEditService, HistoryShareService, VariantMergeService |
| Minecraft adapter | game hooks and map mutation | HistoryCaptureManager, WorldOperationManager, BlockChangeApplier, WorldMutationCapturePolicy |
| Storage | file layout and payload I/O | ProjectLayout, repositories in storage/repository |
| Client UI | owo-ui screens, controllers, HUD, overlays, view state | ScreenRouter, ProjectScreen, SaveScreen, ShareScreen, WorkspaceHudCoordinator |
Rules:
- domain services own product logic
- Minecraft adapters touch game APIs
- repositories handle files and payloads
- UI controllers stay thin
Project data lives under:
<save>/lumi/projects/<project>.mbp/
Main files:
project.jsonvariants.jsonversions/*.jsonpatches/*.meta.jsonpatches/*.bin.lz4snapshots/*.bin.lz4previews/*.pngpreview-requests/*.jsonrecovery/draft.bin.lz4recovery/draft.wal.lz4recovery/journal.json
Runtime test reports from /lumi testing singleplayer are written under:
<save>/lumi/test-logs/
History archives and share packages are written under:
<game>/lumi-projects/
See docs/storage-format.md for the full format.
- Minecraft
1.21.11 - Fabric Loader
0.19.2 - Java
21 - Fabric API
0.141.3+1.21.11
Main libraries:
cloth-configowo-liblz4-java
The client menus are implemented with owo-ui. Lumi depends on owo-lib for Fabric 1.21.11.
Build output is one mod jar.
.\gradlew.bat buildRun client:
.\gradlew.bat runClientDev launch tasks automatically remove packaged lumi-*.jar and legacy luma-*.jar copies from the local run/*/mods folders so Loom only loads the compiled source-set output.
Run test client:
.\scripts\run-test-client.ps1The default test-client profile installs a small Fabric 1.21.11 builder-tool stack for local validation: Fabric API, WorldEdit, and a pinned Axiom-5.4.1-for-MC1.21.11.jar Modrinth file. The broader performance-mod stack is available with .\scripts\run-test-client.ps1 -FullStack. See docs/test-client.md for the complete mod list.
Run tests:
.\gradlew.bat testRun the local in-world regression suite from a singleplayer save with cheats enabled:
/lumi testing singleplayerThis creates and later archives a temporary bounded test project in an empty air volume above the player's current chunk. The run reports phase progress in chat, keeps a pass/fail report instead of stopping on the first failed check, verifies broad gameplay edits plus a gameMode-driven water bridge and controlled TNT interaction can be undone/redone or restored back to the initial save, checks preview fulfillment after a gameplay save, checks a lightweight performance budget for scoped operations and synchronous tick work, and writes a detailed log under <save>/lumi/test-logs/.
Artifacts go to build/libs/. Packaging tasks also prune stale legacy luma-* artifacts so the folder only keeps the current lumi-* outputs.
- Open a local singleplayer save.
- On dedicated servers, make sure the player has operator-level permissions. In local singleplayer, tracked builder actions start immediately.
- Press
U. - Lumi opens the current Build History directly when the dimension project is available.
- Build in the tracked area.
- Use the Lumi action button plus
Z/Yto undo or redo the latest tracked action while no screen is open. The default action button isLeft Alt, and changing it changes these chords too. WorldEdit/FAWE actions use native tool undo/redo; captured Axiom capability actions replay through Lumi. - Hold the Lumi action button to preview the latest 10 undo actions, or hold it plus
Yto preview redo actions, when the compare overlay is not active. Small previews render nearest exposed changed blocks; dense previews collapse into merged low-alpha volume blobs so large edits do not draw thousands of separate block overlays. Opening See Changes for a resolved diff enables the world highlight immediately; comparisons againstCurrent buildrefresh automatically while you keep editing. - Press the Lumi action button plus
Sto open Quick save when you only need to name and save the current build. The default chord isLeft Alt+S; both keys are listed under MinecraftControls->Lumi. - Use
Save buildwhen you want the full save screen with manual naming or replace-latest tools. - Open a save when you want details, restore, see changes, or create a branch from it.
- Use
Branchesfor alternate build directions, the sidebar for Import / Export and Settings, andMorefor storage cleanup, manual compare, the history graph, raw references, or the Deleted saves tab.
Current scope:
- singleplayer / integrated-server first
- menu flow first, with commands limited to diagnostics/help and the explicit
/lumi testing singleplayerruntime test suite - combine currently works through imported review projects for the same project lineage, with background review, block-level same-area detection, and validation messages before Lumi writes a combined save
- partial restore is available from save details with manual bounds or a wooden-sword Lumi selection, including inside-selection and everything-except-selection modes
- compare overlay marks changed positions, not a full 3D preview; very large comparisons collapse into merged volume blobs so the client does not draw hundreds of thousands of separate block overlays
- In-use player onboarding for tools, tabs, and workflow explanations
- Multiplayer support
- Additional test coverage
- Exploit discovery and hardening
- Wiki website
- Mod landing page
- Tutorial video
- User guide
- Commands
- Development
- Architecture
- Module map
- Maintenance guide
- Storage format
- Commit policy
- Test client profile
Licensed under GPL-3.0.
