ElytraF5 & more · Developer guide
Practical integration

Gradle, translations and examples

Compile against ElytraF5

The current project configures a local Maven publication. In the ElytraF5 project, run publishToMavenLocal. In your mod project, use the local repository and project coordinates:

repositories {
    mavenLocal()
}

dependencies {
    modCompileOnly("net.turtle:elytraF5:1.0")
}

Declare ElytraF5 in your fabric.mod.json as well. Use suggests if your mod works without the integration, and avoid loading integration classes when ElytraF5 is absent. Use depends if the integration is required.

"suggests": {
  "ef5am": "*"
}

Coordinates follow this repository’s maven_group, archives_base_name and mod_version; adjust them if those properties change. The API is client-side: do not reference it from server code.

Persisting a setting

Initialize the value from your config, return it from the getter, and update and save your config from the callback.

BooleanSettingOption(
    id = "particles",
    title = Component.translatable("examplemod.settings.particles"),
    description = Component.translatable("examplemod.settings.particles.hint"),
    currentValue = { ExampleConfig.particles },
    onChanged = { enabled ->
        ExampleConfig.particles = enabled
        ExampleConfig.save()
    }
)

Multi-value choices

val modes = listOf(
    SettingsChoice("quiet", Component.translatable("examplemod.mode.quiet")),
    SettingsChoice("normal", Component.translatable("examplemod.mode.normal")),
    SettingsChoice("loud", Component.translatable("examplemod.mode.loud"))
)

ChoiceSettingOption(
    id = "sound_mode",
    title = Component.translatable("examplemod.settings.sound_mode"),
    description = Component.translatable("examplemod.settings.sound_mode.hint"),
    choices = modes,
    currentChoice = { ExampleConfig.soundMode },
    onChanged = { id ->
        ExampleConfig.soundMode = id
        ExampleConfig.save()
    }
)

Action that opens a screen

ActionSettingOption(
    id = "advanced",
    title = Component.translatable("examplemod.settings.advanced"),
    description = Component.translatable("examplemod.settings.advanced.hint"),
    buttonTitle = Component.translatable("examplemod.settings.open"),
    action = { parent ->
        Minecraft.getInstance().gui.setScreen(ExampleSettingsScreen(parent))
    }
)

In the child screen, restore the parent when it closes. This returns the player to ElytraF5 settings without losing their place.

Translations

Put translation keys in your own mod resources, for example:

assets/examplemod/lang/en_us.json
{
  "examplemod.settings.visuals": "Visuals",
  "examplemod.settings.enabled": "Enable effects",
  "examplemod.settings.enabled.tooltip": "Enables this mod’s visual effects."
}

Add fr_fr.json and any other languages you support. Category titles, option labels, descriptions and choice labels are all Component values and can use translation keys.

Troubleshooting

SymptomCheck
Category is missingRegister from the client entrypoint; make sure ElytraF5 is installed; check startup logs for exceptions.
Duplicate ID validation errorGive every category a unique namespace and each option a unique ID within its category.
Initial choice fails validationMake sure currentChoice() returns an exact registered choice ID and does not read uninitialized state.
Missing or magenta iconUse a 16 × 16 PNG under assets/<namespace>/textures/gui/... and pass its matching Identifier.
Child screen does not return to settingsKeep the supplied parent Screen and restore it when the child closes.