Grenadier is a library for Paper that allows developers to use the Brigadier command engine developed by Mojang without having to interact with NMS classes all the while providing access to a lot of the powerful features Brigadier brought with it.
Check out the project on GitHub here and the Javadoc documentation
The project also comes with lots of built-in argument parsers and utilities so you don't have to rewrite something that already exists in vanilla, you can see those all listed below.
On top of this, each argument type is mapped to a vanilla counterpart which allows for grenadier's command trees to be translated into vanilla trees so they can provide more info during input for the client, and show distinct colors in chat to let you know what kind of argument you're typing. Not to mention the error messages which give more detail on where an error ocurred during parsing.
Support is also provided for custom ArgumentTypes
You can then create commands by extending the
Currently, an annotation extension (inspired by Aikar's command framework) is being worked on to remove a lot of boilerplate and hassle involved in writing commands. Here's an example of how that should look like:
General use argument types
Minecraft argument types
You can add it to your projects like so:
Check out the project on GitHub here and the Javadoc documentation
The project also comes with lots of built-in argument parsers and utilities so you don't have to rewrite something that already exists in vanilla, you can see those all listed below.
On top of this, each argument type is mapped to a vanilla counterpart which allows for grenadier's command trees to be translated into vanilla trees so they can provide more info during input for the client, and show distinct colors in chat to let you know what kind of argument you're typing. Not to mention the error messages which give more detail on where an error ocurred during parsing.
Support is also provided for custom ArgumentTypes
You can then create commands by extending the
net.forthecrown.grenadier.AbstractCommand
abstract class, for example:
Java:
import net.forthecrown.grenadier.AbstractCommand;
public class ExampleCommand extends AbstractCommand {
public ExampleCommand() {
super("example_command");
register();
}
public void createCommand(GrenadierCommand command) {
command.executes(context -> {
CommandSource source = context.getSource();
source.sendMessage("Hello, world!");
return 0;
});
}
}
Currently, an annotation extension (inspired by Aikar's command framework) is being worked on to remove a lot of boilerplate and hassle involved in writing commands. Here's an example of how that should look like:
Java:
@CommandData("""
name = 'annotation_example'
aliases = alias1
| alias2
argument(@argument_name, greedy_string) {
executes = run()
}
""")
public class TestCommand2 {
static final String THING_ARGUMENT = "thing";
@VariableInitializer
void initLocalVariables(Map<String, Object> variables) {
variables.put("argument_name", THING_ARGUMENT);
}
public void run(CommandContext<CommandSource> context,
@Argument(THING_ARGUMENT) String input
) {
context.getSource().sendMessage(input);
}
}
General use argument types
Argument type | Description | Example |
---|---|---|
OptionsArgument | Parse a list of pre-set options and flags | key=value -flag |
MapArgument | Takes a string 2 object map and parses a map value via its string key | a_value |
EnumArgument | Parses an enum constant from it's Enum.name() | red |
ArrayArgument | Parses a List of a specified type of arguments | minecraft:stone,minecraft:eek:ak_log |
LocalDateArgument | Parses a LocalDate object from the ISO-8601 format | 12-12-2023 |
TimeArgument | Parses a Duration | 3s , 3seconds , 5m , 5minutes |
Minecraft argument types
Argument type | Description | Example |
---|---|---|
BlockArgument | Parses a block state and optionally NBT data that can be applied to a block | minecraft:chest[facing=west]{dataKey:1b} |
BlockFilterArgument | Parses a block or block tag that can be used to as a predicate for blocks | #minecraft:buttons[face=ceiling] |
ComponentArgument | Parses a text component from a JSON format | {"text":"Some text","color":"red"} |
EntityArgument | Parses an entity selector that returns 1 or more entities/players | @e[limit=1,distance=..2] |
GameModeArgument | Game mode value from a non-vanilla set of labels | creative, survival, c, s |
ItemArgument | Parses an itemstack along with item NBT data | minecraft:stone{nbtKey:1b} |
ItemFilterArgument | Parses an item or itemtag along with NBT data that will be used as a predicate against other items | #minecraft:flowers{nbtKey:1b} |
KeyArgument | Parses a namespaced key | minecraft:stone |
NbtArgument | Parses NBT data in the SNBT format | {foo:'bar',abc:1b} |
ObjectiveArgument | Parses a scoreboard objective from its name | deaths, noClip |
ParticleArgument | Parses a particle by its key | minecraft:explosion_emitter |
PositionArgument | Parses a relative/local/absolute 2D or 3D position | ~ ~ ~ |
TagPathArgument | Parses an NBT path | key1.key2[] |
TeamArgument | Parses a scoreboard team from its name | team1 , Team2 |
UuidArgument | Parses a UUID by its hexadecimal value | 21290ce5-679c-4917-b30e-168c0d450c72 |
WorldArgument | Parses a world by its name | world , world_the_end |
DoubleRangeArgument | Parses an inclusive range of double values | 1..2 , 1.. , ..3 |
IntRangeArgument | Parses an inclusive range of integer values | 1..2 , 1.. , ..3 |
You can add it to your projects like so:
Code:
repositories {
mavenCentral()
// Brigadier's repository
maven("https://libraries.minecraft.net")
}
dependencies {
// Grenadier
implementation("net.forthecrown:grenadier:2.0.6")
// Mojang's Brigadier
compileOnly("com.mojang:brigadier:1.0.18")
}