Building a Command

The first step is to get a new Builder builder. The builder provides methods to modify the command help messages, command arguments, and the command logic. These methods can be chained.

To finally build the command, you’ll want to call the Command.Builder#build() method.

Example: Building a Simple Command

import org.spongepowered.api.command.Command;

public Command.Parameterized buildCommand(){
    return Command
        .builder()
        .executor(new HelloWorldCommand())
        .permission("myplugin.command.helloWorld")
        .shortDescription(Component.text("Hello World Command"))
        .build();
}

Overview of the Command.Builder methods

method

Description

executor

Defines the command logic. Setting the executor is required if no child commands are set.

parameters

Sets the parameters for use on the executor

flags

Sets the flags for use on the executor

permission

Sets the permission that will be checked before using this command

shortDescription

A short, one-line description of this command’s purpose that will be displayed by the help system

extendedDescription

Sets an extended description to use in longer help listings. Will be appended to the short description

children

Sets the child commands of this command with their aliases

executionRequirements

Sets the execution requirements for the command.

terminal

Sets if the command can execute despite the parameters stating that they are mandatory

build

Builds the command. After that you need to register the command

Player-Only Commands

Sometimes it is necessary that only players can execute a command. Example /suicide command. This is best done though the executionRequirements on the command’s builder where we check for a target player on the command cause.

public Command.Parameterized buildCommand(){
    return Command
        .builder()
        .executor(new HelloWorldCommand())
        .permission("myplugin.command.helloWorld")
        .shortDescription(Component.text("Hello World Command"))
        .executionRequirements(context -> context.cause().root() instanceof ServerPlayer)
        .build();
}

Megjegyzés

We recommend you to add an optional [player] argument to make the command console-friendly for example, /suicide [player]

The easiest solution for this is to append a playerOrTarget command parameter (see Argument Parsing) instead of providing an execution requirement.

Javaslat

Often times command are put in as player-only as they require the location in the world the command was executed from. Best practise would be to check if the root of the command is Locatable instead of the player as this would allow command blocks to run the command without specifying a player.

Writing a Command Executor

The only required component to build a simple command is the command executor class, which contains the logic of the command.

The class has to implement the CommandExecutor interface, which contains a single method that is called on command execution. The method contains a single argument of CommandContext which contains all data attached to the command.

Example: Simple Command Executor

import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.parameter.CommandContext;
import org.spongepowered.api.command.CommandExecutor;
import org.spongepowered.api.command.exception.CommandException;

public class HelloWorldCommand implements CommandExecutor {

    @Override
    public CommandResult execute(CommandContext context) throws CommandException{
        context.sendMessage(Component.text("Hello World!"));
        return CommandResult.success();
    }

}

Javaslat

You can use anonymous classes to define the command executor in the command’s build process (see example in the Argument Parsing page).

Command Result

The command result is used to give more information about how the command was executed. In the example above we used CommandResult#success(), however we can give more information than this, which is then sent back to the client to provide a correctly formatted message.

By going the builder route you gain access to the result method which is an integer value sent back to the client. Generally this can be ignored and the static helper methods of CommandResult#success() and CommandResult#error(Component) will be used.

Example: Building a CommandResult

CommandResult result = CommandResult.builder()
    .result(0)
    .error(Component.text("Hello world in error form"))
    .build();

The result’s input number has three meanings.

Value

Description

Positive

Successful execution

Zero

Unsuccessful execution (but not necessarily an error)

Negative

Undefined in the Minecraft spec, can result in different effects

Error Handling

The execute method may also throw a CommandException, signaling that an error occured while trying to execute the command. If such an Exception is thrown, its message will be displayed to the command source, formatted as an error. An ArgumentParseException, a subtype of CommandExeption is automaticlly thrown if the commands arguments could not be parsed.

Registering a Command

Commands are registered on a RegisterCommandEvent. The event takes a generic which is the type of command that is being registered to it. To register a command, the RegisterCommandEvent#register(PluginContainer, C, String, String…) method needs to be invoked.

In the following example, we register two commands. helloworld which is from the building a simple command example above, as well as a raw command which is explained in Raw Command. These two commands need to be registered in different listeners as they are different command types, however in most cases a single listener will suffice as all commands in a single plugin are typically of the same type.

@Inject
PluginContainer container;

@Listener
public void onRegisterCommands(final RegisterCommandEvent<Command.Parameterized> event){
  event.register(this.container, buildCommand(), "helloworld", "hello", "test");
}

@Listener
public void onRegisterRawCommands(final RegisterCommandEvent<Command.Raw> event){
  event.register(this.container, new MyRawCommand(), "raw");
}