Creating commands

Declare a command the way players type it. WYSIWYG.

Endstone commands are declared as usage strings: you write the command the way a player types it, and Endstone parses that string to build the argument structure and wire up Bedrock's native, client-side tab-completion for you. What you write is what the player sees.

Why a usage string

Most server frameworks make you trade one thing for another:

  • Brigadier-style builders (Bukkit/Paper) have you assemble a tree of argument nodes by hand, nesting builder calls inside builder calls. It's powerful, but verbose, and the shape of the command is buried in the code.
  • Nukkit-style registration keeps the code flat, but you lose Bedrock's client-side autocomplete - players get no parameter hints as they type.

Endstone takes neither path. You declare a single line - /give <player: target> <item: str> [amount: int] - and Endstone parses it into typed parameters, registers them so the Bedrock client shows native tab-completion and parameter hints, and hands your handler the parsed arguments. No nested builders, no lost autocomplete: the usage string is the source of truth.

How you attach that string to a command differs by language - see your track's setup guide for the exact call.

Parameters

A usage string is the command name followed by zero or more parameters. There are two kinds:

KindDescriptionSyntax
MandatoryMust be provided<name: type>
OptionalCan be omitted[name: type]

So /hello [msg: message] declares one optional msg parameter of type message; switch the brackets to /hello <msg: message> to make it mandatory. Parameters read left to right, exactly as the player types them.

Overloads

A command can declare multiple usage strings, and each one is an overload. The client suggests whichever overloads match what the player has typed so far - the same way vanilla commands like /give offer different forms. Endstone merges them into a single autocomplete tree.

Built-in types

Each parameter has a type that drives both validation and the client's suggestions. Endstone ships these out of the box:

TypeAliasDescriptionExample
intAn integer10
floatA floating-point number3.14
boolA booleantrue
targetactor, entity, playerA target selector@e, @r, PlayerName
strstringA string, terminated by a spaceHello
block_posvec3iA 3D integer position1 2 3
posvec3, vec3fA 3D float position1.0 2.0 3.0
messageEverything until the end of the lineHello World!
jsonA JSON string{"key": "value"}
blockA block typewood
block_statesBlock states["wood_type"="birch","stripped_bit"=true]
entity_typeAn entity typeminecraft:creeper

Because the message type captures everything up to the end of the line, it must be the last parameter in a usage string - Endstone refuses to register a command that places any parameter after a message.

Enum parameters

To accept one of a fixed set of values, use an enum parameter. There are two ways to write one.

Short form

List the values right inside the parameter brackets, separated by |, with no name or type:

  • Mandatory: <value1|value2|value3>
  • Optional: [value1|value2|value3]

For example, /home <add|list|del> lets the player pick add, list, or del, and the client suggests exactly those. Endstone generates the parameter name and the enum type for you, so this is the quickest way to a choice parameter - prefer it for up to about five values.

Full form

The Bedrock client only spells out the inline add|list|del hint while the set is small. Past about five values it stops listing them and shows the parameter as <name: EnumType> instead - and with the short form that name is the one Endstone auto-generated by concatenating the command name and every value (/home <add|list|del> becomes HomeAddListDel), which reads as noise to the player. Past about five values, name the type yourself so the hint stays meaningful: put the values in parentheses, then give the parameter a name and an enum type:

  • Mandatory: (value1|value2|value3)<name: EnumType>
  • Optional: (value1|value2|value3)[name: EnumType]

For example, /warp (home|spawn|shop|mine|nether|end)<destination: WarpTarget> declares a destination parameter of type WarpTarget. A named type stays readable and can be reused across commands.

Enum types behave like string-literal unions in TypeScript or Python: a named set of allowed constants. Because the client autocompletes them, players never have to guess the valid values.

On this page