Modpack authors are always on the hunt for ways to optimize performance, and that means giving them the right configuration options. A recent bug report revealed I’d made those options impossible to find in Bok’s Banging Butterflies…
In a discussion on the feature request that was made for config options, I informed them of the options already available thinking they just didn’t know about them. They clarified that they knew about them, but my config options were in the wrong place, meaning modpack authors couldn’t actually use them.
After this initial confusion, I understood that they were asking me to move the config options already in place.
Config Types
To explain what’s going on, I’ll briefly explain how configuration files work for Forge/Neoforge mods. If you want more detail, there is documention available. For now all we need to know is that Forge/Neoforge mods use three main types of configuration files:
- Client
Loaded only on the client, and not synchronised over the network. - Common
Loaded on both client and server, and also not synchronised over the network. - Server
Loaded only on the server, and synchronised to the client. Can also be overridden for each world.
When I first implemented the config options, I opted to use the server settings since this meant the settings could be unique for each world. This, as it turns out, was a misstep. Server configs are great for world-specific tweaking, but can’t set defaults for an entire modpack, which is what most modpack authors need.
The Fix
Most of my time on this was spent digging into how exactly configs worked, and how other mod packs did it. Once I had a full understanding of how configs worked, I was ready to implement the fix. It’s actually pretty simple.
All I needed to do was build a second, common config. I moved all of the options into this config, except for the debugInformation
option. Unlike the other options, debugInformation
is per-world, as only one world at a time needs debugging
So I updated my ButterfliesConfig
class to have two ForgeConfigSpec
s, one for common settings, the other for server settings:
public class ButterfliesConfig { public static final ForgeConfigSpec COMMON_CONFIG; public static final ForgeConfigSpec SERVER_CONFIG; }
This allows us to have two sets of settings, one for the common config, and one for the server config.
I grouped the actual settings using inner classes, so that it is obvious in code where these settings are coming from when they are accessed. This helps maintainability, as we don’t need to refer to the class itself to see where these settings come from.
// Group common config values in a static inner class public static class Common { public static ForgeConfigSpec.DoubleValue doubleEggChance; public static ForgeConfigSpec.IntValue eggLimit; public static ForgeConfigSpec.IntValue maxDensity; public static ForgeConfigSpec.BooleanValue enableLifespan; public static ForgeConfigSpec.BooleanValue enablePollination; } // Group server config values in a static inner class public static class Server { public static ForgeConfigSpec.BooleanValue debugInformation; }
I use static initialisation to build these configs, as they are used in the mod’s constructor. Here is where I set each value’s range and provide documentation on each setting so users can see what the settings will change.
static { // Build Common Config ForgeConfigSpec.Builder commonBuilder = new ForgeConfigSpec.Builder(); commonBuilder.comment("Common configs for the butterflies mod."); commonBuilder.push("butterfly_options"); Common.doubleEggChance = commonBuilder .comment("Chance a butterfly has double eggs (0-1).") .defineInRange("double_egg_chance", 0.0625, 0, 1); Common.eggLimit = commonBuilder .comment("Eggs per butterfly (0-1024).") .defineInRange("egg_limit", 1, 0, 1024); Common.maxDensity = commonBuilder .comment("Butterfly max density in a 32x32x32 area before breeding is disabled (0 ignores).") .defineInRange("max_density", 16, 0, 1024); Common.enableLifespan = commonBuilder .comment("If true, butterflies will die naturally.") .define("enable_lifespan", true); Common.enablePollination = commonBuilder .comment("If true, butterflies will pollinate flowers.") .define("enable_pollination", true); commonBuilder.pop(); COMMON_CONFIG = commonBuilder.build(); // Build Server Config ForgeConfigSpec.Builder serverBuilder = new ForgeConfigSpec.Builder(); serverBuilder.comment("Server configs for the butterflies mod."); serverBuilder.push("butterfly_options"); Server.debugInformation = serverBuilder .comment("If true, render debug info.") .define("debug_info", false); serverBuilder.pop(); SERVER_CONFIG = serverBuilder.build(); }
Registering the new config is easy. The registerConfig()
method is called in the ButterflyMod
class to register the server config already. I just need to call it a second time to register the COMMON
config type:
// Register mod configuration files ModLoadingContext modLoadingContext = ModLoadingContext.get(); modLoadingContext.registerConfig(ModConfig.Type.COMMON, ButterfliesConfig.COMMON_CONFIG); modLoadingContext.registerConfig(ModConfig.Type.SERVER, ButterfliesConfig.SERVER_CONFIG);
Now, the options that control butterfly spawning and reproduction could be modified by mod pack authors as well as by individual players. Or at least they should as far as I knew. I needed to test an actual released version of the mod to know for sure.
Testing
The problem with this change is that running the game through the debugger puts the configs in an entirely different place to an instance of a modpack installed through a launcher like CurseForge or Modrinth.
I had already tested the new configs by altering some settings and using breakpoints to ensure the values were set, but in order to test the config creation itself, I needed to publish a new release and run it through CurseForge.
So I did just that, then updated and launched one of my custom mod packs with Bok’s Banging Butterflies installed. Sure enough, the new config file appeared in the config folder alongside all the other mod configs:

I confirmed through in-game testing and modpack launches that the settings not only appeared but also successfully controlled butterfly spawning when changed. So I can safely say that this has worked, and now mod pack authors can play with these settings to hopefully improve the performance of their games!
I’m thankful there’s a small community contributing bug reports and feature requests like this. Each time I get one it helps to improve the mod and make it better for all players. So keep those bug reports coming!