-
-
Notifications
You must be signed in to change notification settings - Fork 0
How to Load an Anvil world
Serve a stored Anvil world (r.<x>.<z>.mca region files) from a Minestom instance using
FalcoAnvilLoader instead of the built-in AnvilLoader.
Before you start: falco-anvil on the classpath (How-to Add Falco to your build), and a
world directory whose chunks are at or above the version floor on
Reference Supported versions. Nothing switches to this loader by itself — a server keeps using
whatever loader it uses today until it constructs a FalcoAnvilLoader explicitly.
- Create the instance, construct the loader from the world root and the dimension key, and set it:
import net.kyori.adventure.key.Key;
import net.minestom.server.MinecraftServer;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.world.DimensionType;
import net.onelitefeather.falco.anvil.FalcoAnvilLoader;
import java.nio.file.Path;
public final class Bootstrap {
public static InstanceContainer createLobby() {
InstanceContainer instance = MinecraftServer.getInstanceManager()
.createInstanceContainer(DimensionType.OVERWORLD);
Key dimension = DimensionType.OVERWORLD.key();
FalcoAnvilLoader loader = new FalcoAnvilLoader(Path.of("worlds", "lobby"), dimension);
instance.setChunkLoader(loader);
instance.enableAutoChunkLoad(true);
return instance;
}
}-
Pass the world root, not the region directory. The loader resolves
worldRoot/dimensions/<namespace>/<value>/regionitself, and falls back toworldRoot/regionwhen only the pre-26.1 layout exists. -
Call
close()on server shutdown. It flushes and closes every open region file and writes the summary line. During operation a region file closes on its own once the last chunk read from it has been unloaded, so nothing has to be closed per chunk.
FalcoAnvilLoader is a plain net.minestom.server.instance.ChunkLoader, so anything that already
accepts one takes it without knowing this library exists. Pass it to
InstanceManager#createInstanceContainer(RegistryKey<DimensionType>, ChunkLoader):
import net.kyori.adventure.key.Key;
import net.minestom.server.MinecraftServer;
import net.minestom.server.instance.ChunkLoader;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.world.DimensionType;
import net.onelitefeather.falco.anvil.FalcoAnvilLoader;
import java.nio.file.Path;
public final class MapLoaders {
public static InstanceContainer open(Path worldRoot, RegistryKey<DimensionType> dimensionKey) {
Key dimension = dimensionKey.key();
ChunkLoader loader = new FalcoAnvilLoader(worldRoot, dimension);
return MinecraftServer.getInstanceManager().createInstanceContainer(dimensionKey, loader);
}
}The relevant Falco signatures are:
| Member | Declaration |
|---|---|
FalcoAnvilLoader(Path, Key) |
public FalcoAnvilLoader(Path worldRoot, Key dimension) |
FalcoAnvilLoader(Path, Key, int) |
public FalcoAnvilLoader(Path worldRoot, Key dimension, int openRegionLimit) |
A provider that keeps a world root per map passes that root and the dimension key of the instance it
is building. Any other ChunkLoader is supplied the same way, which is what makes the choice
reversible.
The falco-demo module does exactly this and is compiled on every build:
LoaderKind#create
constructs either loader from the same world description, and
DemoServer
hands the result to createInstanceContainer.
The number of region files held in the cache defaults to 64 and is set through the three-argument constructor:
FalcoAnvilLoader loader = new FalcoAnvilLoader(worldRoot, dimension, 256);The loader writes an opening log line naming the resolved region directory and the policies it
resolved. Players see the stored world rather than freshly generated terrain, and
AnvilDiagnostics#chunksLoaded() climbs while errors() stays at zero.
A load that throws AnvilChunkException rather than returning air is the loader working as designed
— it found a chunk it could not read and refused to let a replacement be generated over it. Read
reason() off the causing ChunkDataException and look it up on
Reference Exceptions and faults. UNSUPPORTED_CHUNK_VERSION means the world predates the floor;
How-to Migrate a world from an older version is the fix.
An IllegalStateException from loadChunk, saveChunk or saveChunks means close() has already
run on this loader.
See also: Reference Exceptions and faults · Reference Supported versions · How-to Replace the version and unknown-entry policies · Explanation How the Anvil loader is built
Every published table lives on Reference Measured results, which owns them; a correction is made
there and nowhere else. What the ± after a JMH mean covers is defined once, in
Explanation What a measurement here means.
Wiki home · Repository · README and quick start · API documentation · Issues · Licence: AGPL-3.0
Getting started
How-to guides
- How-to Add Falco to your build
- How-to Load an Anvil world
- How-to Compute light for a loaded world
- How-to Keep chunk light up to date automatically
- How-to Use FalcoInstance instead of InstanceContainer
- How-to Migrate a world from an older version
four more
Reference
six more
Background
- Explanation Choosing between Falco and the built-in loader
- Explanation Scope and non-goals
- Explanation When light computation actually runs
- Explanation What a measurement here means
nine more
- Explanation Choosing between FalcoInstance and InstanceContainer
- Explanation How the Anvil loader is built
- Explanation How the light engine works
- Explanation How the concurrency design works
- Explanation How world migration works
- Explanation The chunk version guard
- Explanation Why a second Anvil loader
- Explanation Why a custom light engine
- Explanation Why falco-instance exists
- Explanation Comparing the light engine with Minestoms
- Explanation What the benchmarks establish
Project record
Working on Falco