# function foo:bar
say This is a normal non-macro command
$say This is a macro line, using $(key_1)!
$teleport @s ~ ~$(key_2) ~
Expected code
NBT structure
Function arguments are represented as NBT compounds. Spigot does not have a data structure to represent an NBT compound, so we have options on how we want to represent this data structure.
We could create our own NBT compound data structure:
public class NBTCompound {
// Getters
public String getString(String key);
public int getInt(String key);
// ...
// Setters/Builders
public NBTCompound setString(String key, String value);
public NBTCompound setInt(String key, int value);
// ...
// Static constructors
public static NBTCompound fromNMS(Object nmsNBTCompound);
public static NBTCompound fromString(String nbtCompoundString);
}
This would look something like this:
NBTCompound functionArguments = new NBTCompound()
.setInt("name1", 123)
.setString("name2", "sometext1")
.setNBTCompound("name3", new NBTCompound()
.setInt("subname1", 456)
.setString("subname2", "sometext2")
);
Using Java's Maps
Or to save a lot of hassle, we could take inspiration from Rtag and use standard Java objects and primitive types. This would look something like this:
For 1.20.2 compatibility, we can call the execute(CommandFunction, CommandSourceStack, TraceCallbacks, CompoundTag) method instead of having to instantiate the command explicitly
Description
In Minecraft 1.20.2, Minecraft added support for "macros" (more info here) which lets you run functions with parameters:
Expected code
NBT structure
Function arguments are represented as NBT compounds. Spigot does not have a data structure to represent an NBT compound, so we have options on how we want to represent this data structure.
Say we have the following NBT compound:
CommandAPI NBT compound structure
We could create our own NBT compound data structure:
This would look something like this:
Using Java's Maps
Or to save a lot of hassle, we could take inspiration from Rtag and use standard Java objects and primitive types. This would look something like this:
Usage
This can be used with the CommandAPI's existing
FunctionWrapper.getFunction().execute()
method:Extra details
On an implementation note, we can call functions by instantiating them directly using the
instantiate
method which accepts the tag:We currently use this method here: https://github.com/JorelAli/CommandAPI/blob/c1399a18b63f88f3c4f3caccafadb78d423ce4d5/commandapi-platforms/commandapi-bukkit/commandapi-bukkit-nms/commandapi-bukkit-1.20.3/src/main/java/dev/jorel/commandapi/nms/NMS_1_20_R3.java#L331-L350
However, we don't call this in 1.20.2:
https://github.com/JorelAli/CommandAPI/blob/c1399a18b63f88f3c4f3caccafadb78d423ce4d5/commandapi-platforms/commandapi-bukkit/commandapi-bukkit-nms/commandapi-bukkit-1.20.2/src/main/java/dev/jorel/commandapi/nms/NMS_1_20_R2.java#L272-L282
For 1.20.2 compatibility, we can call the
execute(CommandFunction, CommandSourceStack, TraceCallbacks, CompoundTag)
method instead of having to instantiate the command explicitly