Brigadier Command API

PotatoMC features a native implementation of Mojang's Brigadier command tree architecture, providing type-safe arguments, nested subcommands, and tab-completion suggestions.

1. Creating Commands

Commands are constructed using fluent builder trees with Command::tree("name"):

use potato_api::command::{Command, CommandContext, CommandResult, CommandSender, Argument};
use potato_api::text::Component;

let cmd = Command::tree("spawn")
    .description("Teleport to the server spawn point")
    .alias("hub")
    .executes(|ctx: &CommandContext| -> CommandResult {
        match ctx.sender() {
            CommandSender::Player(player) => {
                player.send_message("§aTeleporting to spawn...");
                // player.teleport(spawn_location);
            }
            CommandSender::Console(console) => {
                console.send_message("Only players can teleport to spawn!");
            }
        }
        Ok(())
    });

2. Type-Safe Arguments

You can append strongly-typed arguments to the command tree. Brigadier automatically handles validation and tab-completion for these argument types before your executor is even called.

let heal_cmd = Command::tree("heal")
    .requires(|sender| sender.has_permission("potato.command.heal"))
    .then(
        Argument::player("target")
            .executes(|ctx| {
                let target = ctx.get_player("target")?;
                target.set_health(20.0);
                ctx.sender().send_message(&format!("Healed {}", target.name()));
                Ok(())
            })
    )
    .executes(|ctx| {
        // Heal self if no target specified
        if let CommandSender::Player(player) = ctx.sender() {
            player.set_health(20.0);
            player.send_message("You have been healed!");
        }
        Ok(())
    });

3. Permissions & Requirements

Use the .requires() closure to specify who is allowed to execute or even see the command in their tab-completion menu.

  • sender.has_permission("node")
  • sender.is_player()
  • sender.is_console()
  • sender.is_op()