# Getting started

{% hint style="warning" %}
This wiki is currently a work-in-progress and is incomplete!
{% endhint %}

Before we begin, it's important to note the wiki code examples will be using official Mojang mappings. You are also expected to have a basic knowledge of the Java programming language. If you don't, please learn Java first.

There is a simple structure: categories contains groups, groups contain options. You can also skip the groups and just add options to the category directly. They will always appear above any groups.

Before we start, lets go into detail about how to construct an `Option`, then we'll use that to make a GUI.

```java
Option.<Boolean>createBuilder() // boolean is the type of option we'll be making
        .name(Component.literal("Boolean Option"))
        .description(OptionDescription.of(Component.literal("This text will appear as a tooltip when you hover over the option.")))
        .binding(
                true, // the default value
                () -> this.myBooleanOption, // a getter to get the current value from
                newVal -> this.myBooleanOption = newVal
        )
        .controller(TickBoxControllerBuilder::create)
        .build()
```

An important concept in YACL options are the controllers. Each option type does not have a hardcoded way of being displayed. The logic of displaying the option in the GUI is held in the `Controller`. To learn more about controllers, click here. You will see in the above example, we're choosing to use a tick-box to display and control the boolean option.

To start making a GUI with YACL, you will need to build an instance of `YetAnotherConfigLib`. We will plug in our `Option` code from above...

```java
YetAnotherConfigLib.createBuilder()
        .title(Component.literal("Used for narration. Could be used to render a title in the future."))
        .category(ConfigCategory.createBuilder()
                .name(Component.literal("Name of the category"))
                .tooltip(Component.literal("This text will appear as a tooltip when you hover or focus the button with Tab. There is no need to add \n to wrap as YACL will do it for you."))
                .group(OptionGroup.createBuilder()
                        .name(Component.literal("Name of the group"))
                        .description(OptionDescription.of(Component.literal("This text will appear when you hover over the name or focus on the collapse button with Tab.")))
                        .option(Option.<Boolean>createBuilder()
                                .name(Component.literal("Boolean Option"))
                                .description(OptionDescription.of(Component.literal("This text will appear as a tooltip when you hover over the option.")))
                                .binding(true, () -> this.myBooleanOption, newVal -> this.myBooleanOption = newVal)
                                .controller(TickBoxControllerBuilder::create)
                                .build())
                        .build())
                .build())
        .build()
```

All you have to do then is tell YACL to generate a Screen instance from it.

```java
YetAnotherConfigLib.createBuilder()
        [...]
        .build()
        .generateScreen(parentScreen) // the screen that opens up when you close YACL
```

{% hint style="warning" %}
You must generate a new instance of `YetAnotherConfigLib` every time you want a GUI `Screen`. You cannot just call `generateScreen()` again!
{% endhint %}

It's that simple! You have made your first GUI with YACL!

<figure><img src="https://8383976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs4yG60a7UCSjUx5DT1wQ%2Fuploads%2Fem9v9MPOFoEdIeuhFxTV%2FScreenshot%202023-11-26%20at%2014.23.12.png?alt=media&#x26;token=ff9c751b-b9ec-43ec-b0a2-4da45898c0a9" alt=""><figcaption></figcaption></figure>

## Displaying the GUI

Now you've learned the basics of creating a config GUI, but how do you show it to the user?

### Mod Menu (Fabric)

[Mod Menu](https://modrinth.com/mod/modmenu) is an extremely popular mod for Fabric that adds a menu that displays a list of currently installed mods, like Forge. You can use its API to add a config button to your mod's entry that opens up your newly created YACL config screen.

#### Adding the dependency

First, add the repository to your build.gradle.

{% tabs %}
{% tab title="Groovy DSL (build.gradle)" %}

```gradle
repositories {
  maven {
    name = "Terraformers"
    url = "https://maven.terraformersmc.com/"
  }
}
```

{% endtab %}

{% tab title="Kotlin DSL (build.gradle.kts)" %}

```kotlin
repositories {
    maven("https://maven.terraformersmc.com/") {
        name = "Terraformers"
    }
}
```

{% endtab %}
{% endtabs %}

Then, add the dependency

{% tabs %}
{% tab title="Groovy DSL (build.gradle)" %}

```gradle
dependencies {
    modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")
}
```

{% endtab %}

{% tab title="Kotlin DSL (build.gradle.kts)" %}

```kotlin
dependencies {
    modImplementation("com.terraformersmc:modmenu:${property("modmenu_version")}")
}
```

{% endtab %}
{% endtabs %}

Then, define the version of Mod Menu you're using in your `gradle.properties`. You can get the latest version number [here](https://modrinth.com/mod/modmenu/version/latest), but you may need a different version if you're not using the latest Minecraft version. See the [versions page](https://modrinth.com/mod/modmenu/versions) for a full list of versions.

{% code title="gradle.properties" %}

```properties
modmenu_version=VERSION_NUMBER_HERE
```

{% endcode %}

#### Using the API

First, create the **modmenu entrypoint** by creating a new class in your mod.

{% code title="com/mymod/config/ModMenuIntegration.java" %}

```java
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;

public class ModMenuIntegration implements ModMenuApi {
    @Override
    public ConfigScreenFactory<?> getModConfigScreenFactory() {
        return parentScreen -> YetAnotherConfigLib.createBuilder()
                ...
                .build()
                .generateScreen(parentScreen);
    }
}
```

{% endcode %}

If you want multiple methods to opening your configuration screen, extracting the config creation to a common method call is useful.

#### Registering the entrypoint

Now that you've created the entrypoint, we need to tell mod menu to use it.&#x20;

{% code title="fabric.mod.json" %}

```json
"entrypoints": {
    "modmenu": [
        "com.mymod.config.ModMenuIntegration"
    ]
}
```

{% endcode %}

And you're done! You can now test it out by going to the mod list, finding your mod, and pressing the configuration button to open your YACL GUI.

### NeoForge Mod List

NeoForge has a mod list built-in, and allows you to register *extension points* to extend the functionality of your mod's entry, notably, a config button.

Add the following to your mod's constructor.

{% tabs %}
{% tab title="after (and including) 1.20.6" %}

```java
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;

@Mod("my_mod_id")
public class MyMod {
    public MyMod() {
        ModLoadingContext.get().registerExtensionPoint(
                IConfigScreenFactory.class,
                () -> (client, parent) -> YetAnotherConfigLib.createBuilder()
                        [...]
                        .build()
                        .generateScreen(parent)
        )
    }
}
```

{% endtab %}

{% tab title="before 1.20.6" %}

```java
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import nnet.neoforged.neoforge.client.ConfigScreenHandler;

@Mod("my_mod_id")
public class MyMod {
    public MyMod() {
        ModLoadingContext.get().registerExtensionPoint(
                ConfigScreenHandler.ConfigScreenFactory.class,
                () -> new ConfigScreenHandler.ConfigScreenFactory(
                        (client, parent) -> YetAnotherConfigLib.createBuilder()
                                [...]
                                .build()
                                .generateScreen(parent)
                )
        )
    }
}
```

{% endtab %}
{% endtabs %}

If you want multiple methods to opening your configuration screen, extracting the config creation to a common method call is useful.

That's it! You can now find your mod in the mod list and open your YACL configuration screen!


---

# 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://docs.isxander.dev/yet-another-config-lib/gui-builder/getting-started.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.
