Normal command executors

Command executors are of the following format, where sender is a CommandSender, and args is a CommandArguments object, which represents arguments which are parsed by the CommandAPI.

new CommandAPICommand("...")
    .executes((sender, args) -> {
        //Code here  
    })
    .register();

With normal command executors, these do not need to return anything. By default, this will return a success value of 1 if it runs successfully, and a success value of 0 if it runs unsuccessfully, either by throwing an exception (RuntimeException) or by forcing the command to fail (See the section on handling command failures).

In short, this is what values are returned when a command is executed from a normal command executor:

Command WorksCommand Doesn't Work
Success Value10
Result Value10

Example - Creating a message broadcasting system

To illustrate this, let's take a look at a simple message broadcasting command. We'll make a command which sends a message to everyone on the server, using the following syntax:

/broadcastmsg <message>
/broadcastmessage <message>
/broadcast <message>

We use an argument "message" to hold the message to broadcast, we provide some aliases and set a permission required to run the command. Then we declare our main command body by using the .executes() method, before finally registering the command:

// Create our command
new CommandAPICommand("broadcastmsg")
    .withArguments(new GreedyStringArgument("message")) // The arguments
    .withAliases("broadcast", "broadcastmessage")       // Command aliases
    .withPermission(CommandPermission.OP)               // Required permissions
    .executes((sender, args) -> {
        String message = (String) args.get("message");
        Bukkit.getServer().broadcastMessage(message);
    })
    .register();
// Create our command
CommandAPICommand("broadcastmsg")
    .withArguments(GreedyStringArgument("message")) // The arguments
    .withAliases("broadcast", "broadcastmessage")       // Command aliases
    .withPermission(CommandPermission.OP)               // Required permissions
    .executes(CommandExecutor { _, args ->
        val message = args["message"] as String
        Bukkit.getServer().broadcastMessage(message)
    })
    .register()

Note how when we finish up our implementation of .executes(), we don't return anything. This is unlike commands in the standard Bukkit API where the onCommand method returns a Boolean value:

boolean onCommand(CommandSender, Command, String, String[])

The returning of this Boolean value is handled automatically by the CommandAPI on a much lower level.


Restricting who can run your command

The CommandAPICommand class has multiple different executes...() methods that can restrict the command sender to any of the following objects:

CommandSender ObjectMethod to useWho can run this?
CommandSender.executes()Any CommandSender
Player.executesPlayer()In-game players only
Entity.executesEntity()Entities only
BlockCommandSender.executesCommandBlock()Command blocks only
ConsoleCommandSender.executesConsole()The console only
ProxiedCommandSender.executesProxy()Proxied senders only
(via /execute as ...)
NativeProxyCommandSender.executesNative()See Native commandsenders

Example - A /suicide command

Say we wanted to create a command /suicide, which kills the player that executes it. Since this command can't be used by non-players (you can't kill a command block!), we can restrict it so only players can execute this command. Since it's a player, we can use the .executesPlayer() method:

new CommandAPICommand("suicide")
    .executesPlayer((player, args) -> {
        player.setHealth(0);
    })
    .register();
CommandAPICommand("suicide")
    .executesPlayer(PlayerCommandExecutor { player, _ ->
        player.setHealth(0.0)
    })
    .register()

Multiple command executor implementations

The CommandAPI allows you to chain different implementations of the command depending on the type of CommandSender. This allows you to easily specify what types of CommandSenders are required to run a command.

Extending on the suicide example above, we could write another implementation for a different CommandSender. Here, we write an implementation to make entities (non-player) go out with a bang when they run the command (using /execute as <entity> run suicide command).

Example - A /suicide command with different implementations

new CommandAPICommand("suicide")
    .executesPlayer((player, args) -> {
        player.setHealth(0);
    })
    .executesEntity((entity, args) -> {
        entity.getWorld().createExplosion(entity.getLocation(), 4);
        entity.remove();
    })
    .register();
CommandAPICommand("suicide")
    .executesPlayer(PlayerCommandExecutor { player, _ ->
        player.setHealth(0.0)
    })
    .executesEntity(EntityCommandExecutor { entity, _ ->
        entity.world.createExplosion(entity.location, 4f)
        entity.remove()
    })
    .register()

This saves having to use instanceof multiple times to check the type of the CommandSender.

The different command sender priority is the following (from highest priority to lowest priority):

\begin{align} &\quad\texttt{.executesNative()} && \texttt{(Always chosen if used)}\\ &\quad\texttt{.executesPlayer()} \\ &\quad\texttt{.executesEntity()} \\ &\quad\texttt{.executesConsole()} \\ &\quad\texttt{.executesCommandBlock()} \\ &\quad\texttt{.executesProxy()} \\ &\quad\texttt{.executes()} \end{align}


Multiple command executors with the same implementation

The CommandAPI also allows you to have multiple command executors with the same command implementation. This is useful for when you want to restrict the command sender required to run a command, but want to run the same code for each different command sender type.

This is achieved using the .executes(executor, ...) method, which accepts a variadic array of ExecutorType objects. ExecutorType has the following values:

ExecutorType ObjectWho can run this?
ALLAny CommandSender
PLAYERIn-game players only
ENTITYEntities only
BLOCKCommand blocks only
CONSOLEThe console only
PROXYProxied senders only
(via /execute as ...)
NATIVESee Native commandsenders

Example - A /suicide command with the same implementation

Expanding on the suicide example above, we can restrict the command to only players and entities. We know that the command sender is a LivingEntity, so we can cast to it safely.

new CommandAPICommand("suicide")
    .executes((sender, args) -> {
        LivingEntity entity;
        if (sender instanceof ProxiedCommandSender proxy) {
            entity = (LivingEntity) proxy.getCallee();
        } else {
            entity = (LivingEntity) sender;
        }
        entity.setHealth(0);
    }, ExecutorType.PLAYER, ExecutorType.PROXY)
    .register();
CommandAPICommand("suicide")
    .executes(CommandExecutor { sender, _ ->
        val entity = (if (sender is ProxiedCommandSender) sender.callee else sender) as LivingEntity
        entity.setHealth(0.0)
    }, ExecutorType.PLAYER, ExecutorType.PROXY)
    .register()

Using the ExecutionInfo

You also have the option to implement a command executor which uses an ExecutionInfo object:

new CommandAPICommand("...")
    .executes(info -> {
        // Use info here
    })
    .register();

The ExecutionInfo provides two user-facing methods which both let you access the CommandSender and the arguments:

CommandSender sender();

This method automatically detects which CommandSender type has been used, similar to the .executesXXX() method (see here)! Therefore, casting is not necessary!

The second method lets you access the command's arguments:

CommandArguments args();