NBT arguments

The CommandAPI includes support for NBT compound arguments using an NBT API. The usage for the NBTCompoundArgument depends on whether you are using the CommandAPI plugin (using a CommandAPI.jar file in your plugins/ folder), or are shading the CommandAPI (including the compiled CommandAPI code in your own plugin).


Plugin usage setup

By default, the CommandAPI plugin includes a copy of the NBT API by tr7zw in dev.jorel.commandapi.nbtapi. No additional set up is required and it can be used directly out the box.

Shading usage setup

In order to use the NBTCompoundArgument, you will have to use an NBT API that can create an NBT Compound object from an Object (ideally a net.minecraft.nbt.NBTTagCompound object). Examples of NBT APIs that can do this are (these are not sponsored in any way):

Hooking into an NBT API

Before the NBTCompoundArgument can be used, the CommandAPI needs to know what implementation of an NBT Compound object you're going to use. This is specified in the onLoad() sequence, where your CommandAPI's config is set up, by using the following method:

<T> CommandAPIConfig initializeNBTAPI(Class<T> nbtContainerClass, Function<Object, T> nbtContainerConstructor);

The initializeNBTAPI(Class<T>, Function<Object, T>) takes in two arguments:

  • Class<T> - The class that will be your NBT Compound implementation. This is also the type that the CommandAPI will return when the NBTCompoundArgument is used.

  • Function<Object, T> - A function that takes in an object and returns the specified NBT Compound implementation. This could be a constructor or a static method, for example.

Example - Hooking into the NBT API

Say we want to use the NBT API as our implementation of NBT compounds. First, we have to shade the NBT API into our project (view the official documentation for how to do this for Maven or Gradle).

Now, we can configure the CommandAPI using the CommandAPI.onLoad() method to use the NBTContainer class, and the NBTContainer constructor that takes in an Object:

@Override
public void onLoad() {
    CommandAPI.onLoad(new CommandAPIBukkitConfig(this)
        .initializeNBTAPI(NBTContainer.class, NBTContainer::new)
    );
}
override fun onLoad() {
    CommandAPI.onLoad(CommandAPIBukkitConfig(this)
        .initializeNBTAPI(NBTContainer::class.java, ::NBTContainer)
    )
}

Confused with the ::new syntax? Read more about method references to a constructor here.

We're now able to use the NBTContainer as our implemented type for the NBTCompoundArgument!


Example - ???

Since the underlying implementation of the NBTCompoundArgument can change (e.g. NBTContainer if you're using the NBT API), the type of your NBT compound implementation has to be declared in angle brackets.

new CommandAPICommand("award")
    .withArguments(new NBTCompoundArgument<NBTContainer>("nbt"))
    .executes((sender, args) -> {
        NBTContainer nbt = (NBTContainer) args.get("nbt");
        
        // Do something with "nbt" here...
    })
    .register();
CommandAPICommand("award")
    .withArguments(NBTCompoundArgument<NBTContainer>("nbt"))
    .executes(CommandExecutor { _, args ->
        val nbt = args["nbt"] as NBTContainer

        // Do something with "nbt" here...
    })
    .register()
commandAPICommand("award") {
    nbtCompoundArgument<NBTContainer>("nbt")
    anyExecutor { _, args ->
        val nbt = args["nbt"] as NBTContainer

        // Do something with "nbt" here...
    }
}

Developer's Note:

If you believe you can supply a suitable example for this page, feel free to send an example on the CommandAPI issues page!