-
Notifications
You must be signed in to change notification settings - Fork 56
Configs
One config builder that produces a NeoForge spec or a Fabric json, and gives you a config screen for free.
If you've used Forge's ModConfigSpec this will look familiar. What it adds:
- Any object with a codec as a config value, not just primitives. Lists and maps of them too.
-
Declared schemas. Hand it a codecui
SchemaCodecinstead of a plainCodecand the screen builds a real form for the object instead of a JSON text box. - Beans. Point it at a record or a POJO and it defines one option per field.
- Rich value types that store the same but edit better: colors, sliders, percentages, ranges, vectors, regex, dropdowns, registry pickers with item previews, list editors with autocomplete.
- Feature toggles that compose, so a nested feature reads false when its parent is off.
-
Server sync. A
COMMON_SYNCEDconfig is pushed to clients on join, server values win. - Change hints: mark a value as needing a world reload, a game restart, or as invalidating the dynamic asset cache.
- Comments that are also tooltips, registered as lang entries so they can be translated later.
public static final Supplier<Boolean> SOME_TOGGLE;
public static final Supplier<Integer> COLOR;
public static final Supplier<MyObj> OBJECT;
public static final ModConfigHolder CONFIG;
static {
ConfigBuilder builder = ConfigBuilder.create(MyMod.MOD_ID, ConfigType.COMMON_SYNCED);
builder.push("misc");
SOME_TOGGLE = builder.comment("This is a boolean config").define("some_toggle", true);
COLOR = builder.comment("Hex color config").defineColor("color", 0xff0000);
OBJECT = builder.defineObject("custom_object", () -> new MyObj(2, 4), MyObj.CODEC);
builder.pop();
CONFIG = builder.build();
CONFIG.forceLoad(); // optional, loads the file right now
}Read with SOME_TOGGLE.get(). The file lands in the config folder as
<modid>-<common|client>.toml on NeoForge, .json on Fabric.
ConfigType is COMMON, COMMON_SYNCED or CLIENT.
Example: ConfigBuilderHelper
A plain codec gets a raw JSON editor on the screen. A SchemaCodec gets a generated form:
public static final SchemaCodec<MyObj> SCHEMA_CODEC = SchemaRecord.create(MyObj.class, i -> i.group(
i.field("first", SchemaCodecs.intRange(0, 100), MyObj::first),
i.field("second", SchemaCodecs.intRange(0, 100), MyObj::second)
).apply(i, MyObj::new));
SCHEMA_CONFIG = builder.defineObject("schema_object", () -> new MyObj(2, 4), SCHEMA_CODEC);A SchemaCodec is a Codec, so the file format is identical. The only difference is that the
screen can draw two sliders instead of a text box.
For mods that gate content behind config. The returned supplier is already ANDed with every enclosing feature:
builder.push("redstone");
Supplier<Boolean> redstone = builder.mainFeature(); // this category's own "enabled"
Supplier<Boolean> speaker = builder.feature("speaker_block"); // false when redstone is off
builder.pop();Nothing is rewritten on disk when you flip a parent, composition happens at read time. On the screen
they draw as ✓/✗ switches with an icon. You can also ask by name later:
CONFIG.isFeatureEnabled("redstone.speaker_block").
builder.worldReload().define("some_worldgen_thing", true);
builder.gameRestart().define("some_startup_thing", true);
builder.affectsDynamicPacks().define("generated_texture_style", "fancy");The first two show a warning on the screen. The third invalidates the generated resource cache when the value changes.
Basics Platform Helpers Registration Networking Events Configs Config Screen
Resources Runtime Resource Packs Texture Manipulation Resource Helpers Block Set API
Client Custom Models Item Rendering Rendered Textures Post Shaders GUI Toolkit Colors
World Block and Item Interfaces Additional Item Placements Improved Entities Fake Levels World Data Dispenser Behaviors
Utilities Codec Utilities Misc Helpers Commands
Datapacks Villagers Soft Fluids Map Markers Spawn Boxes Global Datapack Folder