Skip to main content
This guide will walk you through creating a simple command using Blade. We’ll build a /greet command that sends a personalized greeting to a player.

Step 1: Create a Command Class

Create a new Java class for your command. Command methods can be static or instance methods.
package com.example.commands;

import me.vaperion.blade.annotation.command.Command;
import me.vaperion.blade.annotation.command.Description;
import me.vaperion.blade.annotation.command.Permission;
import me.vaperion.blade.annotation.parameter.Name;
import me.vaperion.blade.annotation.parameter.Sender;
import org.bukkit.entity.Player;

public class GreetCommand {
    
    @Command("greet")
    @Description("Send a greeting to a player")
    @Permission("example.greet")
    public void greet(
        @Sender Player sender,
        @Name("player") Player target
    ) {
        sender.sendMessage("Hello " + target.getName() + "!");
        target.sendMessage(sender.getName() + " says hello!");
    }
}
1

Annotate the method

Use @Command to define the command name. The annotation value becomes the command that players type in chat.
2

Add a description

Use @Description to provide a description for your command. This appears in help messages.
3

Set permissions

Use @Permission to restrict who can use the command. Players need this permission to execute the command.
4

Define parameters

  • @Sender marks the command executor (required first parameter)
  • @Name specifies the argument name shown in usage messages
The @Sender parameter is required and must be the first parameter. It represents the entity executing the command (Player, ConsoleCommandSender, etc.).

Step 2: Initialize Blade

In your plugin’s main class, initialize Blade and register your command.
package com.example;

import me.vaperion.blade.Blade;
import me.vaperion.blade.bukkit.BladeBukkitPlatform;
import org.bukkit.plugin.java.JavaPlugin;

public class MyPlugin extends JavaPlugin {
    
    private Blade blade;
    
    @Override
    public void onEnable() {
        // Initialize Blade for the Bukkit platform
        this.blade = Blade.forPlatform(new BladeBukkitPlatform(this))
            .config(cfg -> {
                cfg.commandQualifier("myplugin"); // Optional: namespace for commands
                cfg.defaultPermissionMessage("You don't have permission!"); // Optional
            })
            .build()
            .register(new GreetCommand()); // Register your command instance
        
        getLogger().info("Plugin enabled with Blade!");
    }
}
1

Create Blade instance

Use Blade.forPlatform() with the appropriate platform class (e.g., BladeBukkitPlatform for Bukkit).
2

Configure Blade (optional)

Use .config() to customize settings like command qualifier and permission messages.
3

Build and register

Call .build() to create the Blade instance, then .register() to add your command.
You can register multiple commands at once by chaining .register() calls:
blade.register(new GreetCommand())
     .register(new PayCommand())
     .register(new TeleportCommand());

Step 3: Test Your Command

Build your plugin and copy it to your server’s plugins folder. Start the server and test your command:
/greet Notch
You should see the greeting message appear for both you and the target player!

Adding More Features

Let’s enhance our command with optional parameters and flags:
import me.vaperion.blade.annotation.parameter.Flag;
import me.vaperion.blade.annotation.parameter.Greedy;
import me.vaperion.blade.annotation.parameter.Optional;

public class GreetCommand {
    
    @Command("greet")
    @Description("Send a greeting to a player")
    @Permission("example.greet")
    public void greet(
        @Sender Player sender,
        @Name("player") Player target,
        @Name("message") @Optional @Greedy String customMessage,
        @Flag(value = 's', description = "Silent mode") boolean silent
    ) {
        String message = customMessage != null 
            ? customMessage 
            : "Hello " + target.getName() + "!";
        
        if (!silent) {
            sender.sendMessage("You greeted " + target.getName());
        }
        
        target.sendMessage(sender.getName() + " says: " + message);
    }
}
Now you can use the command in multiple ways:
/greet Notch
  • @Optional makes a parameter optional (it will be null if not provided)
  • @Greedy combines all remaining arguments into a single string
  • @Flag creates a command flag (like -s for silent mode)

Registering Multiple Commands

You can register all commands in a package at once:
@Override
public void onEnable() {
    this.blade = Blade.forPlatform(new BladeBukkitPlatform(this))
        .build()
        // Register all commands in the package
        .registerPackage(MyPlugin.class, "com.example.commands");
}
This will automatically discover and register all command classes in the com.example.commands package and its sub-packages.

Common Patterns

Static Methods

Commands can also be static methods:
public class GreetCommand {
    @Command("greet")
    public static void greet(@Sender Player sender, @Name("player") Player target) {
        // Command logic
    }
}
Register static command classes without instantiation:
blade.register(GreetCommand.class);

Multiple Commands in One Class

You can define multiple command methods in a single class:
public class SocialCommands {
    
    @Command("greet")
    public void greet(@Sender Player sender, @Name("player") Player target) {
        // Greeting logic
    }
    
    @Command("wave")
    public void wave(@Sender Player sender, @Name("player") Player target) {
        // Waving logic
    }
    
    @Command("hug")
    public void hug(@Sender Player sender, @Name("player") Player target) {
        // Hugging logic
    }
}

Subcommands

Create subcommands by using spaces in the command annotation:
public class AdminCommands {
    
    @Command("admin reload")
    @Permission("example.admin.reload")
    public void reload(@Sender Player sender) {
        // Reload logic
    }
    
    @Command("admin debug")
    @Permission("example.admin.debug")
    public void debug(@Sender Player sender) {
        // Debug logic
    }
}
Players would use these commands like:
  • /admin reload
  • /admin debug

Error Handling

Blade automatically handles common errors:
  • Invalid arguments: Shows usage message
  • Missing permissions: Shows permission denied message
  • Player not found: Shows “Player not found” error
  • Invalid number: Shows “Invalid number” error
You can customize error messages in your configuration:
Blade.forPlatform(new BladeBukkitPlatform(this))
    .config(cfg -> {
        cfg.defaultPermissionMessage("§cYou don't have permission to use this command!");
    })
    .build();

Next Steps

You’ve created your first Blade command! Here’s what to explore next:

Core Concepts

Learn about arguments, flags, and providers

Annotations Reference

Explore all available annotations

Custom Providers

Create custom argument types

Advanced Features

Async commands, custom senders, and more

Build docs developers (and LLMs) love