All pages
Powered by GitBook
1 of 3

Creating your config

Getting Started

Building your base

To create your config, you'll first need to create a new class that extends OneConfig's Config class, like so:

public class ExampleConfig extends Config {
}
object ExampleConfig : KtConfig() // This is an object so we can easily access a singleton instance of the config. Refer to later section for more info

Why do we use KtConfig for the Kotlin example?

KtConfig provides additional functionality which makes it easier to create type-safe options in Kotlin with a much more readable and serviceable syntax.

Easy, right? Now, you'll need to provide it with some info via it's constructor, which takes your config's name, category, file name and some other relating data.

The filename you pass to OneConfig is what the file will be named inside of the user's OneConfig settings profile, f.ex .minecraft/config/OneConfig/profiles/example_config.json.

public class ExampleConfig extends Config {
    public ExampleConfig() {
         super(
              "example_config.json",                // Your mod's config file's name and extension
              "/assets/examplemod/example_mod.png", // A path to a PNG or SVG file, used as your mod's icon in OneConfig's UI
              "Example Mod",                        // Your mod's name was it is shown in OneConfig's UI
              Category.QOL                          // The category your mod will be sorted in within OneConfig's UI
         );
    }
}
object ExampleConfig : KtConfig(
     id = "example_config.json",                  // Your mod's config file's name and extension
     icon = "/assets/examplemod/example_mod.png", // A path to a PNG or SVG file, used as your mod's icon in OneConfig's UI
     title = "Example Mod",                       // Your mod's name was it is shown in OneConfig's UI
     category = Config.Category.QOL               // The category your mod will be sorted in within OneConfig's UI
)

Simple as that!

Initializing your config when the game launches

There are various different ways to initialize your config, but here are the way we recommend:

If you are on Java, add an INSTANCE field to your config. This is where you will access your dedicated object of your config for non-static methods, such as save.

public class ExampleConfig extends Config {

    // Your actual config options here...
    
    public static final ExampleConfig INSTANCE = new ExampleConfig();
    
    // Your constructor here...
}

If you are on Kotlin and you have not already, make your config class an object. This makes your class a singleton, which essentially will create the INSTANCE field in Java for you, and make accessing it via Kotlin syntax easier.

object ExampleConfig : KtConfig(
     // Your constructor stuff here...
)

Now, all you need to do is initialize your config when the game first launches with your mod, via the preload method. This can be done using your mod loader's standard means of initializing your mod at game launch, or alternatively, by using OneConfig's events system, using the InitializationEvent.

@Mod(modid = ExampleMod.MODID, version = ExampleMod.VERSION, name = ExampleMod.NAME)
public class ExampleMod {
    public static final String MODID = "examplemod";
    public static final String VERSION = "1.0.0";
    public static final String NAME = "Example Mod";
    
    @Mod.EventHandler
    public void onInitialize(FMLInitializationEvent event) {
        ExampleConfig.INSTANCE.preload();  // Ensures that everything is set up as it should be!
    }
}
@Mod(modid = ExampleMod.MODID, version = ExampleMod.VERSION, name = ExampleMod.NAME)
class ExampleMod { // This can also be an object via a language adapter, which you can use via OneConfig!
    companion object {
        const val MODID = "examplemod"
        const val VERSION = "1.0.0"
        const val NAME = "Example Mod"
    }
    
    @Mod.EventHandler
    fun onInitialize(event: FMLInitializationEvent) {
        // Unlike Java, you don't need the `INSTANCE` reference here.
        ExampleMod.preload() // Ensures that everything is set up as it should be!
    }
}
public class ExampleMod {
    
    @Subscribe
    public void onInitialize(InitializationEvent event) {
        ExampleConfig.INSTANCE.preload();  // Ensures that everything is set up as it should be!
    }
}
class ExampleMod {
    
    @Subscribe
    fun onInitialize(event: InitializationEvent) {
        // Unlike Java, you don't need the `INSTANCE` reference here.
        ExampleConfig.preload()  // Ensures that everything is set up as it should be!
    }
}

Option dependencies & hiding options

Dependency management

public MyConfig() {
    addDependency("myOptionName", "myOtherOptionName"); // Disables myOptionName when myOtherOptionName = false
    // The above obviously only works when myOtherOptionName is a boolean-typed option.
    
    addDependency("myOtherOtherOptionName", () -> Property.Display.HIDDEN); // Hides myOtherOtherOptionName
    
    addDependency("myOtherOtherOtherOptionName", "myOptionName", true); // Hides myOtherOtherOtherOptionName when myOptionName is false
}
init {
    addDependency("myOptionName", "myOtherOptionName") // Disables myOptionName when myOtherOptionName = false
    // The above obviously only works when myOtherOptionName is a boolean-typed option.
    
    addDependency("myOtherOtherOptionName") { Property.Display.HIDDEN } // Hides myOtherOtherOptionName
    
    addDependency("myOtherOtherOtherOptionName", "myOptionName", true) // Hides myOtherOtherOtherOptionName when myOptionName is false
}

Hiding your options

public MyConfig() {
    hideIf("myOptionName", () -> true); // Hides myOptionName
    
    hideIf("myOptionName", "myOtherOptionName"); // Hides myOptionName if myOtherOptionName is false
    // The above obviously only works when myOtherOptionName is a boolean-typed option.
}
init {
    hideIf("myOptionName") { true } // Hides myOptionName
    
    hideIf("myOptionName", "myOtherOptionName") // Hides myOptionName if myOtherOptionName is false
    // The above obviously only works when myOtherOptionName is a boolean-typed option.
}

What's the difference?

You can use addDependency to fine-tune the display status of your options based on your own conditions or other options. By default, simply using addDependency and passing the options of your choosing will cause the dependant to be disabled rather than hidden.

hideIf will ALWAYS completely hide the option passed to it based on the condition(s) provided as opposed to having to pick a display status.

Listening for option changes

Monitoring changes to options for any reason is simple, thanks to the convenient methods provided by OneConfig. You can use them like so:

public MyConfig() {
    addCallback("myOptionName", () -> {
        System.out.println("myOptionName changed!");
    });
}
init {
    addCallback("myOptionName") {
        println("myOptionName changed!");
    }
}

Easy enough, eh? But what if we want to know the new value at the time of the change?

public MyConfig() {
    addCallback<Boolean>("myOptionName", (value) -> {
        System.out.println("myOptionName value: " + value);
    });
}
init {
    addCallback<Boolean>("myOptionName") { value ->
        println("myOptionName value: $value")
    }
}