Skip to content

Command Arguments

Redempt edited this page Nov 16, 2021 · 6 revisions

You may have noticed a crucial thing missing from the previous pages: Arguments. Commands need arguments. But arguments are not always straightforward. RedLib has a broad set of tools to ensure that you can always easily get the information you need from your command's arguments.

In the command file, arguments are specified right after the command's name. It looks like this:

commandname string:argname {
	help This is the help for this command
	hook hookname
}

This command takes a string argument whose name is argname. If a user runs this command without specifying the argument, they will be shown the command's help page. Now that you've added an argument to your command, however, you need to take that argument in your method hook:

@CommandHook("hookname")
public void doSomething(CommandSender sender, String arg) {
	//Do stuff
}

This is the most basic example of command arguments, but they can get a lot more advanced than this. For example, sometimes you need to take an int rather than a String. That's easy:

commandname int:arg {
	hook hookname
	help This is command help
}

Now, in your command hook, you would simply take an int instead of String:

@CommandHook("hookname")
public void doSomething(CommandSender sender, int arg) {
	//Do stuff
}

If the user specifies an argument which is not an int, or doesn't give that argument, they will be shown the help menu. This saves time having to cast types and check for errors.

The default types supported by command manager are int, double, string, long, float, boolean, and player. They all work the same: You take the same type in your method hook, and if the player provides an invalid value to be parsed into that type, they will be shown the help screen.

Sometimes, however, you need more flexibility with your command's arguments. Let's talk about command argument metadata.

First, we have to discuss how the help entry is generated. When you run a command incorrectly, you will generally be shown this menu. For the above example, it would look like this:

/commandname <int:arg> : This is command help

Sometimes you don't want to show the type of the argument because it's implied. In those cases, you can put * at the end of your command argument, like this:

commandname int:arg* {
	hook hookname
	help This is command help
}

Now, the help entry will look like this:

/commandname <arg> : This is command help

But you need control over a lot more than just what the help entry looks like. Sometimes you don't need the argument to be specified, because you can assume what it will be if it's not passed. You can specify optional arguments like this:

commandname int:arg? {
	hook hookname
	help This is command help
}

If the argument is not specified, the argument will now be passed as null rather than showing the player the help menu. If you're using an optional argument, make sure to not use primitive types like int, which are non-nullable and will throw errors if null is passed. Optional arguments can also have default values specified which will be passed instead of null. You can do that like this:

commandname int:arg?(1) {
	hook hookname
	help This is command help
}

In this case, if the argument isn't specified, the value will be passed as 1 instead of null.

Additionally, sometimes you need to take all of the remaining text into a single argument, like for a broadcast command. You can do that similarly to how you define a vararg in Java:

broadcast string...:message {
	hook broadcast
	help Broadcasts a message to the entire server
}

Without the ..., a player would be shown an error if they tried to run /broadcast a b. Now, "a b" will be passed as a single String. However, an argument with ... must be the last argument in its command.

Similarly, you can use [] to specify that the arguments should be taken and parsed individually and passed as an array rather than passed to the converter as a single string including spaces:

kill player[]:targets {
	help Kills one or several players
	hook kill
}

The parameter type in the method hook for this argument should be Player[]. If the argument is not marked as optional, at least one value must be supplied. Otherwise, an array of length 0 will be passed if no arguments are supplied.

Of course, you can combine all of these modifiers: string...:message*?(hello). And while only single-argument commands were covered so far, you can specify multiple command arguments separated by a space:

commandname int:arg string:arg2 {
	hook hookname
	help This is command help
}

The hook method for this command would look like this:

@CommandHook("hookname")
public void doSomething(CommandSender sender, int number, String text) {
	//Do stuff
}

Now you know how to specify arguments for your commands, so that they can get much more specific in their purpose. However, the values that a command can take are often more complex than just strings, numbers, and players. To learn how to define your own types of command arguments with their own tab completions, read on to the Custom Argument Types page.

Clone this wiki locally