Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Improve Brigadier Documentation #507

Draft
wants to merge 55 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
159f2d4
Add introduction page
Strokkur424 Dec 14, 2024
86fbcbd
Move comparison to seperate file
Strokkur424 Dec 14, 2024
b541bf5
Add missing files!
Strokkur424 Dec 14, 2024
aedbde5
Improve introduction page
Strokkur424 Dec 14, 2024
5a67905
Update docs/paper/dev/api/command-api/introduction.mdx
Strokkur424 Dec 14, 2024
e65c570
Update docs/paper/dev/api/command-api/introduction.mdx
Strokkur424 Dec 14, 2024
a63eec3
Create command tree site
Strokkur424 Dec 14, 2024
473c518
Merge branch 'improve-brigadier-docs' of https://github.com/Strokkur4…
Strokkur424 Dec 14, 2024
96c0352
Remove titles from code blocks
Strokkur424 Dec 14, 2024
efb22e3
Revisit comparison page
Strokkur424 Dec 14, 2024
ac4ef8b
Improvements to the command tree site
Strokkur424 Dec 15, 2024
548eae0
Create command execution page
Strokkur424 Dec 15, 2024
9c8f087
Commit unsaved changes
Strokkur424 Dec 15, 2024
c165ade
Decrease tree art size
Strokkur424 Dec 15, 2024
57cbd19
Move newlines
Strokkur424 Dec 15, 2024
0d0f9f2
Add arguments-and-literals site
Strokkur424 Dec 15, 2024
d1d6355
Fix spelling mistake
Strokkur424 Dec 15, 2024
c3a721f
Reverse gamemode tree
Strokkur424 Dec 15, 2024
d0dbb30
Slight improvements to the arguments page
Strokkur424 Dec 15, 2024
4b0ed02
Add command executor site
Strokkur424 Dec 15, 2024
1147109
Slight modifications
Strokkur424 Dec 15, 2024
f55c87b
Fix incorrect link
Strokkur424 Dec 15, 2024
834c010
Add command registration site
Strokkur424 Dec 17, 2024
a6ec90d
Fix broken link
Strokkur424 Dec 17, 2024
c7a3e70
Change titles
Strokkur424 Dec 17, 2024
f9122d1
Move previous documentation to seperate category for better organization
Strokkur424 Dec 17, 2024
e6e4074
...forgor to git add the new files
Strokkur424 Dec 17, 2024
968b639
blockPosition, blockState, and component arguments
Strokkur424 Dec 17, 2024
f6a7605
doubleRange, entity, entities arguments
Strokkur424 Dec 17, 2024
f786b2c
Hopefully fix all issues
Strokkur424 Dec 17, 2024
1aa2359
Convert gifs to mp4s
Strokkur424 Dec 18, 2024
b3f1561
Add entity anchor, fine position, gamemode, heightmap, integerrange, …
Strokkur424 Dec 18, 2024
14d2f89
Format
Strokkur424 Dec 18, 2024
797cf99
Add namespaced and objective criteria arguments
Strokkur424 Dec 18, 2024
e356556
Fix casing for argument titles
Strokkur424 Dec 18, 2024
221361d
Fixup
Strokkur424 Dec 18, 2024
81a974f
Add player, players, playerprofiles, scoreboarddisplayslot, signedmes…
Strokkur424 Dec 18, 2024
dc67f62
Rebase main branch
Strokkur424 Dec 19, 2024
51411ae
Basic restructure
Strokkur424 Dec 19, 2024
d5e7233
Finish migrating arguments to seperate pages
Strokkur424 Dec 21, 2024
95cd544
Revert "Finish migrating arguments to seperate pages"
Strokkur424 Dec 21, 2024
f9c122b
Migrate arguments to seperate pages
Strokkur424 Dec 21, 2024
7fde946
Fix spelling mistakes
Strokkur424 Dec 21, 2024
aa67a4b
Final fixup
Strokkur424 Dec 21, 2024
bbbd32d
Update docs/paper/dev/api/command-api/arguments/adventure-arguments.mdx
Strokkur424 Dec 21, 2024
0edb936
Add showcase videos and basic registry argument file structure
Strokkur424 Dec 25, 2024
e93ac96
Fix assets
Strokkur424 Dec 25, 2024
47a52c7
Rename Brigadier and Bukkit comparison page title
Strokkur424 Dec 28, 2024
7063436
Merge branch 'improve-brigadier-docs' of github.com:Strokkur424/paper…
Strokkur424 Dec 28, 2024
72f01f2
Add registry preview videos
Strokkur424 Dec 29, 2024
e383051
Registry arguments
Strokkur424 Dec 29, 2024
9dc9d4b
Fix spelling
Strokkur424 Dec 29, 2024
55997df
Fix broken anchors
Strokkur424 Dec 29, 2024
686529e
Add BasicCommand documentation
Strokkur424 Dec 29, 2024
d5441c7
Fix spelling and wording
Strokkur424 Dec 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion config/sidebar.paper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,21 @@ const paper: SidebarsConfig = {
type: "category",
label: "Brigadier Command API",
collapsed: true,
items: ["dev/api/command-api/commands", "dev/api/command-api/arguments"],
items: [
"dev/api/command-api/introduction",
"dev/api/command-api/comparison",
"dev/api/command-api/command-tree",
"dev/api/command-api/arguments-and-literals",
"dev/api/command-api/command-executors",
"dev/api/command-api/registering",
"dev/api/command-api/minecraft-arguments",
],
},
{
type: "category",
label: "Old Brigadier Command API",
collapsed: true,
items: ["dev/api/command-api-old/commands", "dev/api/command-api-old/arguments"],
},
{
type: "category",
Expand Down
189 changes: 189 additions & 0 deletions docs/paper/dev/api/command-api/arguments-and-literals.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
---
slug: /dev/command-api/arguments-and-literals
description: An extensive guide to commands arguments and literals
---

import ValidFloatInput from "./assets/in-game/valid-float.png"
import SmallFloatInput from "./assets/in-game/small-float.png"
import BigFloatInput from "./assets/in-game/big-float.png"
import StringArguments from "./assets/in-game/string-arguments.gif"

# Arguments and Literals

:::note

In the previous site we have looked at the structure of Brigadier commands and how to build up a command tree. If you haven't looked at that site yet, we really recommend doing that
before reading about arguments and literals. You can check out that site [by clicking here](./command-tree)

:::

Each `.then(...)` method of a `LiteralArgumentBuilder<CommandSourceStack>` takes in an abstract `ArgumentBuilder<CommandSourceStack, ?>` object. That abstract ArgumentBuilder
has two implementations: `RequiredArgumentBuilder` and `LiteralArgumentBuilder`. When coding with Brigadier, we create these objects by running either `Commands.literal(String)`
for the `LiteralArgumentBuilder` and `Commands.argument(String, ArgumentType)` for the `RequiredArgumentBuilder`.

For the sake of simplicity, We refer to the `RequiredArgumentBuilder` as a generic argument builder, and the `LiteralArgumentBuilder` as a generic literal builder.

As an explanation to what the difference is, you can picture it like this:
* An argument is a variable input by the user. It is semi-unpredictable, but will always return a valid entry of the object that it is backing.
* A literal is a non-variable input by the user. It is mainly defined as a way to define predictable input, since each literal is a new branch on our command tree.

## Literals
In code, literals generally can not be accessed. Yet, due to the nature of our command tree, we can always know on what literal branch we currently are:
```java
Commands.literal("plant")
.then(Commands.literal("tree") /* Here we are on /plant tree */)
.then(Commands.literal("grass") /* Here we are on /plant grass */);
```

This makes literals perfect for a command like `/gamemode`. The gamemode command has only 4 valid input: `creative`, `survival`, `spectator`, and `adventure`.
We can represent this gamemode command using the following tree:
<p align="center">
```mermaid
stateDiagram-v2
gamemode --> creative
gamemode --> survival
gamemode --> spectator
gamemode --> adventure
```
</p><br></br>
In code, it would look like this:
```java
Commands.literal("gamemode")
.then(Commands.literal("creative")
.executes(ctx -> /* Set player's gamemode to creative */)
)

.then(Commands.literal("survival")
.executes(ctx -> /* Set player's gamemode to survival */)
)

.then(Commands.literal("spectator")
.executes(ctx -> /* Set player's gamemode to spectator */)
)

.then(Commands.literal("adventure")
.executes(ctx -> /* Set player's gamemode to adventure */)
);
```

You may have noticed the use of the `.executes(...)` method. This method defines the execution logic of a node. If the player sends `/gamemode`, without any arguments, it
will not even run, as our root node does not have a executor defined. Contrary, if the player executes `/gamemode creative`, it will run the code in the first `executes` method.
We are not going to go into detail of the stuff that you can do inside a `execute` method, as that is out of scope for this site. If you want to read up on those, you should
check out the [Extensive Guide on Command Execution](./command-executors) after you finish reading this.

## Arguments
Arguments are slightly more complex. They also define a new branch in a tree, but they are not directly predictable. Each argument is created using `Commands.argument(String, ArgumentType<T>)`.
That method returns a `RequiredArgumentBuilder`. The T type parameter declares the return type of the argument, which you can then use inside your `executes` method. That means that
if you put in an `ArgumentType<Integer>`, you can retrieve the value of that argument as an integer, requiring no manual parsing! The only issue is, how do we create an `ArgumentType`
object? There are a few build-in, primitive argument types that you should definitely be aware of:

| Name | Return value | Possible Input | Description |
|-----------------------------------|---------------|-------------------|------------------------------------------------------------------------------------|
| BoolArgumentType.bool() | Boolean | true/false | Only allows a boolean value |
| IntegerArgumentType.integer() | Integer | 253, -123, 0 | Any valid integer |
| LongArgumentType.longArg() | Long | 25418263123783 | Any valid long |
| FloatArgumentType.floatArg() | Float | 253.2, -25.0 | Any valid float |
| DoubleArgumentType.doubleArg() | Double | 4123.242, -1.1 | Any valid double |
| StringArgumentType.word() | String | no_spaces | A single word. May only contain letters and underscores |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The StringArgumentType.word() supports alphanumeric values, and these: +, -, _, ..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will update the description once I will be revising that file, thanks for clearing that up!

| StringArgumentType.string() | String | "with spaces" | A single word, or a valid string with spaces, if quoted |
| StringArgumentType.greedyString() | String | unquoted spaces | The literal written input. May contain any characters. Has to be the last argument |

### Boolean argument type and argument parsing
The BoolArgumentType can be used for enabling/disabling options. Like if we have a `/serverflight` command, which toggles every members ability to fly, we could add a boolean argument
onto that, which would allow for `/serverflight true` and `/serverflight false`:
```java title="ServerFlightCommand.java"
Commands.literal("serverflight")
.then(Commands.argument("allow", BoolArgumentType.bool())
.executes(ctx -> {
boolean allowed = ctx.getArgument("allow", boolean.class);
/* Toggle server flying with this value now */

return Command.SINGLE_SUCCESS;
})
);
```
Here, you can see how one would access an argument in-code. The first parameter for the `Commands.argument(String, ArgumentType)` method takes in the node name. This is not required
by literals, as their name is the same as their value. But here we need a way to access the argument. The parameter of the executes-lambda has a method called
`T getArgument(String, Class<T>)`. The first parameter is the name of the method we want to retrieve. The second parameter is the return value of the argument. As we are using
a boolean argument, we put in `boolean.class` and retrieve the argument value as such. Another thing to notice is the return clause. The executes method requires an integer to be returned.
This is mostly irrelevant, but the `Command` class has a static constant called `SINGLE_SUCCESS`, which you can return, marking the command as successfully executed.

### Number arguments
All of the number arguments (like `IntegerArgumentType.integer()`) have three overloads:

| Overload | Description |
|---------------------------------------------------|-----------------------------------------------------------|
| `IntegerArgumentType.integer()` | Any value between Integer.MIN_VALUE and Integer.MAX_VALUE |
| `IntegerArgumentType.integer(int min)` | Any value between min and Integer.MAX_VALUE |
| `IntegerArgumentType.integer(int min, int max)` | Any value between min and max |

This is particularly useful for filtering out too high or too low input. As an example, we can define a `/flyspeed` command. As the `Player#setFlySpeed(float value)` method only
accepts floats between -1 and 1, where -1 is an inverse direction, it would make sense to limit the values between 0 and 1 for allowed, non-negative speeds. That can be
achieved with the following command tree:
```java title="FlightSpeedCommand.java"
Commands.literal("flyspeed")
.then(Commands.argument("speed", FloatArgumentType.floatArg(0, 1.0f))
.executes(ctx -> {
float speed = ctx.getArgument("speed", float.class);
/* Set player's flight speed */
return Command.SINGLE_SUCCESS;
})
);
```

Now, if we input a valid float between 0 and 1, the command would execute correctly:
<div style={{display: 'inline-block', width: '100%'}}>
<img src={ValidFloatInput} style={{float: 'left', width: '100%'}}/>
</div>

But if we input a too small or too big float, it would throw an error **on the client**:
<div style={{display: 'inline-block', width: '100%'}}>
<img src={SmallFloatInput} style={{float: 'left', width: '50%'}}/>
<img src={BigFloatInput} style={{float: 'right', width: '50%'}}/>
</div><br/><br/>

This is the main advantage of native arguments: The client itself performs simple error checking on the arguments, which makes user experience whilst running a command
way better, as they can see invalid input without sending the command to the server.

### String arguments
There is three string arguments: `word`, `string`, and `greedyString`.

The `word` string argument is the simplest one of these. It only accepts a single word without any quotes or special characters. The only special character you can use is a underscore.
* ✅ `this_is_valid_input`
* ❌ `this is invalid input`
* ❌ `"also_invalid"`
* ✅ `10_numbers_are_valid`
* ❌ `@_@`

The `string` argument is slightly more complicated. If unquoted, it follows the same rules as the `word` argument. Only letters and underscores. But if you put your string into quotes,
you can enter any combination of unicode characters you want to. Special characters, like quotes `"`, can be escaped using a backslash `\`.
* ✅ `this_is_valid_input`
* ✅ `"\"quotes\""`
* ❌ `this is invalid input`
* ✅ `"this is valid input again"`
* ✅ `"also_valid"`
* ✅ `"紙の神"`

The `greedyString` argument is the only argument which does not perform any parsing. Due to its "greedy" nature, it does not allow any arguments after its declaration. That also means, that
any input is completely valid and it requires no quotes. In fact, quotes are counted as literal characters.
* ✅ `this_is_valid_input`
* ✅ `this is valid as well input`
* ✅ `"this is valid input again"`
* ✅ `also_valid`
* ✅ `紙の神`

Here you can see the arguments in action:
<div style={{display: 'inline-block', width: '100%'}}>
<img src={StringArguments} style={{float: 'left', width: '100%'}}/>
</div>

## Further reference
It is suggested that you visit our [Extensive Guide on Command Execution](./command-executors) in order to read more about the `.executes(...)` method. It contains a lot of useful information
that is required for fully understanding Brigadier commands.

### Minecraft arguments
Apart from these build-in Brigadier arguments, countless custom arguments are defined by Paper as well. These can be accessed in a static context with the `ArgumentTypes` class. You
can read more about these **here**. (WIP).

### Custom arguments
Sometimes you want to define your own, custom arguments. For that you can implement the `CustomArgumentType<T, N>` interface. For more details, you should check out **this** site. (WIP).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading