Sub-Commands
Subcommands are a powerful feature in Imperat that allows you to create hierarchical command structures. They enable you to organize related functionality under a single root command, making your commands more intuitive and easier to manage.
Subcommands are treated as commands themselves, so they have the same usage types (EMPTY, DEFAULT, MAIN) as regular commands.
Three Ways to Create Subcommands
Imperat provides three flexible approaches to create subcommands, each with its own advantages and use cases.
Way 1: Methods with @SubCommand
Create subcommands directly as methods within your command class.
@Command("user")
public final class UserCommand {
@Usage
public void defaultUsage(BukkitSource source) {
source.reply("User command");
}
@SubCommand("profile")
public void showProfile(BukkitSource source, @Named("player") Player player) {
source.reply("Showing profile for " + player.getName());
}
@SubCommand("settings")
public void showSettings(BukkitSource source) {
source.reply("User settings");
}
}
Result: This creates the following command structure:
/user
- Main command/user profile <player>
- Profile subcommand/user settings
- Settings subcommand
This approach is the simplest and most straightforward way to create subcommands. It's perfect for commands with a few related subcommands that don't require complex organization.
Way 2: Inner Classes with @SubCommand
Create subcommands as inner classes within your main command class.
Static Inner Classes
@Command("admin")
public final class AdminCommand {
@Usage
public void defaultUsage(BukkitSource source) {
source.reply("Admin command");
}
@SubCommand("ban")
public static class BanSubCommand {
@Usage
public void defaultUsage(BukkitSource source) {
source.reply("Ban subcommand");
}
@Usage
public void banPlayer(
BukkitSource source,
@Named("player") Player player,
@Optional String reason
) {
source.reply("Banning " + player.getName() + " for: " + reason);
}
}
@SubCommand("kick")
public static class KickSubCommand {
@Usage
public void kickPlayer(
BukkitSource source,
@Named("player") Player player
) {
source.reply("Kicking " + player.getName());
}
}
}
Non-Static Inner Classes
@Command("game")
public final class GameCommand {
private final GameManager gameManager;
public GameCommand(GameManager gameManager) {
this.gameManager = gameManager;
}
@SubCommand("start")
public class StartSubCommand {
@Usage
public void startGame(BukkitSource source) {
gameManager.startGame(); // Can access outer class fields
source.reply("Game started!");
}
}
}
Inner classes provide better organization for complex subcommands while keeping related functionality together. Static inner classes are preferred for most use cases.
Way 3: External Classes with @ExternalSubCommand
Create subcommands as separate classes and include them in your main command using the @ExternalSubCommand
annotation.