Skip to main content

Creating Your First Command

To create a custom command, create a class or object that extends Command:
import gg.essential.api.commands.Command
import gg.essential.api.commands.DefaultHandler

object MyCommand : Command("mycommand") {
    @DefaultHandler
    fun handle() {
        println("Command executed!")
    }
}
Then register it:
MyCommand.register()

Kotlin vs Java

The Command API works in both Kotlin and Java. Here’s the same command in both languages:
object MyCommand : Command("mycommand") {
    @DefaultHandler
    fun handle() {
        println("Command executed!")
    }
}
In Kotlin, it’s recommended to use object instead of class for commands to ensure a single instance.

Default Handler

The @DefaultHandler annotation marks a function to be invoked when:
  1. The command has no subcommands, OR
  2. The user didn’t specify a subcommand
If no @DefaultHandler is specified and no subcommand is matched, the command’s usage will be printed instead.
object MyCommand : Command("mycommand") {
    @DefaultHandler
    fun handle() {
        // Called when user types: /mycommand
    }

    @SubCommand("test")
    fun test() {
        // Called when user types: /mycommand test
    }
}

Command with Arguments

Arguments are automatically parsed based on your function parameters:
object MyCommand : Command("mycommand") {
    @DefaultHandler
    fun handle(number: Int, choice: Boolean?) {
        // number is required
        // choice is optional (nullable)
        println("Number: $number, Choice: $choice")
    }
}

Usage Examples

User InputResult
/mycommand 5handle(5, null)
/mycommand 5 truehandle(5, true)
/mycommand 5 falsehandle(5, false)
/mycommand abc trueError: Usage printed

Auto-Generated Usage Messages

When a user provides invalid arguments, Essential automatically generates helpful usage messages:
Usage: /mycommand <number> [choice]
  • <required> - Required parameters
  • [optional] - Optional parameters

Custom Parameter Names

If your build process wipes parameter names, or you want custom names in the usage message, use the @DisplayName annotation:
@DefaultHandler
fun handle(
    @DisplayName("amount") number: Int,
    @DisplayName("enabled") choice: Boolean?
) {
    // Usage: /mycommand <amount> [enabled]
}

Command Configuration

Constructor Parameters

abstract class Command(
    val name: String,
    val autoHelpSubcommand: Boolean = true,
    val hideFromAutocomplete: Boolean = false
)

name

The command name. Your command will be invoked as /$name.

autoHelpSubcommand

Whether to automatically generate a help subcommand (i.e., /$name help) that shows all available subcommands, their usages, and descriptions. Default: true
object MyCommand : Command(
    name = "mycommand",
    autoHelpSubcommand = true
)

hideFromAutocomplete

Whether to hide this command from Minecraft’s command tab completion. Default: false
object DebugCommand : Command(
    name = "debug",
    hideFromAutocomplete = true
)

Command Aliases

Define global aliases using the commandAliases property:
object MyCommand : Command("mycommand") {
    override val commandAliases = setOf(
        Alias("mc"),
        Alias("mycmd", hideFromAutocomplete = true)
    )

    @DefaultHandler
    fun handle() {
        // Can be invoked with /mycommand, /mc, or /mycmd
    }
}
Each Alias can optionally be hidden from autocomplete:
data class Alias(
    val alias: String,
    val hideFromAutocomplete: Boolean = false
)

Complete Example

Here’s a complete example with multiple features:
import gg.essential.api.commands.*

object TeleportCommand : Command(
    name = "tp",
    autoHelpSubcommand = true
) {
    override val commandAliases = setOf(
        Alias("teleport")
    )

    @DefaultHandler
    fun handle(@DisplayName("player") target: String) {
        // Teleport to player
        println("Teleporting to $target")
    }

    @SubCommand("coords", description = "Teleport to coordinates")
    fun coords(x: Int, y: Int, z: Int) {
        println("Teleporting to $x, $y, $z")
    }

    @SubCommand("random", description = "Teleport to random location")
    fun random(radius: Int?) {
        val r = radius ?: 1000
        println("Teleporting to random location within $r blocks")
    }
}

// Register the command
fun init() {
    TeleportCommand.register()
}

Next Steps

Arguments

Learn about the argument parsing system

Subcommands

Create complex command structures

Build docs developers (and LLMs) love