Skip to content

Command Organization

SuSeu1414 edited this page Nov 15, 2020 · 6 revisions

Subcommands Structuring Recommendation

In the old Bukkit ways, many people used Command Executors to separate their base commands, and preferred root commands vs subcommands to keep the logic for sub command routing simpler.

This has lead to a lot of unnecessary breaking up of Subcommands into separate class files.

ACF recommends that you keep your related commands in the same class. Each subcommand is its own method, your IDE will provide ample structure menus for jumping around.

When to break into more than 1 class

Note, that says class, not file. If you have a bunch of commands that are all prefixed the same (2nd tier of subcommand), like so

  • foo|f bar
  • foo|f baz
  • foo|f qux

This is usually a good case to move these commands into an inner class. You may specify @Subcommand("foo|f") on the inner class itself like so:

@CommandAlias("root|r")
public class OuterClass extends BaseCommand {
  @Subcommand("foo|f")
  public class InnerFooClass extends BaseCommand {
    @Subcommand("bar")
    public void onRootFooBar(CommandSender sender) {}
  }
}

In this case /r f bar and /root foo bar both route to your subcommand. It avoids having to repeat that "foo|f" at the start of every subcommand.

You may optionally move these subcommands to their own top level class instead of an inner class, however this will require you to re-define the @CommandAlias again, and it must match exactly as the other file.

// OuterClass.java
@CommandAlias("root|r")
public class OuterClass extends BaseCommand {
}

// OuterFooClass.java
@CommandAlias("root|r")
@Subcommand("foo|f")
public class OuterFooClass extends BaseCommand {
  @Subcommand("bar")
  public void onRootFooBar(CommandSender sender) {}
}

Recommendation: Prefer Inner Classes

Using Inner Classes may provide more features such as parent annotation inheritance, and reduces duplication.

If you move your sub commands to an outer class using the same root base command, every annotation you define on the outer class that needs to still apply to the other subcommands, will need to be duplicated to the 2nd class.

This provides opportunity to mess up and forget to update all classes when you need to make changes.

Moving to its own file really should only be done if the size of your command file is simply too much to handle. If you do this, it is recommended you use the Command Replacements feature to register the duplicated configs as variables so you only need to update it in 1 place.