From 5bc1920083e63d717810d54833fc68fc0af7d08e Mon Sep 17 00:00:00 2001 From: ChampionAsh5357 Date: Mon, 28 Mar 2022 21:09:45 -0400 Subject: [PATCH 1/5] Create configuration docs --- docs/misc/config.md | 95 +++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 96 insertions(+) create mode 100644 docs/misc/config.md diff --git a/docs/misc/config.md b/docs/misc/config.md new file mode 100644 index 00000000..c87fbc02 --- /dev/null +++ b/docs/misc/config.md @@ -0,0 +1,95 @@ +Configuration +============= + +Configurations define settings and consumer preferences that can be applied to a mod instance. Forge uses a configuration system using [TOML][toml] files and read with [night-config][nightconfig]. + +Creating a Configuration +------------------------ + +A configuration can be created using a subtype of `IConfigSpec`. Forge implements the type via `ForgeConfigSpec` and enables its construction through `ForgeConfigSpec#Builder`. The builder can separate the config values into sections via `Builder#push` to create a section and `Builder#pop` to leave a section. Afterwards, the configuration can be built using one of two methods: + +Method | Description +:--- | :--- +build | Creates the `ForgeConfigSpec`. +configure | Creates a pair of the class holding the config values and the `ForgeConfigSpec`. + +Each config value can be supplied with additional context to provide additional behavior. Contexts must be defined before the config value is fully built: + +Method | Description +:--- | :--- +comment | Provides a description of what the config value does. Can provide multiple strings for a multiline comment. +translation | Provides a translation key for the name of the config value. +worldRestart | The world must be restarted before the config value can be changed. + +### ConfigValue + +Config values can be built with the provided contexts (if defined) using any of the `#define` methods. The methods take in four components: a path representing the name of the variable, the default value when no valid configuration is present, a validator to make sure the deserialized object is valid, and a class representing the data type of the config value. + +!!! note + The path is a `.` separated string representing the sections the config value is in. + +```java +// For some ForgeConfigSpec$Builder builder +ConfigValue value = builder.comment("Comment") + .define("config_value_name", defaultValue); +``` + +The values themselves can be obtained using `ConfigValue#get`. The values are additionally cached to prevent multiple readings from files. + +#### Range Values + +Config values that are specified within a range can be defined using `#defineInRange`. These expect the value to be a subtype of `Comparable`. The method is broken down into five components: a path representing the name of the variable, the default value when no valid configuration is present, the minimum and maximum value, and a class representing the data type of the config value. + +#### Whitelisted Values + +Config values that must be a part of a specific whitelist can be defined using `#defineInList`. The method is broken down into three components: a path representing the name of the variable, the default value when no valid configuration is present, and a collection of the allowed values the configuration can be. + +#### List Values + +Config values that can take in a list of entries can be defined using `#defineList`. If the list provided by the consumer can be empty, `#defineListAllowEmpty` should be used instead. The method is broken down into three components: a path representing the name of the variable, the default value when no valid configuration is present, and a validator to make sure a deserialized element from the list is valid. + +#### Enum Values + +Config values that represent an `Enum` can be defined by `EnumValue`s via `#defineEnum`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, a getter to convert a string or integer into an enum, and a collection of the allowed values the configuration can be. + +#### Boolean Values + +Config values that represent a `boolean` can be defined by `BooleanValue`s via `#define`. The method is broken down into two components: a path representing the name of the variable and the default value when no valid configuration is present. + +#### Double Values + +Config values that represent a `double` can be defined by `DoubleValue`s via `#defineInRange`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, and the minimum and maximum value. + +#### Int Values + +Config values that represent an `int` can be defined by `IntValue`s via `#defineInRange`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, and the minimum and maximum value. + +#### Long Values + +Config values that represent a `long` can be defined by `LongValue`s via `#defineInRange`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, and the minimum and maximum value. + +Registering a Configuration +--------------------------- + +Once a `ForgeConfigSpec` has been built, it must be registered to allow Forge to load, track, and sync the configuration settings as required. Configurations should be registered in the mod constructor via `ModLoadingContext#registerConfig`. A configuration can be registered with a given type representing the side the config belongs to (`CLIENT`, `COMMON`, `SERVER`), the `ForgeConfigSpec`, and optionally a specific file name for the configuration. + +```java +// In the mod constructor with a ForgeConfigSpec CONFIG +ModLoadingContext.get().registerConfig(Type.COMMON, CONFIG); +``` + +!!! tip + The definition of each config type and what they are used for can be found as part of the [constant's javadoc][type]. + +Reading a Configuration +----------------------- + +Operations that occur whenever a config is loaded or reloaded can be done using the `ModConfigEvent$Loading` and `ModConfigEvent$Reloading` events. The events must be [registered][events] to the mod event bus. + +!!! warning + These events are called for all configurations for the mod; the `ModConfig` object provided should be used to denote which configuration is being loaded or reloaded. + +[toml]: https://toml.io/ +[nightconfig]: https://github.com/TheElectronWill/night-config +[type]: https://github.com/MinecraftForge/MinecraftForge/blob/1.18.x/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java#L108-L136 +[events]: ../concepts/events.md#creating-an-event-handler diff --git a/mkdocs.yml b/mkdocs.yml index 622989f2..1d4b0659 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -56,6 +56,7 @@ nav: - Model Providers: 'datagen/client/modelproviders.md' # - Server Data: - Miscellaneous Features: + - Configuration: 'misc/config.md' - Forge Update Checker: 'misc/updatechecker.md' - Debug Profiler: 'misc/debugprofiler.md' - Advanced Topics: From 86af3a1b1483b032356ba8572dd23f850235fef6 Mon Sep 17 00:00:00 2001 From: ChampionAsh5357 Date: Sat, 2 Apr 2022 19:03:40 -0400 Subject: [PATCH 2/5] Address sci's changes --- docs/misc/config.md | 126 ++++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 45 deletions(-) diff --git a/docs/misc/config.md b/docs/misc/config.md index c87fbc02..3dd9cf69 100644 --- a/docs/misc/config.md +++ b/docs/misc/config.md @@ -1,32 +1,54 @@ Configuration ============= -Configurations define settings and consumer preferences that can be applied to a mod instance. Forge uses a configuration system using [TOML][toml] files and read with [night-config][nightconfig]. +Configurations define settings and consumer preferences that can be applied to a mod instance. Forge uses a configuration system using [TOML][toml] files and read with [NightConfig][nightconfig]. Creating a Configuration ------------------------ -A configuration can be created using a subtype of `IConfigSpec`. Forge implements the type via `ForgeConfigSpec` and enables its construction through `ForgeConfigSpec#Builder`. The builder can separate the config values into sections via `Builder#push` to create a section and `Builder#pop` to leave a section. Afterwards, the configuration can be built using one of two methods: +A configuration can be created using a subtype of `IConfigSpec`. Forge implements the type via `ForgeConfigSpec` and enables its construction through `ForgeConfigSpec$Builder`. The builder can separate the config values into sections via `Builder#push` to create a section and `Builder#pop` to leave a section. Afterwards, the configuration can be built using one of two methods: Method | Description :--- | :--- -build | Creates the `ForgeConfigSpec`. -configure | Creates a pair of the class holding the config values and the `ForgeConfigSpec`. +`build` | Creates the `ForgeConfigSpec`. +`configure` | Creates a pair of the class holding the config values and the `ForgeConfigSpec`. + +!!! note + `ForgeConfigSpec$Builder#configure` is typically used with a `static` block and a class that takes in `ForgeCondifSpec$Builder` as part of its constructor to attach and hold the values: + + ```java + // In some config class + ExampleConfig(ForgeConfigSpec.Builder builder) { + // Define values here in final fields + } + + // Somewhere the constructor is accessible + static { + Pair pair = new ForgeConfigSpec.Builder() + .configure(ExampleConfig::new); + // Store pair values in some constant field + } + ``` Each config value can be supplied with additional context to provide additional behavior. Contexts must be defined before the config value is fully built: Method | Description :--- | :--- -comment | Provides a description of what the config value does. Can provide multiple strings for a multiline comment. -translation | Provides a translation key for the name of the config value. -worldRestart | The world must be restarted before the config value can be changed. +`comment` | Provides a description of what the config value does. Can provide multiple strings for a multiline comment. +`translation` | Provides a translation key for the name of the config value. +`worldRestart` | The world must be restarted before the config value can be changed. ### ConfigValue -Config values can be built with the provided contexts (if defined) using any of the `#define` methods. The methods take in four components: a path representing the name of the variable, the default value when no valid configuration is present, a validator to make sure the deserialized object is valid, and a class representing the data type of the config value. +Config values can be built with the provided contexts (if defined) using any of the `#define` methods. -!!! note - The path is a `.` separated string representing the sections the config value is in. +All config value methods take in at least two components: +* A path representing the name of the variable: a `.` separated string representing the sections the config value is in +* The default value when no valid configuration is present + +The `ConfigValue` specific methods take in two additional components: +* A validator to make sure the deserialized object is valid +* A class representing the data type of the config value ```java // For some ForgeConfigSpec$Builder builder @@ -36,53 +58,67 @@ ConfigValue value = builder.comment("Comment") The values themselves can be obtained using `ConfigValue#get`. The values are additionally cached to prevent multiple readings from files. -#### Range Values - -Config values that are specified within a range can be defined using `#defineInRange`. These expect the value to be a subtype of `Comparable`. The method is broken down into five components: a path representing the name of the variable, the default value when no valid configuration is present, the minimum and maximum value, and a class representing the data type of the config value. - -#### Whitelisted Values - -Config values that must be a part of a specific whitelist can be defined using `#defineInList`. The method is broken down into three components: a path representing the name of the variable, the default value when no valid configuration is present, and a collection of the allowed values the configuration can be. - -#### List Values - -Config values that can take in a list of entries can be defined using `#defineList`. If the list provided by the consumer can be empty, `#defineListAllowEmpty` should be used instead. The method is broken down into three components: a path representing the name of the variable, the default value when no valid configuration is present, and a validator to make sure a deserialized element from the list is valid. - -#### Enum Values - -Config values that represent an `Enum` can be defined by `EnumValue`s via `#defineEnum`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, a getter to convert a string or integer into an enum, and a collection of the allowed values the configuration can be. - -#### Boolean Values +#### Additional Config Value Types -Config values that represent a `boolean` can be defined by `BooleanValue`s via `#define`. The method is broken down into two components: a path representing the name of the variable and the default value when no valid configuration is present. +* **Range Values** + * Description: Value must be between the defined bounds + * Class Type: `Comparable` + * Method Name: `#defineInRange` + * Additional Components: + * The minimum and maximum the config value may be + * A class representing the data type of the config value -#### Double Values - -Config values that represent a `double` can be defined by `DoubleValue`s via `#defineInRange`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, and the minimum and maximum value. - -#### Int Values - -Config values that represent an `int` can be defined by `IntValue`s via `#defineInRange`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, and the minimum and maximum value. - -#### Long Values - -Config values that represent a `long` can be defined by `LongValue`s via `#defineInRange`. The method is broken down into four components: a path representing the name of the variable, the default value when no valid configuration is present, and the minimum and maximum value. +!!! note + `DoubleValue`s, `IntValue`s, and `LongValue`s are range values which specify the class as `Double`, `Integer`, and `Long` respectively. + +* **Whitelisted Values** + * Description: Value must be in supplied collection + * Class Type: `T` + * Method Name: `#defineInList` + * Additional Components: + * A collection of the allowed values the configuration can be + +* **List Values** + * Description: Value is a list of entries + * Class Type: `List` + * Method Name: `#defineList`, `#defineListAllowEmpty` if list can be empty + * Additional Components: + * A validator to make sure a deserialized element from the list is valid + +* **Enum Values** + * Description: An enum value in the supplied collection + * Class Type: `Enum` + * Method Name: `#defineEnum` + * Additional Components: + * A getter to convert a string or integer into an enum + * A collection of the allowed values the configuration can be + +* **Boolean Values** + * Description: A `boolean` value + * Class Type: `Boolean` + * Method Name: `#define` Registering a Configuration --------------------------- -Once a `ForgeConfigSpec` has been built, it must be registered to allow Forge to load, track, and sync the configuration settings as required. Configurations should be registered in the mod constructor via `ModLoadingContext#registerConfig`. A configuration can be registered with a given type representing the side the config belongs to (`CLIENT`, `COMMON`, `SERVER`), the `ForgeConfigSpec`, and optionally a specific file name for the configuration. +Once a `ForgeConfigSpec` has been built, it must be registered to allow Forge to load, track, and sync the configuration settings as required. Configurations should be registered in the mod constructor via `ModLoadingContext#registerConfig`. A configuration can be registered with a given type representing the side the config belongs to, the `ForgeConfigSpec`, and optionally a specific file name for the configuration. + +Type | Loaded | Synced to Client | Stored | Default Suffix +:---: | :---: | :---: | :---: | :--- +CLIENT | Client | ❌ | `.minecraft/config` | `-client` +COMMON | Both | ❌ | `.minecraft/config` | `-common` +SERVER | Server | ✔️ | `/serverconfig` | `-server` + +!!! tip + Forge documents the [config types][type] within their codebase. ```java // In the mod constructor with a ForgeConfigSpec CONFIG ModLoadingContext.get().registerConfig(Type.COMMON, CONFIG); ``` -!!! tip - The definition of each config type and what they are used for can be found as part of the [constant's javadoc][type]. - -Reading a Configuration ------------------------ +Listening for Configuration Loading/Reloading +--------------------------------------------- Operations that occur whenever a config is loaded or reloaded can be done using the `ModConfigEvent$Loading` and `ModConfigEvent$Reloading` events. The events must be [registered][events] to the mod event bus. From cdb7690ae4894ef080e6e201c5242924d64dbe85 Mon Sep 17 00:00:00 2001 From: ChampionAsh5357 Date: Sat, 2 Apr 2022 22:44:41 -0400 Subject: [PATCH 3/5] Add sci's changes Co-authored-by: sciwhiz12 --- docs/misc/config.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/misc/config.md b/docs/misc/config.md index 3dd9cf69..082e7580 100644 --- a/docs/misc/config.md +++ b/docs/misc/config.md @@ -8,25 +8,25 @@ Creating a Configuration A configuration can be created using a subtype of `IConfigSpec`. Forge implements the type via `ForgeConfigSpec` and enables its construction through `ForgeConfigSpec$Builder`. The builder can separate the config values into sections via `Builder#push` to create a section and `Builder#pop` to leave a section. Afterwards, the configuration can be built using one of two methods: -Method | Description -:--- | :--- + Method | Description + :--- | :--- `build` | Creates the `ForgeConfigSpec`. `configure` | Creates a pair of the class holding the config values and the `ForgeConfigSpec`. !!! note - `ForgeConfigSpec$Builder#configure` is typically used with a `static` block and a class that takes in `ForgeCondifSpec$Builder` as part of its constructor to attach and hold the values: + `ForgeConfigSpec$Builder#configure` is typically used with a `static` block and a class that takes in `ForgeConfigSpec$Builder` as part of its constructor to attach and hold the values: ```java // In some config class ExampleConfig(ForgeConfigSpec.Builder builder) { - // Define values here in final fields + // Define values here in final fields } // Somewhere the constructor is accessible static { - Pair pair = new ForgeConfigSpec.Builder() - .configure(ExampleConfig::new); - // Store pair values in some constant field + Pair pair = new ForgeConfigSpec.Builder() + .configure(ExampleConfig::new); + // Store pair values in some constant field } ``` @@ -43,10 +43,12 @@ Method | Description Config values can be built with the provided contexts (if defined) using any of the `#define` methods. All config value methods take in at least two components: + * A path representing the name of the variable: a `.` separated string representing the sections the config value is in * The default value when no valid configuration is present The `ConfigValue` specific methods take in two additional components: + * A validator to make sure the deserialized object is valid * A class representing the data type of the config value From a14787bd7f352c58188ec969c4d4ff3599c24eee Mon Sep 17 00:00:00 2001 From: ChampionAsh5357 Date: Sat, 2 Apr 2022 23:00:24 -0400 Subject: [PATCH 4/5] Finish changes on config --- docs/misc/config.md | 78 ++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/docs/misc/config.md b/docs/misc/config.md index 082e7580..f3515632 100644 --- a/docs/misc/config.md +++ b/docs/misc/config.md @@ -63,64 +63,68 @@ The values themselves can be obtained using `ConfigValue#get`. The values are ad #### Additional Config Value Types * **Range Values** - * Description: Value must be between the defined bounds - * Class Type: `Comparable` - * Method Name: `#defineInRange` - * Additional Components: - * The minimum and maximum the config value may be - * A class representing the data type of the config value + * Description: Value must be between the defined bounds + * Class Type: `Comparable` + * Method Name: `#defineInRange` + * Additional Components: + * The minimum and maximum the config value may be + * A class representing the data type of the config value !!! note `DoubleValue`s, `IntValue`s, and `LongValue`s are range values which specify the class as `Double`, `Integer`, and `Long` respectively. * **Whitelisted Values** - * Description: Value must be in supplied collection - * Class Type: `T` - * Method Name: `#defineInList` - * Additional Components: - * A collection of the allowed values the configuration can be + * Description: Value must be in supplied collection + * Class Type: `T` + * Method Name: `#defineInList` + * Additional Components: + * A collection of the allowed values the configuration can be * **List Values** - * Description: Value is a list of entries - * Class Type: `List` - * Method Name: `#defineList`, `#defineListAllowEmpty` if list can be empty - * Additional Components: - * A validator to make sure a deserialized element from the list is valid + * Description: Value is a list of entries + * Class Type: `List` + * Method Name: `#defineList`, `#defineListAllowEmpty` if list can be empty + * Additional Components: + * A validator to make sure a deserialized element from the list is valid * **Enum Values** - * Description: An enum value in the supplied collection - * Class Type: `Enum` - * Method Name: `#defineEnum` - * Additional Components: - * A getter to convert a string or integer into an enum - * A collection of the allowed values the configuration can be + * Description: An enum value in the supplied collection + * Class Type: `Enum` + * Method Name: `#defineEnum` + * Additional Components: + * A getter to convert a string or integer into an enum + * A collection of the allowed values the configuration can be * **Boolean Values** - * Description: A `boolean` value - * Class Type: `Boolean` - * Method Name: `#define` + * Description: A `boolean` value + * Class Type: `Boolean` + * Method Name: `#define` Registering a Configuration --------------------------- Once a `ForgeConfigSpec` has been built, it must be registered to allow Forge to load, track, and sync the configuration settings as required. Configurations should be registered in the mod constructor via `ModLoadingContext#registerConfig`. A configuration can be registered with a given type representing the side the config belongs to, the `ForgeConfigSpec`, and optionally a specific file name for the configuration. -Type | Loaded | Synced to Client | Stored | Default Suffix -:---: | :---: | :---: | :---: | :--- -CLIENT | Client | ❌ | `.minecraft/config` | `-client` -COMMON | Both | ❌ | `.minecraft/config` | `-common` -SERVER | Server | ✔️ | `/serverconfig` | `-server` - -!!! tip - Forge documents the [config types][type] within their codebase. - ```java // In the mod constructor with a ForgeConfigSpec CONFIG ModLoadingContext.get().registerConfig(Type.COMMON, CONFIG); ``` -Listening for Configuration Loading/Reloading ---------------------------------------------- +Here is a list of the available configuration types: + +Type | Loaded | Synced to Client | Stored | Default File Suffix +:---: | :---: | :---: | :---: | :--- +CLIENT | Client Side Only | No | `.minecraft/config` | `-client` +COMMON | On Both Sides | No | `/config` | `-common` +SERVER | Server Side Only | Yes | `/world/serverconfig` | `-server` + +* `` specifies the folder the game is being run from, whether `.minecraft` on the client or the `` for the server. + +!!! tip + Forge documents the [config types][type] within their codebase. + +Configuration Events +-------------------- Operations that occur whenever a config is loaded or reloaded can be done using the `ModConfigEvent$Loading` and `ModConfigEvent$Reloading` events. The events must be [registered][events] to the mod event bus. @@ -129,5 +133,5 @@ Operations that occur whenever a config is loaded or reloaded can be done using [toml]: https://toml.io/ [nightconfig]: https://github.com/TheElectronWill/night-config -[type]: https://github.com/MinecraftForge/MinecraftForge/blob/1.18.x/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java#L108-L136 +[type]: https://github.com/MinecraftForge/MinecraftForge/blob/c3e0b071a268b02537f9d79ef8e7cd9b100db416/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java#L108-L136 [events]: ../concepts/events.md#creating-an-event-handler From e20418fd43b35b79bc758cfa4232eef802a7529b Mon Sep 17 00:00:00 2001 From: ChampionAsh5357 Date: Thu, 7 Apr 2022 19:58:03 -0400 Subject: [PATCH 5/5] Fix table alignment --- docs/misc/config.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/misc/config.md b/docs/misc/config.md index f3515632..3938a787 100644 --- a/docs/misc/config.md +++ b/docs/misc/config.md @@ -112,13 +112,11 @@ ModLoadingContext.get().registerConfig(Type.COMMON, CONFIG); Here is a list of the available configuration types: -Type | Loaded | Synced to Client | Stored | Default File Suffix -:---: | :---: | :---: | :---: | :--- -CLIENT | Client Side Only | No | `.minecraft/config` | `-client` -COMMON | On Both Sides | No | `/config` | `-common` -SERVER | Server Side Only | Yes | `/world/serverconfig` | `-server` - -* `` specifies the folder the game is being run from, whether `.minecraft` on the client or the `` for the server. +Type | Loaded | Synced to Client | Client Location | Server Location | Default File Suffix +:---: | :---: | :---: | :---: | :---: | :--- +CLIENT | Client Side Only | No | `.minecraft/config` | N/A | `-client` +COMMON | On Both Sides | No | `.minecraft/config` | `/config` | `-common` +SERVER | Server Side Only | Yes | `.minecraft/saves//serverconfig` | `/world/serverconfig` | `-server` !!! tip Forge documents the [config types][type] within their codebase.