Updating WorldGuard to Minecraft 1.13

Posted on Fri 10 August 2018 in Minecraft

This article is the third in a series of articles, the first can be found here. and the second can be found here.

Updating WorldGuard to 1.13 has been a complicated process, however not as time-consuming as WorldEdit. Much of the work put into WorldEdit made WorldGuard much easier to update, however, changes were made to the core of the plugin to allow for future improvements.

Is WorldGuard cross-platform now?

WorldEdit and WorldGuard are very similar internally, both abstract away the concepts of the game to allow for cross-platform usage. However, WorldGuard has a LOT of Bukkit specific code. While my changes have not made WorldGuard cross-platform compatible, it provides the stepping stones to allow this in the future.

One of the most common WorldGuard questions I get asked is "Can I download this for Sponge?" Sadly, the answer to this is no. One major roadblock for this was the requirement of API breakages to provide actual feature parity across the platforms. So while it's not able to support Sponge at this stage, it can now be implemented without breaking every plugin that depends on the WorldGuard API. Now was the most appropriate time to do this, as 1.13 already broke almost every plugin that existed, and the WorldEdit API is almost 100% breaking.

User-Facing Changes

Like WorldEdit, there are as few user-facing changes as possible. The Block Parsing section from my previous article also applies here to WorldGuard; however, it also extends to entities and game modes.

Aside from that, there should be no other known user-facing changes in 1.13. Everything should work as it did before, with "as good as possible" automatic conversion of configuration files.

Developer Changes

Here is where the substantial changes start to occur. All of the old deprecated APIs are removed, and most major accessors have been moved to a 'core' package, similar to the way WorldEdit works. The reasoning for this was explained above.

The core system is accessed through WorldGuard.getInstance(), and the platform-specific code can be accessed via WorldGuard.getInstance().getPlatform().

Flags

For most plugins that integrate with WorldGuard, the first noticed change will be that the DefaultFlag class no longer exists. This has been replaced with a Flags class, that handles the flags built into WorldGuard in a more registry-friendly way. All usages of the class should be easily replaceable, aside from iteration over flags which should now be done via the registry.

Accessing the registry has slightly changed in WorldGuard 7. It's now accessed through the core, rather than through the Bukkit plugin. The following code gets a copy of the flag registry in WorldGuard 7, WorldGuard.getInstance().getFlagRegistry().

One other change is that flags now use WorldEdit generic classes, rather than Bukkit specific classes. This is part of the ongoing effort to make WorldGuard platform-agnostic.

Flag Queries

This is the other major change that developers have noticed in WorldGuard 7. To query for flags in a region, the region container must be obtained from the platform rather than the plugin. This is done via WorldGuard.getInstance().getPlatform().getRegionContainer(), rather than the old WorldGuardPlugin#getRegionContainer(). This means most usages of the API will no longer require getting a copy of WorldGuardPlugin.

This means that the method of testing a flag is now the following,

// Create a query
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();

// Testing state with a player
boolean state = query.testState(localPlayer.getLocation(), localPlayer, Flags.GHAST_FIREBALL);

// Testing state without a player
boolean state = query.testState(location, (RegionAssociable) null, Flags.GHAST_FIREBALL);

This can, of course, be compressed down into a single line.

Accessing the Configuration

While this isn't recommended for other plugins to do, sometimes access to WorldGuard's configuration is required. This has changed slightly in WorldGuard 7, as it now must be accessed through the platform. With a copy of the platform, getGlobalStateManager() can be called, accessing the same configuration class from prior WorldGuard versions.

The next article in this series will be on CraftBook and is coming eventually. Bugs in Spigot have prevented CraftBook from being entirely updated at this point.

I've devoted countless hours to working on this project. If you'd like to support me, I have a Patreon and accept donations through PayPal. Thanks 😁