Skip to content

Opening a World

Before we get into chunks, entities and blocks, let’s start with the basics: opening a world folder and reading the data that sits right at its root, like level.dat.

If you looked at the Introduction guide already, you know a world is not just a single file. It’s a whole folder full of .dat files, region files and player data. Most of that data only matters once you start looking at a specific dimension or a specific chunk, which we’ll cover in later guides.

For now, think of a world as two things:

  1. A handful of files that describe the world itself: its name, its difficulty, its spawn point, whether it’s hardcore, and so on. This lives in level.dat.
  2. A session.lock file that Minecraft uses to make sure only one thing is writing to the world at a time.

minified-worlds wraps both of these in one class: WorldSave.

repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
// Replace 3.1.0 with your preferred version
implementation 'com.github.dervarex.minified:minified-worlds:3.1.0'
}

All you need is a path to the world folder, the same folder that contains the level.dat.

Path worldDirectory = Path.of("saves/My World");
WorldSave world = new WorldSave(worldDirectory);

When you construct WorldSave, it immediately reads level.dat and a couple of other small .dat files from the data/ folder, so the constructor can throw if something is wrong. Two things it checks:

  • The given path has to be an existing directory. If it isn’t, you’ll get a RuntimeException saying the world directory doesn’t exist.
  • That directory has to contain a level.dat file. Without it, minified-worlds has no idea what world it’s even looking at, so it throws too.

Both of these are unchecked exceptions, so you don’t need a try/catch just to open a world, but it’s worth catching them if you’re opening a folder the user picked or one that might not be a real world.

Once you have a WorldSave, its getLevel() method gives you a Level object with the world’s core settings already parsed for you.

Level level = world.getLevel();
System.out.println(level.getLevelName());
System.out.println(level.getDifficulty());
System.out.println(level.isHardcore());
System.out.println(level.getSpawn().getPos());

A few of the fields you’ll find on Level:

Level fieldsThe most commonly used ones
levelNameString

The world’s name, as shown on the “Select World” screen.

difficultyDifficulty

The world’s difficulty: peaceful, easy, normal or hard.

hardcoreboolean

Whether hardcore mode is on. This is separate from difficulty, a hardcore world still reports hard there.

spawnSpawn

The world spawn point: dimension, position, pitch and yaw.

versionVersion

The Minecraft version this world was last saved with.

gameTypeint

The default game mode: 0 survival, 1 creative, 2 adventure, 3 spectator.

enabledDatapacksString[]

Which datapacks are turned on for this world. disabledDatapacks lists the rest.

allowCommandsboolean

Whether cheats are enabled.

timeint

The current world time, in ticks.

Level is a plain data class with getters and setters for everything, so if you want to change something, like renaming the world or nudging the spawn point, just call the matching setter.

Difficulty

peacefulNo hostile mobs spawn, and hunger doesn’t drain.
easyHostile mobs deal less damage, hunger drains slowly.
normalThe default, balanced difficulty.
hardHostile mobs deal more damage, hunger drains faster. Also what hardcore worlds report here.

WorldSave has a save() method that writes the Level object back to level.dat.

level.setLevelName("My Renamed World");
world.save();

Keep in mind that save() only writes level.dat. It doesn’t touch chunks, entities or point of interest data, since those live in their own region files per dimension. We’ll get to saving those in the next guide.

Minecraft uses session.lock to prevent two processes (say, a running server and your tool) from writing to the same world at the same time. WorldSave reads this for you through getLock().

if (world.getLock().isLocked()) {
System.out.println("This world is currently open somewhere else!");
}

It’s a good habit to check this before writing to a world your tool didn’t open itself, editing a world while Minecraft has it loaded is a great way to lose progress.

A couple of files in the data/ folder aren’t always there, since Minecraft only creates them once they’re actually used. WorldSave exposes those as Optional:

world.getGameRules().ifPresent(rules -> {
// do something with the game rules
});
world.getCustomBossEvents().ifPresent(bossEvents -> {
// do something with the boss bars
});

Now that you can open a world and read its top level settings, it’s time to look at the actual terrain.