---
title: Data Generation
---

<Callout>
Added in Fzzy Config 0.7.0
</Callout>

Fzzy Config includes a built in system for defining and generating the language files for your config with a data generator (or a script etc.). **These annotations can also be used to generate lang for registered objects by annotating `RegistrySupplier` or `Identifier`. See below.**

To see how translations work in general in Fzzy Config, check out the [Translations](../config-concepts/Translation) page.

This system has two main components
* Annotations for defining the translations
* API calls that hook into a generator

## Translatable Annotations
The first half of the equation, three annotations in the `Translatable` class let you define setting names, descriptions (tooltips), and prefixes (inline information text)
* `@Translatable.Name`
* `@Translatable.Desc` - `@Comment` and `@TomlComment` also work for en_us descriptions
* `@Translatable.Prefix`

These annotations are pretty self-explanatory. Attach them to a setting or class, and the generator will generate that "thing" for that setting/class in the lang output.

<Callout variant="info">
These annotations are repeatable. Each repeat can be used to define translations for a different language.
</Callout>

<CodeTabs>

```java !!tabs Java
@Translatable.Name("My Config") //a name will be generated for your config class itself at "mod_id.config_name"
@Translatable.Name(value = "Mi Configuración", lang = "es_es") //define lang for multiple languages by adding a lang code
@Translatable.Desc("This is my mod's cool config") //description generated at "mod_id.config_name.desc"
@Translatable.Prefix("This config controls these cool things") //header/prefix generated at "mod_id.config_name.prefix"
public class MyConfig extends Config {

    //works on classes and settings.
    //"mod_id.config_name.mySetting" = "MySetting"
    @Translatable.Name("My Setting") 
    public Boolean mySetting = false;

    @Translation(prefix = "my.prefix") //the generator works with the Translation annotation too, using that defined prefix
    //For nested sections or walkable objects, you only need the lang on the setting, not on the section class
    //"my.prefix.mySection" = "My Section"
    @Translatable.Name("My Section") 
    public MySection mySection = new MySection();

    public class MySection extends ConfigSection {

        @Translatable.Name("My Section Setting") //works automatically on nested section fields too.
        public boolean mySectionSetting = true;
    }
}
```

```kotlin !!tabs Kotlin
@Translatable.Name("My Config") //a name will be generated for your config class itself at "mod_id.config_name"
@Translatable.Name(value = "Mi Configuración", lang = "es_es") //define lang for multiple languages by adding a lang code
@Translatable.Desc("This is my mod's cool config") //description generated at "mod_id.config_name.desc"
@Translatable.Prefix("This config controls these cool things") //header/prefix generated at "mod_id.config_name.prefix"
class MyConfig: Config(Identifier.of(MOD_ID, "config_name")) {

    //works on classes and settings.
    //"mod_id.config_name.mySetting" = "MySetting"
    @Translatable.Name("My Setting")
    var mySetting: Boolean = false

    @Translation(prefix = "my.prefix") //the generator works with the Translation annotation too, using that defined prefix
    //For nested sections or walkable objects, you only need the lang on the setting, not on the section class
    //"my.prefix.mySection" = "My Section"
    @Translatable.Name("My Section")
    var mySection: MySection = MySection()

    class MySection: ConfigSection() {

        @Translatable.Name("My Section Setting") //works automatically on nested section fields too.
        var mySectionSetting: Boolean = true
    }
}
```

</CodeTabs>

## Translating Registry Objects
The Fzzy Config platform api provides a convenience method for translating registered objects like Items, Blocks, etc. To prepare your objects for translation, attach the same `Name` and `Desc` annotations to your fields. For java mods, you will have to change up the typical registry pattern a bit (see the code example)

<CodeTabs>

```java !!tabs Java
public class ItemsRegistry {

    // the Fzzy Config generator looks at instance fields, not static fields.
    // as such, your registry needs to be setup with an instance pattern, rather than statics for each registered item
    // (this is a better pattern in general anyways)
    public static ItemsRegistry INSTANCE = new ItemsRegistry();

    public void init() {
        REGISTRAR.init();
    }

    // set up your FC registrar
    public Registrar<Item> REGISTRAR = ConfigApi.platform().createRegistrar(MOD_ID, Registries.ITEM);

    @Translatable.Name("My Item") //attach the annotation directly to the regsitry supplier generated by the registrar
    public RegistrySupplier<Item> MY_ITEM = REGISTRAR.register("my_item", () -> new MyItem());

    @Translatable.Name("My Other Item") //If you don't want to use FC's registrar, you can still generate translations by making separate identifiers for your objects
    public Identifier myId = Identifier.of(MOD_ID, "my_item_id");
}
```

```kotlin !!tabs Kotlin
object ItemsRegistry {

    fun init() {
        REGISTRAR.init()
    }

    // set up your FC registrar
    val REGISTRAR: Registrar<Item> = ConfigApi.platform().createRegistrar(MOD_ID, Registries.ITEM)

    @Translatable.Name("My Item") //attach the annotation directly to the regsitry supplier generated by the registrar
    val MY_ITEM: RegistrySupplier<Item> = REGISTRAR.register("my_item") { MyItem() } 

    @Translatable.Name("My Other Item") //If you don't want to use FC's registrar, you can still generate translations by making separate identifiers for your objects
    val myId: Identifier = Identifier.of(MOD_ID, "my_item_id")
}
```

</CodeTabs>

## Generating Translations
Once your config is annotated, you can wire up the config to a lang file data generator. The example below uses a Fabric data generation snippet.

<CodeTabs>

```java !!tabs Java
public class EnUsGenerator extends FabricLanguageProvider {
    public EnUSGenerator(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
        super(dataOutput, "en_us", registryLookup);
    }

    @Override
    public void generateTranslations(RegistryWrapper.WrapperLookup wrapperLookup, TranslationBuilder builder) {
        //call the api method and provide the builder to automatically append the config lang
        //That's it! You can of course put any other language translating here too.
        ConfigApiJava.buildTranslations(MyConfig.class, Identifier.of(MOD_ID, "config_name"), "en_us", true, builder::add);

        //registry translations
        //call the platform api method using the instance of your registry, not the class object in this case.
        //the prefix param is the same prefix that is needed in the standard translation key
        ConfigApiJava.platform().buildRegistryTranslations(ItemsRegistry.INSTANCE, "item", "en_us", true, builder::add);
    }
}
```

```kotlin !!tabs Kotlin
class EnUsGenerator(dataOutput: FabricDataOutput, registryLookup: CompletableFuture<RegistryWrapper.WrapperLookup>): FabricLanguageProvider(dataOutput, "en_us", registryLookup) {

    fun generateTranslations(wrapperLookup: RegistryWrapper.WrapperLookup, builder: TranslationBuilder) {
        //call the api method and provide the builder to automatically append the config lang
        //That's it! You can of course put any other language translating here too.
        ConfigApi.buildTranslations(MyConfig::class, Identifier.of(MOD_ID, "config_name"), "en_us", true, builder::add)

        //registry translations
        //call the platform api method using the instance of your registry, not the class object in this case.
        //the prefix param is the same prefix that is needed in the standard translation key
        ConfigApi.platform().buildRegistryTranslations(ItemsRegistry.INSTANCE, "item", "en_us", true, builder::add)
    }
}
```

</CodeTabs>

<Callout>
See the documentation page <a target="_blank" rel="noopener" href="https://fzzyhmstrs.github.io/fconfig/-fzzy%20-config/me.fzzyhmstrs.fzzy_config.util/-translatable/index.html">here 🗗</a>
</Callout>