> ## Documentation Index
> Fetch the complete documentation index at: https://wiki.refineryteam.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Annotation-driven mapping between a YAML file and a Java class.

`RefineryConfiguration` (`xyz.refineryteam.refinerycore.api.config`) maps a YAML file directly onto fields of a Java class using annotations, so you don't hand-write `getConfig().getString(...)` calls scattered across your plugin.

## Defining a configuration class

Extend `RefineryConfiguration`, annotate the class with `@ConfigFile`, and annotate fields with `@ConfigEntry`:

```java MainConfig.java icon="java" theme={"system"}
@ConfigFile("config.yml")
public class MainConfig extends RefineryConfiguration {

    @ConfigEntry(key = "database.host", comment = "The MySQL host to connect to")
    private String databaseHost = "localhost";

    @ConfigEntry(key = "database.port")
    private int databasePort = 3306;

    @ConfigEntry(key = "features.enabled")
    private boolean featuresEnabled = true;

    public MainConfig(JavaPlugin plugin) {
        super(plugin);
    }

    // getters as needed
}
```

The field's **initial value doubles as the default** — when the key doesn't exist in the YAML file yet, that value is written back before the file is saved.

## Annotations

| Annotation                   | Target                | Purpose                                                                                                                                   |
| ---------------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `@ConfigFile(value)`         | Class                 | The filename (relative to the plugin's data folder) this configuration maps to                                                            |
| `@ConfigEntry(key, comment)` | Field                 | Maps the field to a YAML path (dot-separated for nesting, e.g. `"database.host"`)                                                         |
| `@ConfigSection(value)`      | A nested config class | Marks a field's type as a nested section, prefixing all of its `@ConfigEntry` keys                                                        |
| `@Category(value)`           | Field                 | (Reserved for grouping/organizing entries — check the field's usage in your version if relying on this for anything beyond documentation) |

### Nested sections

Group related entries into a nested object using `@ConfigSection`:

```java MainConfig.java icon="java" theme={"system"}
@ConfigSection("database")
public class DatabaseSection {
    @ConfigEntry(key = "host")
    private String host = "localhost";

    @ConfigEntry(key = "port")
    private int port = 3306;
}

@ConfigFile("config.yml")
public class MainConfig extends RefineryConfiguration {
    private DatabaseSection database = new DatabaseSection();

    public MainConfig(JavaPlugin plugin) {
        super(plugin);
    }
}
```

This produces:

```yaml theme={"system"}
database:
  host: localhost
  port: 3306
```

## Lifecycle

```java Plugin.java icon="java" theme={"system"}
MainConfig config = new MainConfig(this);

@Override
public void onLoad() {
    config.saveDefault(); // creates the file with defaults if missing
}

@Override
public void onEnable() {
    config.load(); // reads the current file's values into the fields
}
```

| Method          | Behavior                                                                                                                   |
| --------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `saveDefault()` | Creates the file (and parent directories) if it doesn't exist, writes any missing keys from field defaults, and saves      |
| `load()`        | Re-reads the YAML file and populates annotated fields. Calls `saveDefault()` first if the file hasn't been initialized yet |
| `reload()`      | Alias for `load()`                                                                                                         |
| `save()`        | Persists the underlying `FileConfiguration` to disk as-is                                                                  |
| `getYaml()`     | Returns the raw Bukkit `FileConfiguration`, for anything not covered by the annotation mapping                             |

## Supported field types

Primitives and their boxed equivalents (`int`/`Integer`, `long`/`Long`, `double`/`Double`, `float`/`Float`, `boolean`/`Boolean`), `String`, `List`, `Map`, and nested `@ConfigSection` types are all handled automatically. Values read back from YAML are cast to the field's declared type — for example, a YAML integer read into a `long` field is safely widened.

<Warning>
  Lists and maps are read back as new `ArrayList`/`HashMap` instances regardless of the YAML value's concrete implementation. If the value at that path isn't actually a list/map when read, an empty collection is substituted rather than throwing.
</Warning>

## Example: reload command integration

Since `reload()` can throw (e.g. malformed YAML), pair it with `CommandContext#executiveContext` from the [command framework](/refinerycore/commands):

```java PluginCommand.java icon="java" theme={"system"}
@Subcommand(value = "reload", permission = "myplugin.reload")
public void onReload(@NonNull CommandContext context) {
    context.executiveContext(config::reload)
            .onSuccess(() -> context.replyRefineryPrefix("<green>Reloaded successfully."))
            .onFailure(e -> context.replyRefineryPrefix("<red>Failed to reload — check console."));
}
```
