Aller au contenu principal


Introduction

Imperat is a powerful command dispatching framework, it allows you to create commands and converts them into the form of multiple data-condensed objects like Command, CommandUsage and CommandParameter These objects are registered/injected into the class Imperat which handles all information about each command and then dispatches/executes the command requested.

Installation

Imperat is a versatile command dispatching framework designed to work across various platforms with the appropriate implementation. This is will guide you through the installation step by step.

Repository setup

Most builds won't require special repository configuration as Imperat artifacts are hosted on Maven Central. However, if you need to explicitly declare it:

<repositories>
<repository>
<id>maven-central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>

Core Dependency setup

Before adding any platform-specific module, you must include the core Imperat dependency:

<dependency>
<groupId>studio.mevera</groupId>
<artifactId>imperat-core</artifactId>
<version>loading...</version>
</dependency>

Preserve parameter names [OPTIONAL]

Imperat uses parameter names to generate helpful command metadata like usage examples and tab completion suggestions. However, Java doesn't preserve parameter names in the compiled bytecode by default. To enable this feature, you need to configure your build tool to preserve parameter names.

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
</plugins>
</build>
TIP

You wouldn't need to use @Named Explicitly on method parameters, if you preserved the names of the compiled paramters from your method signatures (Explained how to do that above)

Platform Dependency setup

Choose the platform you are developing for to see specific setup instructions.

Implementation for Bukkit-based Minecraft servers (like Spigot, Paper).

  • Imperat Class: BukkitImperat
  • Command Source: BukkitSource

Installation

<dependency>
<groupId>studio.mevera</groupId>
<artifactId>imperat-bukkit</artifactId>
<version>loading...</version>
</dependency>
Brigadier Integration

You can integrate Imperat with Mojang's Brigadier for enhanced command features (like suggestions and argument types) on compatible servers (Minecraft 1.13+). Call this applyBrigadier method while configuring imperat's instance, the method must be the FIRST one to be called in the builder's chain like the following example:

BukkitImperat imperat = BukkitImperat.builder(this)
.applyBrigadier(true)
.build();
Important

Do NOT register your commands within your plugin's plugin.yml file. Imperat handles registration dynamically.

Note on Versions

Ensure you use the same version (loading...) for both imperat-core and the platform-specific module (e.g., imperat-bukkit) to avoid compatibility issues.

Initializing Imperat

Frequently asked question: What's a command dispatcher/Imperat ??
Answer: It's the Ultimate class handling all data needed when processing and registering commands objects (Command). You have to create new instance of the imperat. on the start of your platform by calling YourPlatformImperat#builder (the method is static) to configure your imperat instance, then finally end the chain with build method to return a new instance of YourPlatformImperat type.

TIP

Creation of an instance of your PlatformImperat depends mainly on which platform you are using.

Creation of Commands

There's mainly 2 ways of creating commands:

I will be giving an intro to the easier way for creating commands which is the annotations.

Annotated Commands

Creating commands with annotations is easy with 2 steps only:

  1. Create a class that will represent your command class
  2. Add unique annotations to it that allows the dispatcher to identify it as a command class

Quick example (Same results as the one above, but with annotations):

@Command("example")  
public final class ExampleCommand {

@Usage
public void defaultUsage(BukkitSource source) {
source.reply("This is just an example with no arguments entered");
}

@Usage
public void exampleOneArg(
BukkitSource source,
@Named("firstArg") int firstArg
) {
source.reply("Entered required number= " + firstArg);
}
}

Register your commands

Register your command by calling the method imperat.registerCommand(command) Note: the method is called from the YourPlatformImperat instance that you should have created

Here's a quick bukkit example:

public class YourPlugin extends JavaPlugin {

private BukkitImperat imperat;

@Override
public void onEnable() {
//initializing imperat
imperat = BukkitImperat.builder(plugin).build();

//registering the command
imperat.registerCommand(new ExampleCommand());
}

}

Basic Execution Flow

It's essential to know how the basic flow of executing a command using Imperat.
It will help you grasp the concept of Context

Key Execution Steps:

  1. Parse Command - Convert raw input into structured Context object
  2. Permission Check - Verify source has permission for root command
  3. Tree Traversal - Find matching usage path through command tree via CommandTree#contextMatch()
  4. Usage Permission - Check permissions for the specific usage found
  5. Pre-Processing - Execute global and command-specific pre-processor
  6. Argument Resolution - Convert raw strings into typed values according to the type of their parameters using ParameterValueAssigner, then inject the values into the ExecutionContext.
  7. Command Execution - Invoke your actual command method with resolved parameters
  8. Post-Processing - Execute global and command-specific post-processors
  9. Result - Return success or failure wrapped in ExecutionResult
NOTICE

Any step can throw exceptions (PermissionDeniedException, InvalidSyntaxException, etc.) which are caught and converted to failed ExecutionResult objects.

Execution flowchart

Customizing Imperat

If you wanted to register a Context Resolver or a Parameter Type , or even set a Suggestion Resolver for tab-completion in commands, You would have to call some methods while configuring imperat.

With Imperat, you can even register your own sender/source type, check out Source Resolver For a complete detailed guide on this, please check out Customizing Imperat

Big-example:

BukkitImperat imperat = BukkitImperat.builder(plugin)
.parameterType(Arena.class, new ArenaParameterType()) //registering custom type 'Arena'
.parameterType(Kit.class, new KitParameterType()) //registering custom type 'Kit'
.parameterType(DuelMode.class, new DuelModeParameterType()) //registering custom type 'DuelMode'
.sourceResolver(CustomSource.class, CustomSource::new) //registering custom command sender/source type 'CustomSource'
.build();
attention

If you ever wanted to create your own implementation of Imperat interface, you will not receive any support and your issue will be instantly ignored/discarded

Tutorials

Check out all the Imperat tutorials here!