This article is the second in a series of articles, you can find the first here.
Updating WorldEdit to Minecraft 1.13 has been a long and arduous process. With weeks of hard work, and hundreds of thousands of lines of code changed, it's finally in a complete state.
It's not without significant changes, however, and this article will cover them. Many of these changes bring WorldEdit into the modern era of Minecraft, as we had not upgraded many internal systems in a fair while.
Firstly, I'll go over the user-facing changes. These are minimised where possible, except in some places they had to happen. The areas these mostly cover are block parsing and schematics.
Due to the significant changes to blocks and IDs in 1.13, block parsing required an entire rewrite. The officially supported format for referencing blocks is to use the official Minecraft format. For example, grass blocks are used by typing
minecraft:grass_block, and a snowy grass block would be accessed by typing
minecraft:grass_block[snowy=true]. If the block is from the vanilla game,
minecraft: can be omitted. For example,
grass_block[snowy=true] will still place a snowy grass block.
To retain some aspect of legacy support, you can still reference most legacy numeric IDs. Doing this is, however, NOT officially supported. Placing wool using their colour is still supported (Eg,
Schematics also required significant changes, but have retained legacy compatibility. As the MCEdit Schematic format leverages numerical IDs, WorldEdit has moved to the Sponge Schematic Format. The Sponge Schematic Format is very future proof and will be the supported way of saving and loading schematics going forwards. An added benefit of using this schematic format is that schematics now work correctly with mods and save entities and biomes.
For the end-user, the transition period should be relatively seamless. However, previously created schematics will still load, with some oddities such as corner stairs losing their corner pieces due to format restrictions. Any newly created schematic will use the Sponge format. Any schematic generated on 1.13 will not be usable on prior Minecraft versions. Schematics, like Minecraft worlds, are not guaranteed to be backwards compatible.
Everything else should still function the same. If you find an issue, please report it on our issue tracker.
This section is much larger and much less backwards compatible than the user-facing changes. Due to a large number of changes in 1.13, and the massive size and technical debt of the WorldEdit codebase, we decided to remove all deprecated or functionally deprecated code from the plugin. Any plugin using deprecated code will no longer function. However, any plugin accessing WorldEdit would have most likely had to be updated anyway. A vast majority of these API calls were deprecated for over four years, so there has been plenty of warning.
The most obvious change is the removal of the
BlockID class. WorldEdit now uses a registry system, in
BlockTypes. The equivalent also exists for
BlockType.get(String) method gets a
BlockType from a namespaced string ID from the registry. The equivalent exists for all of the registries. The following registries currently exist in WorldEdit 7:
- FluidType (In 1.13, Mojang moved fluid blocks to a separate system. This is currently unused, however)
- BlockCategory (Mirrors the vanilla Tag system)
Another change is the migration of everything
BukkitUtil to the
BukkitAdapter class. Previously we spread methods across both files, which confused developers.
In WorldEdit 6 and earlier, a file called
BlockType shared the name of the new
BlockType class. This class contained a list of blocks, as well as some utility functions regarding blocks. These utility functions now reside in
Blocks, as well as
BlockMaterial. Materials can be accessed via the
Also relating to blocks, in 1.13 properties have replaced the metadata system. WorldEdit can now access these. In prior versions, there was a class called
BaseBlock. Whilst this class still exists, it has a very different purpose now. Most usages of
BaseBlock should now be
BlockState instances are both immutable and cached. Developers should never create instances of
BlockState. This system keeps memory usage down and performance high. Creating new instances would prevent this and cause other issues. You access properties by name on
BlockType, and values can be applied and retrieved in
BlockState. Applying a property to a
BlockState returns a copy of that
BlockState with the property applied. There will only be a single
BlockState object made for each type and combination of properties, meaning object reference equality works.
When dealing with NBT Data,
BaseBlock should be used. Instances are created by passing both a
BlockState and a
CompoundTag to the constructor. When getting blocks from the world, use
getBlock() to get the block itself, and
getFullBlock() to get the block with NBT data.
Another significant change is the Selection API, however this only impacts Bukkit plugins using the 'native layer'. We removed the native layer to standardise WorldEdit across various platforms and clean up the codebase. This layer was first talked about by sk89q back in 2013 on his blog.
To get a selection using WorldEdit 7, you need to do the following:
- Get a WorldEdit player using
- Get the
LocalSessionfor the player using
LocalSession#getSelection(World)using the WorldEdit Player's World.
This method returns a
Region object. From here, you can call many functions on the region and iterate over it to get all of the containing
BlockVectors. You can also check and cast into various shapes, such as
If no selection exists when calling this code,
getSelection(World) will throw an
IncompleteRegionException. This exception should be caught and shown to the user.
We also made significant changes to the schematic system. Other plugins can now register schematic formats, and we implemented the Sponge Schematic Format. It is now the recommended format to use, and we've deprecated usage of the MCEdit format for all non-legacy import purposes. As the old MCEdit format does not support the way Minecraft works in modern versions, the API can also only load these, not save them.
Schematic formats should be accessed using
BuiltInClipboardFormat.MCEDIT_SCHEMATIC to access specific formats, by using
ClipboardFormats.findByAlias(String) to find formats by name, or by using
ClipboardFormats.findByFile(File) to identify the format of a schematic file.
A more in-depth tutorial on this API change is available here.
If you have any issues with the API, please join the WorldEdit discord.
WorldEdit also now includes a much larger general Minecraft API for writing cross-platform plugins. Developers can use this to make their plugins work across Sponge, Spigot, Forge, Fabric, etc. This system has been utilised in WorldGuard to make the plugin much more abstract; however, it still only supports Bukkit.
Part 3, focusing on the changes to WorldGuard, can be found here.
We've devoted countless hours to working on this project. If you'd like to support us, we have a GitHub Sponsors. Thanks 😁
About the Author
Hi, I'm Maddy Miller, a Senior Software Engineer at Clipchamp at Microsoft. In my spare time I love writing articles, and I also develop the Minecraft mods WorldEdit, WorldGuard, and CraftBook. My opinions are my own and do not represent those of my employer in any capacity.