Skip to content

Functions

The CommandAPI has support to use Minecraft's functions within your plugins. This is handled by using a class provided by the CommandAPI called FunctionWrapper, which allows you to execute functions. The CommandAPI also provides support to let you run your own commands within Minecraft function files.

Functions in 1.16+

Developer's Note:

Minecraft 1.16+ changes the way that datapacks are loaded on the server, so that they load before plugins are enabled. This means that non-vanilla commands that are declared in functions and tags will be detected as invalid, causing the server to throw a lot of errors at the very start.

To make commands available in datapacks, they have to be registered at the right place. More on that later.

The CommandAPI reloads datapacks once the server has finished loading using all declared commands, therefore the error messages at the start of the server can be ignored.

Using custom commands in functions

In order to use a command from your plugin in a .mcfunction file, you must register your command in your plugin's bootstrap(BootstrapContext) method, instead of the onLoad()/onEnable() method. Failure to do so will not allow the command to be registered for Minecraft functions, causing the function file to fail to load during the server startup phase.

Developer's Note:

In short, if you want to register a command which can be used in Minecraft functions, register it in your plugin's bootstrap(BootstrapContext) method.

Example – Registering command for use in a function

Example – Registering command for use in a function

Say we have a command /killall that simply kills all entities in all worlds on the server. To make it available in a function, we want to register the command in the bootstrap(BootstrapContext) method.

java
public class MainBoostrap implements PluginBootstrap {
    @Override
    public void bootstrap(BootstrapContext context) {
        // Commands which will be used in Minecraft functions are registered here

        new CommandAPICommand("killall")
            .executes((sender, args) -> {
                // Kills all enemies in all worlds
                Bukkit.getWorlds().forEach(w -> w.getLivingEntities().forEach(e -> e.setHealth(0)));
            })
            .register();
    }
}

Say we have a command /killall that simply kills all entities in all worlds on the server. It doesn't matter where we register to make the command available in a function, but we'll just use the onLoad() method here.

java
public class Main extends JavaPlugin {
    @Override
    public void onLoad() {
        new CommandAPICommand("killall")
            .executes((sender, args) -> {
                // Kills all enemies in all worlds
                Bukkit.getWorlds().forEach(w -> w.getLivingEntities().forEach(e -> e.setHealth(0)));
            })
            .register();
    }
}