config
Config Data Class
You must create a class that has fields for all the data you want to retrieve from your config file.
Your config data class must have a constructor with no parameters that initializes the default config values. The first time someone plays with your mod, these values will be written to a config file that they can edit for future use.
Even above 1.16, it can NOT be a record
(the version of Gson shipped with Minecraft does not support them) or have any final fields. Since you need to have a no parameter constructor that sets default values anyway, the record limitation doesn't really add more code.. Json serialization will be handled automatically.
See Serialization for more information on what types of data are supported.
Adding Comments
If you use the @Comment("description")
annotation on one of your fields, that text will be added as a comment above the field in the generated default config json (created when the file does not exist, the first time someone uses your mod).
Building a ConfigWrapper
ConfigWrapper
has three initialization methods depending what side you want to read the config from. Each requires the data class that should be read from the config file.
ConfigWrapper.synced(ConfigData.class)
: Will be read from theworld/serverconfig
directory of the server then synced to all clients. Available on both sides.ConfigWrapper.server(ConfigData.class)
: Will be read from theworld/serverconfig
directory of the server. Only available from the logical server.ConfigWrapper.client(ConfigData.class)
: Will be read from theminecraft/config
directory of the client. Only available from the logical client.
Each of these options returns a ConfigWrapper<ConfigData>
that can be stored in a static variable. The methods described below are set up like a Builder so they can be chained.
File Location
- You must call the
ConfigWrapper#named
method to set the name of the file to read config from. - The file name actually used for your config will include the logical side (from when you created the
ConfigWrapper
). - You can put your config file in a subdirectory of its normal location by calling
ConfigWrapper#dir
- If you call
ConfigWrapper#named
with a resource location, instead of a string, the path will be used as the file name and the namespace will be used for the subdirectory. - The file extension can be set by calling
ConfigWrapper#ext
(this does not actually change the data format!) but generally leaving it as the default (json5
) is fine.
The file will be in [dir]/[name]-[side].[ext]
.
Lists & Maps
Calling ConfigWrapper#listOf
will cause your config to load a list of your originally specified type instead of just one object. The config value will default to an empty list unless you call ConfigWrapper#setDefaultValue
to change it.
Calling ConfigWrapper#mapOf
will cause your config to load a map of strings to your originally specified type instead of just one object. The config value will default to an empty map unless you call ConfigWrapper#setDefaultValue
to change it.
If you pass a class to ConfigWrapper#mapOf
it will be used as the key type. The toString method of this class must preform the json serialization. The normal type adapter will not be called unless you use Gson#enableComplexMapSerialization
(you can set the Gson instance to use with ConfigWrapper#withGson
). Examples that work by default: String, UUID, ResourceLocation.
Config Loading
As long as your ConfigWrapper
is constructed in time (ie. it is in your mod initializer class or its parent class gets class loaded during your mod initializer), the config values will automatically be loaded at a reasonable time with no extra work from you.
client
configs can safely be retrieved at any time.server
orsynced
configs are loaded duringServerStartingEvent
/ServerLifecycleEvents.SERVER_STARTING
.- When a player joins a server, any
synced
configs will be sent their client.
If you try to read server
or synced
configs early, no MinecraftServer
instance will be available, so it won't where to find the world folder. Default values will be returned and an error will be logged.
When a server
or synced
config loads but cannot find its file in world/serverconfig
it checks in minecraft/defaultconfigs
before generating the default file. This allows modpacks to ship their own default configs for your mods.
Reading Config Values
Simply call ConfigWrapper#get
to retrieve an object of your data class with the values loaded from your config file.
Reloading
By default, server
and synced
configs will be reloaded when the /reload
command is used (before data packs are reloaded). Synced configs are also resynced to all players. Note this does not update the previous config object, it creates a new one. So you should call ConfigWrapper#get
every time you need it, in case the values have changed, instead of caching its result. If the changed config file cannot be parsed, it will be ignored and the old value will continue being used.
If you want to prevent a certain config from being reloaded, call ConfigWrapper#noReload
during setup.
onLoad(Runnable)
Call this method during setup with a runnable to be called immediately after loading your config.
server
orsynced
: when the server starts or when the/reload
command is usedclient
: when the client starts
Simple Example
This creates an item that will deal a configurable amount of damage (item registration omitted).
// ExampleModMain.java
public static final Supplier<ExampleConfigData> CONFIG = ConfigWrapper.server(ExampleConfigData.class).named(MOD_ID);
// ExampleConfigData.java
public class ExampleConfigData {
public int needleDamage = 5;
}
// NeedleItem.java
@Override
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
if (!target.level.isClientSide()) target.hurt(DamageSource.GENERIC, ExampleModMain.CONFIG.get().needleDamage);
}