Skip to content

Adding arguments

You can add arguments just by adding parameters to your execute methods.

For example, command /tellmini <players> <message> could look like this:

@Executes
void tellMini(CommandSender sender, List<Player> players, @StringArg(GREEDY) String message) {
Component component = MiniMessage.miniMessage().deserialize(message);
players.forEach(p -> p.sendMessage(component));
}

What this does on Brigadier terms is add two new arguments: ArgumentTypes.players() and StringArgumentType.greedy(). The argument values are automatically resolved by StrokkCommands.

TellMiniCommandBrigadier.java
// StrokkCommands generates all of this from just the parameters!
Commands.literal("tellmini")
.then(Commands.argument("players", ArgumentTypes.players())
.then(Commands.argument("message", StringArgumentType.greedyString())
.executes(ctx -> {
INSTANCE.tellMini(
ctx.getSource().getSender(),
ctx.getArgument("players", PlayerSelectorArgumentResolver.class).resolve(ctx.getSource()),
StringArgumentType.getString(ctx, "message")
);
return Command.SINGLE_SUCCESS;
})
)
);

To declare literals, you can use the @Literal annotation. You can pass a list of strings for multiple-choice literals. For example, a command /tellpreset <player> <first|second|last> could be declared as follows:

TellPresetCommand.java
@Executes
void executeTellPreset(CommandSender sender,
Player player,
@Literal({"first", "second", "last"}) String preset) {
String message = switch (preset) {
case "first" -> "You selected the first choice!";
case "second" -> "This is the second one...";
case "last" -> "...and this is the last one.";
// This will never happen
default -> throw new IllegalStateException("Illegal literal.");
};
player.sendPlainMessage(message);
}

This will generate the following Brigadier command tree:

Warning: Brigadier jumpscare
TellPresetCommandBrigadier.java
final TellPresetCommand instance = new TellPresetCommand();
return Commands.literal("tellpreset")
.then(Commands.argument("player", ArgumentTypes.player())
.then(Commands.literal("second")
.executes(ctx -> {
instance.executeTellPreset(
ctx.getSource().getSender(),
ctx.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(ctx.getSource()).getFirst(),
"second"
);
return Command.SINGLE_SUCCESS;
})
)
.then(Commands.literal("first")
.executes(ctx -> {
instance.executeTellPreset(
ctx.getSource().getSender(),
ctx.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(ctx.getSource()).getFirst(),
"first"
);
return Command.SINGLE_SUCCESS;
})
)
.then(Commands.literal("last")
.executes(ctx -> {
instance.executeTellPreset(
ctx.getSource().getSender(),
ctx.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(ctx.getSource()).getFirst(),
"last"
);
return Command.SINGLE_SUCCESS;
})
)
)
.build();

(( The types here correspond to the ones documented on their designated Paper documentation page ))

The following primitive types can be added as parameters:

  • boolean, Boolean
  • int, Integer
  • long, Long
  • float, Float
  • double, Double

The number ones always have an extra @<Number>Arg(min = <value>, max = <value>) annotation you can add to optionally specify a max or min value:

FlySpeedCommand.java
// The speed argument is limited to be 1 or 10 or in-between.
void execute(CommandSender sender, @IntArg(min = 1, max = 10) int speed) {
// ...
}

(( The String types here correspond to the ones documented on their designated Paper documentation page ))

When you add a String parameter, StrokkCommands defaults to adding a word string argument type. You can change the type of the String argument by adding a @StringArg() annotation and specifying a StringArgType inside. The following types exist:

  • StringArgType.WORD - The default type. Only supports alphanumerical characters and +, -, _, and ..
  • StringArgType.STRING - Similar to the WORD one, but if you add quotes, you can enter any unicode characters.
  • StringargType.GREEDY - Accepts all inputs, but cannot have any arguments follow it.

You can statically import these types for better readability in source code.

In addition to the argument types Brigadier provides natively, you can also add Minecraft-implemented argument types. You can view a list of all on this Paper docs page.

Though, there are a few special cases you should know about.

Certain argument types usually have to be resolved by the developer. A very well-known example for that is the player argument. Usually, this one returns a PlayerSelectorArgumentResolver, which needs resolving.

Not with StrokkCommands! Instead of a resolver, you can instead just declare a Player parameter, and it will resolve it automatically. The same works for List<Player>, Collection<Player>, and even Player[].

You can declare arguments which depend on registry values. The Paper-approach is adding a resource argument type with a specified RegistryKey.

StrokkCommands resolves all registry key arguments natively. That means that to retrieve, for example, an Enchantment, you can just declare an Enchantment parameter. StrokkCommands maps that parameter to an ArgumentTypes.resource(RegistryKey.ENCHANTMENT) argument type.

You can view all available registry keys (and thus the type of parameter you’d have to use) by visiting the RegistryKey<T> JavaDocs.

You can get the key used for accessing the registry from the resource argument type by wrapping the return type in a TypedKey<T>.

For our Enchantment example, if you were to declare a TypedKey<Enchantment>, StrokkCommands would map that parameter to an ArgumentTypes.resourceKey(RegistryKey.ENCHANTMENT) argument type.