-
-
Notifications
You must be signed in to change notification settings - Fork 115
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
Strokkur424
wants to merge
55
commits into
PaperMC:main
Choose a base branch
from
Strokkur424:improve-brigadier-docs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,518
−2
Draft
Changes from 33 commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
159f2d4
Add introduction page
Strokkur424 86fbcbd
Move comparison to seperate file
Strokkur424 b541bf5
Add missing files!
Strokkur424 aedbde5
Improve introduction page
Strokkur424 5a67905
Update docs/paper/dev/api/command-api/introduction.mdx
Strokkur424 e65c570
Update docs/paper/dev/api/command-api/introduction.mdx
Strokkur424 a63eec3
Create command tree site
Strokkur424 473c518
Merge branch 'improve-brigadier-docs' of https://github.com/Strokkur4…
Strokkur424 96c0352
Remove titles from code blocks
Strokkur424 efb22e3
Revisit comparison page
Strokkur424 ac4ef8b
Improvements to the command tree site
Strokkur424 548eae0
Create command execution page
Strokkur424 9c8f087
Commit unsaved changes
Strokkur424 c165ade
Decrease tree art size
Strokkur424 57cbd19
Move newlines
Strokkur424 0d0f9f2
Add arguments-and-literals site
Strokkur424 d1d6355
Fix spelling mistake
Strokkur424 c3a721f
Reverse gamemode tree
Strokkur424 d0dbb30
Slight improvements to the arguments page
Strokkur424 4b0ed02
Add command executor site
Strokkur424 1147109
Slight modifications
Strokkur424 f55c87b
Fix incorrect link
Strokkur424 834c010
Add command registration site
Strokkur424 a6ec90d
Fix broken link
Strokkur424 c7a3e70
Change titles
Strokkur424 f9122d1
Move previous documentation to seperate category for better organization
Strokkur424 e6e4074
...forgor to git add the new files
Strokkur424 968b639
blockPosition, blockState, and component arguments
Strokkur424 f6a7605
doubleRange, entity, entities arguments
Strokkur424 f786b2c
Hopefully fix all issues
Strokkur424 1aa2359
Convert gifs to mp4s
Strokkur424 b3f1561
Add entity anchor, fine position, gamemode, heightmap, integerrange, …
Strokkur424 14d2f89
Format
Strokkur424 797cf99
Add namespaced and objective criteria arguments
Strokkur424 e356556
Fix casing for argument titles
Strokkur424 221361d
Fixup
Strokkur424 81a974f
Add player, players, playerprofiles, scoreboarddisplayslot, signedmes…
Strokkur424 dc67f62
Rebase main branch
Strokkur424 51411ae
Basic restructure
Strokkur424 d5e7233
Finish migrating arguments to seperate pages
Strokkur424 95cd544
Revert "Finish migrating arguments to seperate pages"
Strokkur424 f9c122b
Migrate arguments to seperate pages
Strokkur424 7fde946
Fix spelling mistakes
Strokkur424 aa67a4b
Final fixup
Strokkur424 bbbd32d
Update docs/paper/dev/api/command-api/arguments/adventure-arguments.mdx
Strokkur424 0edb936
Add showcase videos and basic registry argument file structure
Strokkur424 e93ac96
Fix assets
Strokkur424 47a52c7
Rename Brigadier and Bukkit comparison page title
Strokkur424 7063436
Merge branch 'improve-brigadier-docs' of github.com:Strokkur424/paper…
Strokkur424 72f01f2
Add registry preview videos
Strokkur424 e383051
Registry arguments
Strokkur424 9dc9d4b
Fix spelling
Strokkur424 55997df
Fix broken anchors
Strokkur424 686529e
Add BasicCommand documentation
Strokkur424 d5441c7
Fix spelling and wording
Strokkur424 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
189 changes: 189 additions & 0 deletions
189
docs/paper/dev/api/command-api/arguments-and-literals.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | | ||
| 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 added
BIN
+803 KB
docs/paper/dev/api/command-api/assets/vanilla-arguments/blockposition.mp4
Binary file not shown.
Binary file added
BIN
+763 KB
docs/paper/dev/api/command-api/assets/vanilla-arguments/blockstate.mp4
Binary file not shown.
Binary file added
BIN
+1.02 MB
docs/paper/dev/api/command-api/assets/vanilla-arguments/component.mp4
Binary file not shown.
Binary file added
BIN
+819 KB
docs/paper/dev/api/command-api/assets/vanilla-arguments/doublerange.mp4
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+5.26 MB
docs/paper/dev/api/command-api/assets/vanilla-arguments/entity-opped.mp4
Binary file not shown.
Binary file added
BIN
+2.64 MB
docs/paper/dev/api/command-api/assets/vanilla-arguments/entity-unopped.mp4
Binary file not shown.
Binary file added
BIN
+640 KB
docs/paper/dev/api/command-api/assets/vanilla-arguments/entityanchor.mp4
Binary file not shown.
Binary file added
BIN
+263 KB
docs/paper/dev/api/command-api/assets/vanilla-arguments/fineposition.mp4
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+951 KB
docs/paper/dev/api/command-api/assets/vanilla-arguments/integerrange.mp4
Binary file not shown.
Binary file added
BIN
+1.61 MB
docs/paper/dev/api/command-api/assets/vanilla-arguments/itempredicate.mp4
Binary file not shown.
Binary file added
BIN
+1.26 MB
docs/paper/dev/api/command-api/assets/vanilla-arguments/itemstack.mp4
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+1.01 MB
docs/paper/dev/api/command-api/assets/vanilla-arguments/namedcolor.mp4
Binary file not shown.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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:+
,-
,_
,.
.There was a problem hiding this comment.
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!