Skip to content

Creating Commands Using Annotations

Matthias Ngeo edited this page Jun 2, 2020 · 26 revisions

Overview

Commands built through CommandNodeBuilders can sometimes become a mess, especially if a command is complex. Command annotations aim to solve that issue by automatically binding fields and methods to commands, thereby eliminating the need to do so by hand. Command annotations were first introduced in 4.1.0 and subsequently overhauled in 4.6.0 to support ahead-of-time compilation. Annotations are parsed and then used to generate a corresponding Java source file at compile-time. Since everything is resolved at compile-time, there is zero reliance on reflection and hence minimal runtime overhead.

This guide provides a walkthrough of the creation of the same tell command in getting started but using annotations instead.

To quote the description of the tell command in getting started,

Our tell command allows a player to send a message to one or more other players. It's syntax is /tell|t <player>|> <players> <messages>. Suggestions are provided for each argument. For <player> and <players>, it's the > names of visible, online players. For <messages>, it's Hello World!. Lastly, the message, Hello darkness my old > friend is displayed if no arguments are given.


Command Markup Language

Command annotations contains an extremely simple markup language used to declare commands within annotations.

A command is a sequence of arguments and literals that should start with a literal. An argument can be declared by surrounding its name in < and >, e.g. <argument_name>. A literal can be declared using its name, with aliases separated by |, e.g. command|alias_1|alias_2. All names and aliases should not contain whitespaces.

That's all, it wasn't too bad was it? In addition, the library will catch most mistakes during compilation and provide explanations to help you fix the issue.

For programming language nerds, the ABNF for the markup language is:

command  = literal *(argument / literal)
argument = "<" name ">"
literal  = name *("|" name)
name     = 1*(%x21 - %x59 / %x3D / %x3F - %7B / %x7D - %x7E) 

Declaring the tell command

Clone this wiki locally