A class-based config API and in-game config screen for Minecraft mods.
EasyConfig makes it easy to create, modify, and share config files for your mod. With an easily accessible in-game config screen, users can adjust settings on the fly without having to manually edit config files.
EasyConfig naturally integrates with NeoForge, not replacing their configs, but giving a cleaner alternative. For Fabric, EasyConfig integrates with ModMenu for in-game config access, while still remaining an optional dependency.
- One config API for Fabric and NeoForge.
- In-game config screens for mods that use EasyConfig.
- Tabs for mods with more than one config.
- Fabric Mod Menu integration.
- Lower-level APIs for custom config loading, saving, and metadata.
Add the Maven repository:
repositories {
maven {
name = "iso2t"
url = "https://maven.iso2t.com/releases"
}
}Fabric:
dependencies {
modImplementation "com.iso2t.easyconfig:easyconfig-fabric-26.2:26.1.0.3"
}NeoForge:
dependencies {
implementation "com.iso2t.easyconfig:easyconfig-neoforge-26.2:26.1.0.3"
}API only:
dependencies {
implementation "com.iso2t.easyconfig:api:1.1.3"
}The Fabric and NeoForge artifacts include the API classes in the built mod jar. Use the standalone api artifact only when you want the Java config API without EasyConfig's Minecraft mod implementation or in-game screens.
import com.iso2t.easyconfig.api.Side;
import com.iso2t.easyconfig.api.annotations.Comment;
import com.iso2t.easyconfig.api.annotations.Ignore;
import com.iso2t.easyconfig.api.annotations.Config;
import com.iso2t.easyconfig.api.value.wrappers.BooleanValue;
import com.iso2t.easyconfig.api.value.wrappers.EnumValue;
import com.iso2t.easyconfig.api.value.wrappers.IntegerValue;
@Config(name = "example", side = Side.COMMON)
public class ExampleConfig {
@Comment(value = "Enable the feature", values = false)
public BooleanValue enabled = BooleanValue.of(true);
@Comment("Maximum entries to process")
public IntegerValue maxEntries = IntegerValue.of(64, 1, 256);
@Ignore // Ignored by the config builder
public IntegerValue maxAttempts = IntegerValue.of(10);
@Comment("Feature mode")
public EnumValue<Mode> mode = EnumValue.of(Mode.NORMAL);
public enum Mode {
QUIET,
NORMAL,
AGGRESSIVE
}
}Build the config during mod initialization:
import com.iso2t.easyconfig.api.ConfigBuilder;
public final class ExampleMod {
public static final String MOD_ID = "examplemod";
public static ExampleConfig CONFIG;
public static void init() {
CONFIG = ConfigBuilder.build(ExampleConfig.class, MOD_ID);
}
}This loads the config, writes missing values, and saves comments. When using the Fabric or NeoForge artifact, it also registers the config screen.
Screen registration is handled by the EasyConfig mod artifacts. If you use the standalone Java API outside Minecraft, configure the config directory through ConfigPlatform.
import com.iso2t.easyconfig.api.ConfigPlatform;
import java.nio.file.Path;
ConfigPlatform.configure(Path.of("config"), modId -> {});Config file names come from @Config.
@Config(name = "example", side = Side.CLIENT)generates:
example-client.json5
Side suffixes:
Side.COMMON: no suffixSide.CLIENT:-clientSide.SERVER:-server
JSON5 is the default format:
ConfigBuilder.build(ExampleConfig.class, MOD_ID);You can pass a file type explicitly:
import com.iso2t.easyconfig.api.files.FileTypes;
ConfigBuilder.build(ExampleConfig.class, MOD_ID, FileTypes.JSON5);
ConfigBuilder.build(ExampleConfig.class, MOD_ID, FileTypes.TOML);Nested classes become sections when they are config-like objects with a no-argument constructor.
@Comment("Debug options")
public Debug debug = new Debug();
public static class Debug {
@Comment(value = "Show debug output", values = false)
public BooleanValue enabled = BooleanValue.of(false);
}@Comment can be used on fields and nested sections.
Configs created through ConfigBuilder are registered for screen support by default.
Config screens are part of the Minecraft implementation, not the standalone Java API.
Disable screen registration:
import com.iso2t.easyconfig.api.ConfigBuildOptions;
ConfigBuilder.build(
ExampleConfig.class,
MOD_ID,
ConfigBuildOptions.unregistered()
);Set a custom tab title:
ConfigBuilder.build(
ExampleConfig.class,
MOD_ID,
ConfigBuildOptions.defaults().screenTitle("Gameplay")
);Multiple configs registered under the same mod id appear as tabs.
NeoForge uses the native mod-list config button. Fabric uses Mod Menu when it is installed.
Use ConfigManager directly when you need a custom path or lifecycle:
import com.iso2t.easyconfig.api.files.FileTypes;
import com.iso2t.easyconfig.api.manager.ConfigManager;
ConfigManager<ExampleConfig> manager = new ConfigManager<>(
ExampleConfig.class,
configPath,
FileTypes.JSON5
);
ExampleConfig config = manager.loadAndSave();
manager.save(config);Useful methods:
load()loadAndSave()save(config)loadInto(config)loadAndSaveInto(config)schema(config)
EasyConfig is licensed under LGPL v3.0. See LICENSE.md.
