Support and Project Discussion:
Downloads & Documentation:
Other
Compatible Minecraft versions:
The list of what version of the CommandAPI you'll need to run on a specific version of Minecraft is as follows:
Minecraft version | Compatible versions | Latest compatible version |
Minimum Java version required to run latest version |
---|---|---|---|
1.13.x | v1.0 - 5.12, 8.3.0 - 8.8.0 | 8.8.0 | 16 |
1.14.1, 1.14.2 | v2.0 - 5.12, 8.3.0 - 8.8.0 | 8.8.0 | 16 |
1.14.3, 1.14.4 | v2.1 - 5.12, 8.3.0 - 8.8.0 | 8.8.0 | 16 |
1.15.x | v2.3a - 5.12, 8.3.0 - 9.3.0 | 9.3.0 | 16 |
1.16.1 | v3.0 - 5.12, 8.3.0 - 9.4.2 | 9.4.2 | 16 |
1.16.2 | v4.0 - 5.12, 8.3.0 - 9.4.2 | 9.4.2 | 16 |
1.16.3 | v4.2 - 5.12, 8.3.0 - 9.4.2 | 9.4.2 | 16 |
1.16.4 | v5.2 - 5.12, 8.3.0 - 9.4.2 | 9.4.2 | 16 |
1.16.5 | v5.7 - 7.0.0, 8.3.0 - 9.5.3 | 9.5.3 | 16 |
1.17 | 6.0.x - 9.5.3 | 9.5.3 | 16 |
1.17.1 | 6.1.x - 9.5.3 | 9.5.3 | 16 |
1.18, 1.18.1 | 6.5.2 - 9.5.3 | 9.5.3 | 16 |
1.18.2 | 6.5.4 - 9.5.3 | 9.5.3 | 16 |
1.19 | 8.3.0 - 9.5.3 | 9.5.3 | 16 |
1.19.1 | 8.5.0 - 9.5.3 | 9.5.3 | 16 |
1.19.2 | 8.5.1 - 9.5.3 | 9.5.3 | 16 |
1.19.3 | 8.7.0 - 9.5.3 | 9.5.3 | 16 |
1.19.4 | 8.8.0 - 9.5.3 | 9.5.3 | 16 |
1.20 | 9.0.2 - 9.5.3 | 9.5.3 | 16 |
1.20.1 | 9.0.3 - 9.5.3 | 9.5.3 | 16 |
1.20.2 | 9.2.0 - 9.5.3 | 9.5.3 | 16 |
1.20.3, 1.20.4 | 9.3.0 - 9.5.3 | 9.5.3 | 16 |
1.20.5, 1.20.6 | 9.4.0 - 9.5.3 | 9.5.3 | 16 |
1.21 | 9.5.0 - 9.5.3 | 9.5.3 | 16 |
1.21.1 | 9.5.2 - 9.5.3 | 9.5.3 | 16 |
This project provides an API to help Bukkit/Spigot developers use the Minecraft 1.13 command UI, which includes:
-
Better commands - Prevent players from running invalid commands, making it easier for developers - you won't get dodgy input!
-
Better arguments - Choose from over 50 arguments including location arguments, raw JSON, enchantments, lists, particles... all fully supported with built-in error checking!
-
Support for proxied command senders - Run your command as other entities using
/execute as ... run command
-
Argument tooltips - Let your users know exactly what their command will do using argument tooltips
-
Support for the
/execute
command - Let your command to be executed by the built in/execute
command, as well as command blocks! -
Support for Minecraft's functions - Allow your command to be executed from Minecraft's functions and tags
-
No plugin.yml registration - Commands don't need to be registered in the
plugin.yml
file anymore -
No need for Brigadier - You don't need to import Brigadier in your projects to use the CommandAPI
-
No tracking - The CommandAPI doesn't collect any stats about its plugin; what you see is what you get!
Still not convinced? In addition to all of the above, the CommandAPI also provides:
- Built-in command converter - Convert other plugin commands into
/execute
-compatible ones - no code required! - Tree-structure command registration - Like Brigadier's code format? We've got you covered with
CommandTree
- Kotlin DSL - Prefer writing plugins in Kotlin? The CommandAPI has an optional Kotlin DSL just for you
- Powerful suggestion generation - Generate new suggestions for each argument, or add to existing suggestions
- Safe suggestion generation - The CommandAPI offers compile-time type safety for specific arguments
- Precise permission support - Apply permissions to specific arguments - you need perms to even see the argument
- Fast updates - Consistently supports new Minecraft versions within a week of their release
- Insanely detailed documentation - Trust me, you've never seen a plugin documentation look so good.
Simple command registration
new CommandAPICommand("enchantitem")
.withArguments(new EnchantmentArgument("enchantment"))
.withArguments(new IntegerArgument("level", 1, 5))
.executesPlayer((player, args) -> {
Enchantment enchantment = (Enchantment) args.get("enchantment");
int level = (int) args.get("level");
//Add the enchantment
player.getInventory().getItemInMainHand().addEnchantment(enchantment, level);
})
.register();
Potion removing, suggesting potions that a player has currently
List<Argument<?>> arguments = new ArrayList<>();
arguments.add(new EntitySelectorArgument.OnePlayer("target"));
arguments.add(new PotionEffectArgument("potioneffect").replaceSafeSuggestions(SafeSuggestions.suggest(info -> {
Player target = (Player) info.previousArgs().get("target");
//Convert PotionEffect[] into PotionEffectType[]
return target.getActivePotionEffects().stream()
.map(PotionEffect::getType)
.toList().toArray(new PotionEffectType[0]);
})));
new CommandAPICommand("removeeffect")
.withArguments(arguments)
.executesPlayer((sender, args) -> {
Player player = (Player) args.get("target");
PotionEffectType effect = (PotionEffectType) args.get("potioneffect");
player.removePotionEffect(effect);
})
.register();
Subcommands
new CommandAPICommand("perm")
.withSubcommand(new CommandAPICommand("group")
.withSubcommand(new CommandAPICommand("add")
.withArguments(new StringArgument("permission"))
.withArguments(new StringArgument("groupName"))
.executes((sender, args) -> {
//perm group add code
})
)
.withSubcommand(new CommandAPICommand("remove")
.withArguments(new StringArgument("permission"))
.withArguments(new StringArgument("groupName"))
.executes((sender, args) -> {
//perm group remove code
})
)
)
.withSubcommand(new CommandAPICommand("user")
.withSubcommand(new CommandAPICommand("add")
.withArguments(new StringArgument("permission"))
.withArguments(new StringArgument("userName"))
.executes((sender, args) -> {
//perm user add code
})
)
.withSubcommand(new CommandAPICommand("remove")
.withArguments(new StringArgument("permission"))
.withArguments(new StringArgument("userName"))
.executes((sender, args) -> {
//perm user remove code
})
)
)
.register();
Command trees
new CommandTree("perm")
.then(new MultiLiteralArgument("group", "user")
.then(new MultiLiteralArgument("add", "remove")
.then(new StringArgument("permission")
.then(new StringArgument("groupName")
.executes((sender, args) -> {
// args = ["group" or "user", "add" or "remove", permission, groupName]
})
)
)
)
)
.register();
Annotation-based commands
@Command("warp")
public class WarpCommand {
// List of warp names and their locations
static Map<String, Location> warps = new HashMap<>();
@Default
public static void warp(CommandSender sender) {
sender.sendMessage("--- Warp help ---");
sender.sendMessage("/warp - Show this help");
sender.sendMessage("/warp <warp> - Teleport to <warp>");
sender.sendMessage("/warp create <warpname> - Creates a warp at your current location");
}
@Default
public static void warp(Player player, @AStringArgument String warpName) {
player.teleport(warps.get(warpName));
}
@Subcommand("create")
@Permission("warps.create")
public static void createWarp(Player player, @AStringArgument String warpName) {
warps.put(warpName, player.getLocation());
}
}
Kotlin DSL
CommandAPICommand
commandAPICommand("mute") {
playerArgument("target")
integerArgument("duration")
playerExecutor { player, args ->
val target: Player = args["target"]!!
val duration: Int = args["duration"]!!
// Implementation...
}
}
CommandTree
commandTree("mute") {
playerArgument("target") {
integerArgument("duration") {
playerExecutor { player, args ->
val target: Player = args["target"]!!
val duration: Int = args["duration"]!!
}
}
playerExecutor { player, args ->
val target: Player = args["target"]!!
// Some default duration
// Implementation...
}
}
}
Command conversion (no compilation required)
plugins-to-convert:
- Essentials:
- speed <speed>[0..10]
- speed <target>[minecraft:game_profile]
- speed (walk|fly) <speed>[0..10]
- speed (walk|fly) <speed>[0..10] <target>[minecraft:game_profile]
The CommandAPI is built using the Maven build tool - if you don't have it, you can download it here.
-
Clone the repository using your preferred method, or with the command below:
git clone https://github.com/JorelAli/CommandAPI.git
-
Run
mvn clean install -P Platform.Bukkit
The resulting plugin .jar
is found in commandapi-platforms/commandapi-bukkit/commandapi-bukkit-plugin/target/CommandAPI-X.X.X_DATE.jar
The CommandAPI's documentation is built using a custom version of mdBook, a command line tool to create "books" with Markdown. This custom version can be found in my mdBook fork.
-
(Optional): Build the CommandAPI first, using the instructions above. The documentation pulls information directly from tests in the source code, so it assumes that those tests compile correctly!
-
Get a copy of mdbook fork executable.
- On Windows, download
mdbook-fa5.exe
from the mdBook FA5 support release - On Linux:
-
Clone my mdBook fork using your preferred method, or with the command below:
git clone https://github.com/JorelAli/mdBook.git
-
Use git to checkout to the
fa5
branch, using the following command:git checkout fa5
-
Build the executable with
cargo
(can be installed usingsudo apt-get install cargo
on Ubuntu distros), using the following command:cargo build
-
Grab the executable
mdbook
frommdBook/target/debug/
-
- On Windows, download
-
Navigate to the
docssrc
folder -
Run
mdbook-fa5.exe build
(ormdbook build
on Linux)
The resulting compiled documentation is found in docs/X.X.X
, where X.X.X
is specified in the book.toml
file's build-dir
in the docssrc
folder.
This is the current roadmap for the CommandAPI (as of 30th April 2024):
-
10.0.0:
Annotation improvements
The CommandAPI's annotation system has always been a bit limited and was primarily introduced as a proof-of-concept. In this update, the CommandAPI's annotation system will be improved to be (ideally) as powerful as the non-annotation system and have slightly better type safety, support for non-static methods and better checks to prevent invalid command generation. More information about annotations can be found in the Annotation specification document .
-
Future:
Velocity support
Velocity support has been greatly anticipated by a large number of developers and we're hoping to bring Velocity support to you at some point in the future!
Argument conflict detection
The CommandAPI simply uses the Brigadier system under the hood. This system is prone to argument conflicts, which is where certain arguments are given priority over other arguments. (For example "hello" and "123" are both valid string arguments, but if you have a command that has a string argument or an integer argument, Brigadier may ignore the integer argument). In this update, the CommandAPI will try to spot potential conflicts and add a warning in the console.
'True' custom arguments and server-side argument implementations
Through some brief testing of the regex-mod branch and my MinecraftRegexArgumentMod repository, it was discovered that 'true' custom arguments (arguments with a custom implementation of the returned type and parser) are possible with the aid of a client-sided mod. Additionally, this functionality also works without a client-sided mod, assuming this is only used server-side. This can be useful for server-only datapacks, functions and tags, as well as command blocks. It is possible that this may lead into being ported to Fabric, but there are no concrete plans to do so as of now.
Version | Date | Features / Changes |
---|---|---|
9.5.3 | August 2024 |
|
9.5.2 | August 2024 |
Minecraft Version Changes:
|
9.5.1 | June 2024 |
|
9.5.0 | June 2024 |
|
9.4.2 | May 2024 |
|
9.4.1 | May 2024 | CommandAPI Changes: |
9.4.0 | April 2024 |
CommandAPI Changes:
|
9.3.0 | December 2023 |
FunctionArgument ! (See documentation for more information)
|
9.2.0 | September 2023 |
|
9.1.0 | August 2023 |
|
9.0.3 | June 2023 |
|
9.0.2 | June 2023 |
CommandAPI changes:
|
9.0.1 | May 2023 |
|
9.0.0 | April 2023 |
New features:
|
8.8.0 | March 2023 |
|
8.7.6 | February 2023 |
|
8.7.5 | February 2023 |
|
8.7.4 | January 2023 |
|
8.7.3 | January 2023 |
|
8.7.2 | January 2023 |
|
8.7.1 | December 2022 |
|
8.7.0 | December 2022 |
|
8.6.0 | December 2022 |
|
8.5.1 | August 2022 |
|
8.5.0 | July 2022 |
Development improvements:
|
8.4.1 | June 2022 |
|
8.4.0 | June 2022 |
Jar minimization improvements:
|
8.3.1 | June 2022 |
|
8.3.0 | June 2022 |
|
8.2.1 | June 2022 |
|
8.2.0 | May 2022 |
|
8.1.0 | May 2022 |
|
8.0.0 | April 2022 |
|
7.0.0 | April 2022 |
Development improvements:
|
6.5.4 | March 2022 |
|
6.5.3 | December 2021 |
|
6.5.2 | December 2021 |
|
6.5.1 | December 2021 |
|
6.5.0 | December 2021 |
|
6.4.0 | November 2021 |
|
6.3.1 | September 2021 |
|
6.3.0 | August 2021 |
|
6.2.0 | July 2021 |
|
6.1.0 | July 2021 |
|
6.0.5 | June 2021 |
|
6.0.4 | June 2021 |
|
6.0.3 | June 2021 |
|
6.0.2 | June 2021 |
|
6.0.1 | June 2021 |
|
6.0.0 | June 2021 |
Version support changes:
|
5.12 | May 2021 |
|
5.11 | May 2021 |
|
5.10 | May 2021 |
|
5.9 | February 2021 |
|
5.8 | January 2021 |
|
5.7 | January 2021 |
|
5.6 | January 2021 |
|
5.5 | January 2021 |
|
5.4 | December 2020 |
|
5.3 | November 2020 |
|
5.2 | November 2020 |
|
5.1 | October 2020 |
|
5.0 | October 2020 |
|
4.3c | October 2020 |
|
4.3b | September 2020 |
|
4.3a | September 2020 |
|
4.3 | September 2020 |
|
4.2 | September 2020 |
|
4.1 | September 2020 |
|
4.0 | August 2020 |
|
3.4 | July 2020 |
|
3.3 | July 2020 |
|
3.2 | July 2020 |
|
3.1 | July 2020 |
|
3.0 | June 2020 |
|
2.3a | December 2019 |
|
2.3 | August 2019 |
|
2.2 | July 2019 |
|
2.1 | July 2019 |
|
2.0.1 | May 2019 |
|
2.0 | May 2019 |
|
1.8.2 | January 2019 |
|
1.8.1 | December 2018 |
|
1.8 | December 2018 |
|
1.7.2 | December 2018 |
|
1.7.1 | December 2018 |
|
1.7 | December 2018 |
|
1.6 | November 2018 |
|
1.5 | October 2018 |
|
1.4 | October 2018 |
|
1.3 | October 2018 |
|
1.2 | August 2018 |
|
1.1 | August 2018 |
|
1.0 | August 2018 |
|