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.
1. What is a world?
Section titled “1. What is a world?”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:
- 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. - A
session.lockfile 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.
2. Add the dependency
Section titled “2. Add the dependency”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'}repositories { mavenCentral() maven { url = uri("https://jitpack.io") }}
dependencies { // Replace 3.1.0 with your preferred version implementation("com.github.dervarex.minified:minified-worlds:3.1.0")}3. Opening a world
Section titled “3. Opening a world”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);val worldDirectory = Path.of("saves/My World")val world = 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
RuntimeExceptionsaying the world directory doesn’t exist. - That directory has to contain a
level.datfile. Without it,minified-worldshas 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.
4. Reading level.dat
Section titled “4. Reading level.dat”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());val level = world.level
println(level.levelName)println(level.difficulty)println(level.hardcore)println(level.spawn.pos)A few of the fields you’ll find on Level:
Level fieldsThe most commonly used ones
levelNameStringThe world’s name, as shown on the “Select World” screen.
difficultyDifficultyThe world’s difficulty: peaceful, easy, normal or hard.
hardcorebooleanWhether hardcore mode is on. This is separate from difficulty, a hardcore world still reports hard there.
spawnSpawnThe world spawn point: dimension, position, pitch and yaw.
versionVersionThe Minecraft version this world was last saved with.
gameTypeintThe default game mode: 0 survival, 1 creative, 2 adventure, 3 spectator.
enabledDatapacksString[]Which datapacks are turned on for this world. disabledDatapacks lists the rest.
allowCommandsbooleanWhether cheats are enabled.
timeintThe 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
Section titled “Difficulty”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.5. Saving your changes
Section titled “5. Saving your changes”WorldSave has a save() method that writes the Level object back to level.dat.
level.setLevelName("My Renamed World");world.save();level.levelName = "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.
6. Checking the session lock
Section titled “6. Checking the session lock”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!");}if (world.lock.locked) { 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.
7. Optional data
Section titled “7. Optional data”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});world.gameRules.ifPresent { rules -> // do something with the game rules}
world.customBossEvents.ifPresent { bossEvents -> // do something with the boss bars}Next steps
Section titled “Next steps”Now that you can open a world and read its top level settings, it’s time to look at the actual terrain.