# Command Attributes

## Command Attributes

**Command attributes** are objects that enhance the functionality of commands. They come in various forms such as&#x20;

* Arguments
* Actions
* Properties
* Subcommands
* Etc.

A command can have an unlimited amount of attributes.  To make sure Delegate can distinguish between command attributes, each attribute must have a unique identifier associated with it. Normally, **these identifiers are assigned automatically** (no intervention needed), but in some cases it is useful for the developer to provide these (as we will see later when arguments are covered).

### Chaining Command Attributes

As said previously, a command can have an unlimited amount of attributes assigned to it. When creating a command using *`Delegate.create()`* , an implementation of an *`ICommandBuilder`* is returned. The implementation of this builder depends on your platform. Different platforms will return different types of builders:

* Paper: *`PaperCommandBuilder`*
* Bukkit: `BukkitCommandBuilder`
* Velocity: *`VelocityCommandBuilder`*
* ...

### Fluent Interface

The *`ICommandBuilder`* interface follows the [Fluent Interface](https://martinfowler.com/bliki/FluentInterface.html) design pattern. This is a type of design pattern that allows proper chaining. In the case of Delegate, it is used to chain command attributes. In the next sections, we will build up to the following command (which has been deliberately overcomplicated):

{% tabs %}
{% tab title="Verbose" %}

```java
public class DelegateExample extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
        //  Event registration
        getServer().getPluginManager().registerEvents(this, this);

        //  Hook Delegate into the plugin
        Delegate.hook(this);
        
        //  Create example with sub-commands
        Delegate.create("math", "Implementation of a arithmetic operations such as addition and  subtraction.")
                .withIgnoreNull()
                .withSubcommand(new SubcommandDefinition(Delegate.create("+", "Adds two numbers together")
                        .withFloat("a", "The first number to add")
                        .withFloat("b", "The second number to add")
                        .withFunctionAction("addition", (sender, context) -> {
                            //  Get the arguments. On purpose, we're not using type-safe methods,
                            //  to demonstrate that the arguments are in fact of the correct type.
                            float a = context.find("a");
                            float b = context.find("b");

                            //  Some command logic
                            float sum = a + b;

                            //  Since this action is a function, we return a result
                            //  which will be captured by Delegate. The type is
                            //  automatically inferred.
                            return sum;
                        })
                ))
                .withSubcommand(new SubcommandDefinition(Delegate.create("-", "Subtracts two numbers from each other")
                        .withFloat("a", "The first number to subtract")
                        .withFloat("b", "The second number to subtract")
                        .withFunctionAction("subtraction", (sender, context) -> {
                            //  Get the arguments. On purpose, we're not using type-safe methods,
                            //  to demonstrate that the arguments are in fact of the correct type.
                            float a = context.find("a");
                            float b = context.find("b");

                            //  Some command logic
                            float difference = a - b;

                            //  Since this action is a function, we return a result
                            //  which will be captured by Delegate. The type is
                            //  automatically inferred.
                            return difference;
                        })
                ))
                .build();
    }

    @EventHandler(priority = EventPriority.MONITOR)
    public void onCommand(DelegateCommandEvent event) {
        //  Get some information from the event such as the sender and the capture.
        CommandSender sender = event.getSender();
        CommandCapture capture = event.getCapture();

        //  From the capture, we can get the result returned by a sub-command or action.
        //  In this case, we retrieve the capture of the most deeply nested sub-command.
        //  For the example, this is "+" or "-".
        // 
        //  Note: If type inference fails, null will be returned!
        Float result = capture.getResultOf("subtraction");

        //  Further processing of the command can be handled.
        if (result != null)
            sender.sendMessage(Component.text("Result: " + result));
    }

}
```

Please note that this example is drastically overcomplicated. Delegate can achieve the same functionality with cleaner and less nested code. This is example is for illustration purposes only. Please check the second tab for a simplified version of the command.
{% endtab %}

{% tab title="Simplified" %}

```java
public class DelegateExample extends JavaPlugin implements Listener {

    public void createSimplifiedExample() {
        //  Create a new Delegate command
        Delegate.create("math", "Implementation of a arithmetic operations such as addition and  subtraction.")
                .withIgnoreNull()
                .withString("operation", "The operation to perform.")
                .withFloat("a", "The first number to add.")
                .withFloat("b", "The second number to add.")
                .withAction((sender, context) -> {
                    String operation = args.context("operation");
                    float a = context.find("a");
                    float b = context.find("b");
                    
                    if (operation.equals("+")) {
                        sender.sendMessage("Result: %s".formatted(a + b));
                    } else if (operation.equals("-")) {
                        sender.sendMessage("Result: %s".formatted(a - b));
                    } else {
                        sender.sendMessage("Unknown operation: %s".formatted(operation));
                    }
                })
                .build();
    }
    
}
```

{% endtab %}
{% endtabs %}

In the next few tutorials, we will go over the four built-in command attributes:

* Arguments
* Actions
* Properties
* Definitions


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rocketpencil-studios.gitbook.io/delegate/commands/command-attributes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
