Introduction
Imperat is a powerful, annotation-driven command framework designed to eliminate boilerplate and let you focus on logic, not plumbing.
It provides a generic, flexible command system that works seamlessly across multiple platforms — all from the same core API.
Supported platforms:
Github: https://github.com/MeveraStudios/Imperat
Discord: https://discord.mevera.studio
Documentation: https://docs.mevera.studio/Imperat
Real life example usage
Imperat is POJO based, meaning that commands are objects.
It also has an annotations package which provides over 20+ different annotation.
How does annotations work ?
it converts/translates the annotations in the classes into aggregation of command objects to be registered.
Custom argument types
Imperat allows creation of custom arguments types and their use in your command, to flawlessly determine how every argument is parsed from the input into a custom object of your choice.
Here's an example of a custom parameter type for the
Then you can now freely use the
Here's a real life scenario:
Note: the
it consumes all arguments starting from its position in the input arg array, yielding a full string of all following arguments separated by a space char.
Then you register the parameter type you created using the imperat instance, along with registering our msg command :
That's not even the tip of the iceberg !
We have many more features and powerful capabilities to offer for you to keep the boilerplate code to a minimum
Documentation: https://docs.mevera.studio/Imperat
Imperat is a powerful, annotation-driven command framework designed to eliminate boilerplate and let you focus on logic, not plumbing.
It provides a generic, flexible command system that works seamlessly across multiple platforms — all from the same core API.
Supported platforms:
- Minecraft(Spigot & Paper & Bungeecord & Velocity & Minestom )
- JDA (discord)
- Hytale (NEW)
Github: https://github.com/MeveraStudios/Imperat
Discord: https://discord.mevera.studio
Documentation: https://docs.mevera.studio/Imperat
Real life example usage
Java:
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import studio.mevera.imperat.annotations.Command;
import studio.mevera.imperat.annotations.Default;
import studio.mevera.imperat.annotations.Named;
import studio.mevera.imperat.annotations.Permission;
import studio.mevera.imperat.annotations.Usage;
@Command({"gamemode", "gm"})
@Permission("lobby.gamemode")
public class GameModeCommand {
@Usage
public void defUsage(
Player source,
@NotNull @Named("gamemode") GameMode gameMode,
@Default("me") @Named("player") Player target
) {
// /gamemode <gamemode> [player]
target.setGameMode(gameMode);
target.sendMessage("Your gamemode has been set to " + gameMode.name());
if (target != source) {
source.sendMessage("You have set " + target.getName() + "'s gamemode to " + gameMode.name());
}
}
@Command("gmc")
public void gmc(Player source, @Default("me") @Named("player") Player target) {
defUsage(source, GameMode.CREATIVE, target);
}
@Command("gms")
public void gms(Player source, @Default("me") @Named("player") Player target) {
defUsage(source, GameMode.SURVIVAL, target);
}
@Command("gma")
public void gma(Player source, @Default("me") @Named("player") Player target) {
defUsage(source, GameMode.ADVENTURE, target);
}
@Command("gmsp")
public void gmsp(Player source, @Default("me") @Named("player") Player target) {
defUsage(source, GameMode.SPECTATOR, target);
}
}
Imperat is POJO based, meaning that commands are objects.
It also has an annotations package which provides over 20+ different annotation.
How does annotations work ?
it converts/translates the annotations in the classes into aggregation of command objects to be registered.
Custom argument types
Imperat allows creation of custom arguments types and their use in your command, to flawlessly determine how every argument is parsed from the input into a custom object of your choice.
Here's an example of a custom parameter type for the
Player object from spigot:
Java:
public class ParameterPlayer extends BaseParameterType<BukkitSource, Player> {
private final PlayerSuggestionResolver SUGGESTION_RESOLVER = new PlayerSuggestionResolver();
private final OptionalValueSupplier DEFAULT_VALUE_SUPPLIER = OptionalValueSupplier.of("~");
public ParameterPlayer() {
super();
}
@Override
public @Nullable Player resolve(
@NotNull ExecutionContext<BukkitSource> context,
@NotNull CommandInputStream<BukkitSource> commandInputStream,
@NotNull String input
) throws ImperatException {
if (input.equalsIgnoreCase("me") || input.equalsIgnoreCase("~")) {
if (context.source().isConsole()) {
throw new UnknownPlayerException(input, context);
}
return context.source().asPlayer();
}
final Player player = Bukkit.getPlayerExact(input);
if (player != null) return player;
throw new UnknownPlayerException(input, context);
}
/**
* Returns the suggestion resolver associated with this parameter type.
*
* @return the suggestion resolver for generating suggestions based on the parameter type.
*/
@Override
public SuggestionResolver<BukkitSource> getSuggestionResolver() {
return SUGGESTION_RESOLVER;
}
private final static class PlayerSuggestionResolver implements SuggestionResolver<BukkitSource> {
/**
* @param context the context for suggestions
* @param parameter the parameter of the value to complete
* @return the auto-completed suggestions of the current argument
*/
@Override
public List<String> autoComplete(SuggestionContext<BukkitSource> context, CommandParameter<BukkitSource> parameter) {
return Bukkit.getOnlinePlayers().stream().map(Player::getName).toList();
}
}
/**
* Returns the default value supplier for the given source and command parameter.
* By default, this returns an empty supplier, indicating no default value.
*
* @return an {@link OptionalValueSupplier} providing the default value, or empty if none.
*/
@Override
public OptionalValueSupplier supplyDefaultValue() {
return DEFAULT_VALUE_SUPPLIER;
}
@Override
public boolean matchesInput(int rawPosition, Context<BukkitSource> context, CommandParameter<BukkitSource> parameter) {
String input = context.arguments().get(rawPosition);
if (input == null) {
return false;
}
return Bukkit.getPlayer(input) != null;
}
}
Then you can now freely use the
Player object as an argument type,Here's a real life scenario:
Java:
import org.bukkit.entity.Player;
import studio.mevera.imperat.BukkitSource;
import studio.mevera.imperat.annotations.Command;
import studio.mevera.imperat.annotations.Greedy;
import studio.mevera.imperat.annotations.Permission;
import studio.mevera.imperat.annotations.Usage;
@Command({"message", "msg"})
@Permission("server.command.message")
public class MsgCommand {
@Usage
public void defaultUsage(BukkitSource sender) {
//what happens here is executed when the sender executes the command without any input arguments.
//also aka: 'Default Command Usage'
sender.reply("/msg <target> <message>");
}
@Usage
public void mainUsage(BukkitSource sender, Player player, @Greedy String message) {
String fullMsg = sender.name() + "-> " + player.getName() + ": " + message;
sender.reply(fullMsg);
player.sendMessage(fullMsg);
}
}
@Greedy annotations is one of the most useful annotations that imperat provides, it consumes all arguments starting from its position in the input arg array, yielding a full string of all following arguments separated by a space char.
Then you register the parameter type you created using the imperat instance, along with registering our msg command :
Java:
public class ExamplePlugin extends JavaPlugin {
private BukkitImperat imperat;
@Override
public void onEnable() {
//setting up our imperat
imperat = BukkitImperat.builder(this)
.parameterType(Player.class, new ParameterPlayer())
.build();
//registering rank command.
imperat.registerCommand(new MsgCommand());
}
}
That's not even the tip of the iceberg !
We have many more features and powerful capabilities to offer for you to keep the boilerplate code to a minimum
Documentation: https://docs.mevera.studio/Imperat
- Type
- Offering
- Provided by
- Team
