Skip to content

Worlds and saves

Changing. Follow: #78, #169, #316, #388

This page is for an admin who wants to point the mcrs server at a world. The server reads a Java Edition world of the same game version, and it saves players. It does not save chunks yet, so every block edit is lost when the server stops.

AreaStateWorksMissing
Saving and AnvilPartialReads an existing Java Edition world. Players are saved when the server shuts down cleanly.Changed chunks are not written back to disk. A world of another data version does not load, and there are no datafixers. WIP#78WIP#169

Give the server a folder as the first argument. The README Quick start shows how to build and start the server.

Terminal window
cargo run --release -- "<path to a world folder>"

The folder must exist, or the server prints “not a world folder” and exits. When you pass a folder, the server takes the seed and the list of dimensions from the world generation settings of the save, and a seed in MCRS_WORLD_SEED or a preset in MCRS_WORLD_PRESET does not override them. The chunks come from the region files of the save, which Java Edition stores in the Anvil format.

Every chunk and every player file carries a DataVersion, the number of the game version that wrote it. The server accepts a file only when that number matches the game version of this build, which is 26.4-snapshot-7 with world version 5127, as version.json states. The server refuses a file from any other version with an error that names the version it found and the version it expected. It also refuses a chunk that has no DataVersion.

mcrs has no converter for saves of older versions and will not get one, because it follows one snapshot at a time and keeps no compatibility chain.1 If you have an older world, open it once in a vanilla client of the right snapshot so that the game rewrites it, and then give the folder to mcrs. A field that no type claims also fails the load, so the server does not keep such a field as raw bytes.1

Without a folder, the server generates a world

Section titled “Without a folder, the server generates a world”

When you start the server with no argument, it generates a world from a preset. Nothing of that world reaches the disk. It has no player files either, because the server builds the path of a player file from the world folder. Three settings shape the world, and the server reads them once at start. The full list of settings is in server_settings.rs.

Variable Meaning Default
MCRS_WORLD_SEED The seed, as a signed or unsigned 64-bit number 0
MCRS_WORLD_PRESET normal or minecraft:normal, flat normal
MCRS_DEFAULT_GAMEMODE Game mode of a new player creative

World generation matches vanilla in parity tests on the reference seeds. Parity says what those tests cover.

Data State
Player files Saved. The server writes each player to players/data/<uuid>.dat in the world folder on disconnect, and an autosave writes them every 6000 ticks, which is vanilla’s own interval
A clean stop with players Works#624. On the first SIGINT or SIGTERM the server disconnects every player with the vanilla shutdown reason, saves them and exits. A second signal exits at once
Chunks and block edits Not saved. The server reads chunks but never writes them, see WIP#78
Clean shutdown with chunks Not done. Waiting for chunk writes is WIP#169
level.dat, world clocks, weather, game rules Read but not written yet. WIP#78 lists writing them

The server protects a player file that it cannot parse. The player joins empty, and the server never saves that player over the old file. An inventory in a player file survives too. The server keeps it as opaque data and writes it back unchanged, because the inventory code was removed and is being rewritten from a specification.2

A short test checks the clean stop.

A shutdown request writes the player file
let player_file = player_dat_path(&world, offline_player_uuid("mcrs_test"));
assert!(!player_file.exists(), "saved before the shutdown");
requested.store(true, Ordering::Relaxed);
exited
.recv_timeout(Duration::from_secs(30))
.expect("the server exits by itself after the request");
server_thread.join().unwrap();
assert!(player_file.exists(), "{} is missing", player_file.display());

tests/it/shutdown.rs:74-83

The server loads the vanilla data pack and your local packs into the registries at start. The vanilla pack comes from the game jar, and a local pack is a directory under mcrs/datapacks/ in the assets root of the build.

You can check a pack without starting a server. The check_pack example of the mcrs_minecraft_game_registries crate loads your pack over the vanilla one, prints every diagnostic, and exits with an error if there is one.

Terminal window
cargo run -p mcrs_minecraft_game_registries --example check_pack -- "<data pack directory>"

The directory must hold pack.mcmeta and data/, and the usage line of the tool says the same.

The server cannot reload a pack while it runs, so you restart it after you change one. /reload and live enabling of packs are planned.4 The plan is that a reload replaces the data at a tick boundary and refuses changes that the saved world depends on, such as the height of a dimension type.

There is no source yet for how the server treats a datapacks folder inside a world folder, so this page makes no claim about it.

  1. Not planned#388 The decision that saves are read at exactly the targeted data version, with no datafixers. ↩ ↩2

  2. WIP#521 Tracks the specification and the plugin of the player inventory. ↩

  3. WIP#78 Tracks saving changed chunks back to region files. ↩

  4. WIP#316 Plans the reload of data packs while the server runs. ↩

Sources and verification

Verified: 26.4-snapshot-7, 51d45c26a, 2026-11-09

Tracking: #78, #169, #316, #388