Skip to content
Federico López edited this page Mar 8, 2021 · 8 revisions

Commodore allows you to define arguments for the tab-completion.
Depending on how the commodore-file looks like or what options you use in the LiteralArgumentBuilder will the defined arguments either show up in the tab completion or not.

General format

The .commodore and LiteralArgumentBuilder offer both a specific syntax that should be followed.

.commodore file

The .commodore file's follows a syntax similar to JSON with some differences to it.
It may look like this:

<command> {
  <literal>;
  <literal> {
    <argument> brigadier:<type>;
  }
  <literal> {
    <literal>;
    <argument> brigadier:<type> <option>;
  }
}

The first argument (<command>) always has to be the command to apply the suggestions towards.
It cannot have any of the different options applied.

Any arguments afterwards can be either a <literal> String or <argument> String.

  • <literal> is, as the name suggests, a literal string that would show up in the argument list of the tab-completion.
    This means that whatever you set for this String would be selectable from the tab-completion menu. Adding any options to it turns it into an <argument>.
  • <argument>s are placeholder text used for where you would insert custom input. They are set by adding any brigadier: option to the String itself.

Code

You use the LiteralArgumentBuilder from the Brigadier Library to set the different arguments.
The same structure from the .commodore file example would look like this in Java:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("<command>")
        .then(LiteralArgumentBuilder.literal("<literal>"))
        .then(LiteralArgumentBuilder.literal("<literal>")
            .then(RequiredArgumentBuilder.argument("<argument>", ArgumentType<?>))
        )
        .then(LiteralArgumentBuilder.literal("<literal>")
            .then(LiteralArgumentBuilder.literal("<literal>"))
            .then(RequiredArgumentBuilder.argument("<argument>", ArgumentType<?>))
        )
        .build();

The first option has to be LiteralArgumentBuilder.literal(String) as it defines the command name similar to the .commodore file format.
After that can you use then(ArgumentBuilder<S, ?>) to chain additional arguments to the CommandNode before using build() to actually build it.

Each then is handled on the same level unless you add a then after either LiteralArgumentBuilder.literal(String) or RequiredArgumentBuilder.argument(String, ArgumentType<?>) which may look like this:

