Arguments

Arguments in the CommandAPI are registered by using a LinkedHashMap<String, Argument> object. There are two things you need to keep in mind when creating arguments:

  • The order which they will be used
  • The type of each argument

By definition of a LinkedHashMap, the order of the elements inserted into it are preserved, meaning the order you add arguments to the LinkedHashMap will be the resulting order of which arguments are presented to the user when they run that command.

Adding arguments for registration is simple:

//Create LinkedHashMap
LinkedHashMap<String, Argument> arguments = new LinkedHashMap<>();

//Add an argument called "target", which is a PlayerArgument
arguments.put("target", new PlayerArgument());

The String value is the prompt that is shown to a player when they are entering the command.


Argument Casting

To access arguments, they have to be casted to the type that the argument represents. The order of the arguments in the args[] is the same as the order in which the arguments were declared.

LinkedHashMap<String, ArgumentType> arguments = new LinkedHashMap<>();
arguments.put("arg0", new StringArgument());
arguments.put("arg1", new PotionEffectArgument());
arguments.put("arg2", new LocationArgument());

new CommandAPICommand("cmd")
    .withArguments(arguments)
    .executes((sender, args) -> {
        String stringArg = (String) args[0];
        PotionEffectType potionArg = (PotionEffectType) args[1];
        Location locationArg = (Location) args[2];
    })
	.register();

The type to cast each argument (declared in the dev.jorel.commandapi.arguments package) is listed below:

Argument classData type
AdvancementArgumentorg.bukkit.advancement.Advancement
AxisArgumentjava.util.EnumSet<org.bukkit.Axis>
BiomeArgumentorg.bukkit.block.Biome
BlockPredicateArgumentjava.util.function.Predicate<org.bukkit.block.Block>
BlockStateArgumentorg.bukkit.block.data.BlockData
BooleanArgumentboolean
ChatArgumentnet.md_5.bungee.api.chat.BaseComponent[]
ChatColorArgumentorg.bukkit.ChatColor
ChatComponentArgumentnet.md_5.bungee.api.chat.BaseComponent[]
CustomArgument<T>T
DoubleArgumentdouble
EnchantmentArgumentorg.bukkit.enchantments.Enchantment
EntitySelectorArgumentThe cast type changes depending on the input parameter:
  • EntitySelector.MANY_ENTITIES - Collection<org.bukkit.entity.Entity>

  • EntitySelector.MANY_PLAYERS - Collection<org.bukkit.entity.Player>

  • EntitySelector.ONE_ENTITY - org.bukkit.entity.Entity

  • EntitySelector.ONE_PLAYER - org.bukkit.entity.Player
EntityTypeArgumentorg.bukkit.entity.EntityType
EnvironmentArgumentorg.bukkit.World.Environment
FloatArgumentfloat
FloatRangeArgumentdev.jorel.commandapi.wrappers.FloatRange
FunctionArgumentdev.jorel.commandapi.wrappers.FunctionWrapper[]
GreedyStringArgumentString
IntegerArgumentint
IntegerRangeArgumentdev.jorel.commandapi.wrappers.IntegerRange
ItemStackArgumentorg.bukkit.inventory.ItemStack
ItemStackPredicateArgumentjava.util.function.Predicate<org.bukkit.inventory.ItemStack>
LiteralArgumentN/A
Location2DArgumentdev.jorel.commandapi.wrappers.Location2D
LocationArgumentorg.bukkit.Location
LongArgumentlong
LootTableArgumentorg.bukkit.loot.LootTable
MathOperationArgumentdev.jorel.commandapi.wrappers.MathOperation
MultiLiteralArgumentString
NBTCompoundArgumentde.tr7zw.nbtapi.NBTContainer
ObjectiveArgumentString
ObjectiveCriteriaArgumentString
ParticleArgumentorg.bukkit.Particle
PlayerArgumentorg.bukkit.entity.Player
PotionEffectArgumentorg.bukkit.potion.PotionEffectType
RecipeArgumentThe cast type changes depending on your Minecraft version:
  • Version 1.14.4 and below - org.bukkit.inventory.Recipe

  • 1.15 and above - org.bukkit.inventory.ComplexRecipe
RotationArgumentdev.jorel.commandapi.wrappers.Rotation
ScoreboardSlotArgumentdev.jorel.commandapi.wrappers.ScoreboardSlot
ScoreHolderArgumentThe cast type changes depending on the input parameter:
  • ScoreHolderType.SINGLE - String

  • ScoreHolderType.MULTIPLE - Collection<String>
SoundArgumentorg.bukkit.Sound
StringArgumentString
TeamArgumentString
TextArgumentString
TimeArgumentint
UUIDArgumentjava.util.UUID

Optional/Different Arguments

Sometimes, you want to register a command that has a different effect whether arguments are included or not. For example, take the /kill command. If you run /kill on its own, it will kill the command sender. If however you run /kill <target>, it will kill the target. In other words, we have the following command structure:

/kill          - Kills yourself
/kill <target> - Kills a target player

As shown by the command structure, we need to register two commands.

Example - /kill command with two separate arguments

For example, say we're registering a command /kill:

/kill          - Kills yourself
/kill <target> - Kills a target player

We first register the first /kill command as normal:

new CommandAPICommand("kill")
    .executesPlayer((player, args) -> {
        player.setHealth(0);
    })
    .register();

Now we declare our command with arguments for our second command. Then, we can register our second command /kill <target> as usual:

// Declare our arguments
LinkedHashMap<String, Argument> arguments = new LinkedHashMap<>();
arguments.put("target", new PlayerArgument());

// Register our second /kill <target> command
new CommandAPICommand("kill")
    .withArguments(arguments)
    .executesPlayer((player, args) -> {
        ((Player) args[0]).setHealth(0);
    })
    .register();

This gives us the ability to run both /kill and /kill <target> with the same command name "kill", but have different results based on the arguments used.