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, we made changes to the plugin's core to allow for future improvements.

Is WorldGuard cross-platform now?

WorldEdit and WorldGuard are very similar internally, both abstract away the game concepts 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 to cause API breakages to provide actual feature parity across the platforms. So while it cannot support Sponge at this stage, we can now implement it 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 practically 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 substantial changes start to occur. We removed all of the old deprecated APIs and moved most major accessors to a 'core' package. This change is similar to the way WorldEdit works. I explained the reasoning for this 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. The DefaultFlag class is now called Flags. This class 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 you should now do via the registry.

Accessing the flag registry has slightly changed in WorldGuard 7. You can now access this 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 change is part of the effort mentioned above to make WorldGuard platform-agnostic.

Flag Queries

This area is the other major change that developers may notice in WorldGuard 7. To query for flags in a region, you must obtain the region container from the platform instead of the plugin. This is done via WorldGuard.getInstance().getPlatform().getRegionContainer(), rather than the old WorldGuardPlugin#getRegionContainer(). This change 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);

You can, of course, write this code in a single line.

Accessing the Configuration

While we don't recommend this for other plugins to do, sometimes access to WorldGuard's configuration is required. This system 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. As always though, the configuration isn't considered API and therefore may change in non-major updates.

The next article in this series is on CraftBook and is available 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

Maddy Miller

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.