LiteralArgumentBuilder.literal("argument")
    .then(RequiredArgumentBuilder.argument("string", StringArgumentType.greedyString())

In the above example would you first get argument as a selectable option before you can define any type of String as the argument after it.

Limitations

There are certain limitations when using the Commodore Library, which mostly comes from the Brigadier library:

  • You can only have one <argument> per level. It is not possible to define multiple arguments on the same level. Once you set an argument can only extra <literals> be defined and used.

    Example: This .commodore format is valid:

    time {
      set {
        day;
        noon;
        night;
        midnight;
        time brigadier:integer;
      }
      add {
        time brigadier:integer;
      }
    }
    

    while this one is not:

    time {
      set {
        day;
        noon;
        night;
        midnight;
        time brigadier:integer;
        moretime brigadier:integer;
      }
      add {
        time brigadier:integer;
      }
    }
    

Argument Types

Brigadier offers different Types of Arguments to use which Commodore supports.
This allows you to define what type of input is acceptable for the specific argument.

The most basic one is the ArgumentType<?> which all other Types extend and that can be used to create your own Type if needed.
It, however, cannot be used directly in the RequiredArgumentBuilder methods.

String

Any text provided would be treated as a String.

.commodore file example:

teleport {
  player brigadier:string single_word;
}

Code example:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("teleport")
        .then(RequiredArgumentBuilder.argument("player", StringArgumentType.word())
        .build();

String Options

The String type is the only one where the option needs to be defined.

  • single_word / StringArgumentType.word() allows a single word to be set.
  • quotable_phrase / StringArgumentType.string() allows either a single word or multiple ones enclosed in ' or ".
  • greedy_phrase / StringArgumentType.greedyString() allows any amount of words.
    This option can only be used in the very last argument, since it takes an infinite amount of words.

Integer

Any text provided would be treated as an Integer number.

.commodore file example:

number {
  number brigadier:integer;
  random {
    min brigadier:integer 1 {
      max brigadier:integer 1 100;
    }
  }
}

Code example:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("number")
        .then(RequiredArgumentBuilder.argument("number", IntegerArgumentType.integer())
        .then(LiteralArgumentBuilder.literal("random")
            .then(RequiredArgumentBuilder.argument("min", IntegerArgumentType.integer(1))
                .then(RequiredArgumentBuilder.argument("max", IntegerArgumentType.integer(1, 100)))
            )
        )
        .build();

Integer Options

  • <min> / IntegerArgumentType.integer(<min>) defines the lowest number allowed for this argument.
  • <min> <max> / IntegerArgumentType.integer(<min>, <max>) defines the lowest and highest numbers allowed for this argument. You cannot set the max number alone. You can however use Integer.MIN_VALUE for the code option to set it to the lowest number possible by Java.

Long

The long option is similar to Integer but accepts much higher (or lower) numbers.

.commodore file example:

number {
  number brigadier:long;
  random {
    min brigadier:long 1 {
      max brigadier:long 1 100;
    }
  }
}

Code example:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("number")
        .then(RequiredArgumentBuilder.argument("number", LongArgumentType.longArg())
        .then(LiteralArgumentBuilder.literal("random")
            .then(RequiredArgumentBuilder.argument("min", LongArgumentType.longArg(1L))
                .then(RequiredArgumentBuilder.argument("max", LongArgumentType.longArg(1L, 100L)))
            )
        )
        .build();

Long Options

  • <min> / IntegerArgumentType.integer(<min>) defines the lowest number allowed for this argument.
  • <min> <max> / IntegerArgumentType.integer(<min>, <max>) defines the lowest and highest numbers allowed for this argument. You cannot set the max number alone. You can however use Long.MIN_VALUE for the code option to set it to the lowest number possible by Java.

Float

The float option allows to accept numbers with decimals in them.

.commodore file example:

number {
  number brigadier:float;
  random {
    min brigadier:float 0.1 {
      max brigadier:float 0.1 100.0;
    }
  }
}

Code example:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("number")
        .then(RequiredArgumentBuilder.argument("number", FloatArgumentType.floatArg())
        .then(LiteralArgumentBuilder.literal("random")
            .then(RequiredArgumentBuilder.argument("min", FloatArgumentType.floatArg(0.1f))
                .then(RequiredArgumentBuilder.argument("max", FloatArgumentType.floatArg(0.1f, 100.0f)))
            )
        )
        .build();

Float Options

  • <min> / FloatArgumentType.floatArg(<min>) defines the lowest number allowed for this argument.
  • <min> <max> / FloatArgumentType.floatArg(<min>, <max>) defines the lowest and highest numbers allowed for this argument. You cannot set the max number alone. You can however use Float.NEGATIVE_INFINITY for the code option to set it to the lowest number possible by Java.

Double

The double option is similar to float but accepts much higher (or lower) values.

.commodore file example:

number {
  number brigadier:double;
  random {
    min brigadier:double 0.1 {
      max brigadier:dounle 0.1 100.0;
    }
  }
}

Code example:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("number")
        .then(RequiredArgumentBuilder.argument("number", DoubleArgumentType.doubleArg())
        .then(LiteralArgumentBuilder.literal("random")
            .then(RequiredArgumentBuilder.argument("min", DoubleArgumentType.doubleArg(0.1))
                .then(RequiredArgumentBuilder.argument("max", DoubleArgumentType.doubleArg(0.0, 100.0)))
            )
        )
        .build();

Float Options

  • <min> / DoubleArgumentType.doubleArg(<min>) defines the lowest number allowed for this argument.
  • <min> <max> / DoubleArgumentType.doubleArg(<min>, <max>) defines the lowest and highest numbers allowed for this argument. You cannot set the max number alone. You can however use Double.NEGATIVE_INFINITY for the code option to set it to the lowest number possible by Java.

Boolean

The boolean type option allows to only accept true or false as valid options.

.commodore file example:

fly {
  enable brigadier:bool;
}

Code example:

LiteralCommandNode<?> command = LiteralArgumentBuilder.literal("fly")
        .then(RequiredArgumentBuilder.argument("enable", BoolArgumentType.bool())
        .build();

Boolean Options

This is the only Type that does not have any options, as the values can only be true or false.