From fb4a608622a39d048ab871faccdbf7da72399336 Mon Sep 17 00:00:00 2001 From: Lexi Date: Thu, 14 Dec 2023 19:57:45 -0500 Subject: [PATCH] Configs! --- Writerside/hi.tree | 2 +- Writerside/redirection-rules.xml | 6 + Writerside/topics/Config.md | 246 +++++++++++++++++- .../Getting-Started-With-Patch-Manager.md | 1 + .../topics/How-to-Use-the-Stage-System.md | 5 + ...art-Patches-More-Moddable-Using-Configs.md | 3 - Writerside/topics/Patch-Manager-C-Interop.md | 3 + Writerside/topics/Top-Level-Statements.md | 22 +- 8 files changed, 282 insertions(+), 6 deletions(-) delete mode 100644 Writerside/topics/Making-Your-Part-Patches-More-Moddable-Using-Configs.md create mode 100644 Writerside/topics/Patch-Manager-C-Interop.md diff --git a/Writerside/hi.tree b/Writerside/hi.tree index 1455d6a..06ec1d0 100644 --- a/Writerside/hi.tree +++ b/Writerside/hi.tree @@ -23,7 +23,6 @@ - @@ -45,4 +44,5 @@ + \ No newline at end of file diff --git a/Writerside/redirection-rules.xml b/Writerside/redirection-rules.xml index 43958ed..12e5773 100644 --- a/Writerside/redirection-rules.xml +++ b/Writerside/redirection-rules.xml @@ -26,4 +26,10 @@ Created after removal of "Simple Part Patching Tutorials" from Patch Manager Simple-Part-Patching-Tutorials.html + + Created after removal of "Making Your Part Patches More Moddable Using Configs" from Patch + Manager + + Making-Your-Part-Patches-More-Moddable-Using-Configs.html + \ No newline at end of file diff --git a/Writerside/topics/Config.md b/Writerside/topics/Config.md index 686ec6f..91a954b 100644 --- a/Writerside/topics/Config.md +++ b/Writerside/topics/Config.md @@ -1,3 +1,247 @@ # Configs + -Start typing here... \ No newline at end of file +> This is going to be added in Patch Manager 0.5.0, it is currently not out +> +{style="note"} + +Configs are a way of having universally accessible configuration for your patches, available at patch time, this can be +useful for like if you have a constant that you want other mods to be able to change, or if you want mods to be able to +provide overrides to your defaults for specific parts. + +## Defining Configs + +> It is recommended for you to define your configs in files under patch files in the `patches/configs/` directory for +> organizational purposes. +> +{style="tip"} + +Defining configs is quite simple, you do `@define-config "config-label", "config-name": [config data as a value];` + + +For a few examples of defining configs: + +``` +@define-config "ls-constants", "ls-day-length": 5; +@define-config "ls-overrides", "cockpit_1v_m1_crew": { + days-of-food: 5, + days-of-water: 5, + days-of-oxygen: 5 +}; +``` + +> Config object names can be the same as long as they have different labels, what fully qualifies a config name is the +> name and label. +> +{style="note"} + + +## Updating Configs + +To update a preexisting config, you do `@update-config update-priority, "config-label", ["config-name"]: [update-expression];` + +The update priority means that in the case of multiple updates on the same config, the ones with the lower priority will +be run first. This is an expression. + +The update expression has `$value` set as the current value of the config pointed to by the label and name, or the current +value of the dictionary of configurations pointed to by config-label if only that is selected. And the update expression +also allows prefix expressions. + +A few examples of updating configurations +``` +$config-update-priority: 5; + +@update-config $config-update-priority, "ls-constants", "ls-day-length": *2; + +@update-config $config-update-priority*2, "ls-overrides", "cockpit_1v_m1_crew": { + days-of-food: 10, + days-of-water: 10, + days-of-oxygen: 10 +}; + +@use "builtin:dictionary"; + +@update-config $config-update-priority, "ls-overrides": $value:merge( + { + wheel_0v_rover: { + days-of-food: 5, + days-of-water: 5, + days-of-oxygen: 5 + }, + wheel_1v_rover: { + days-of-food: 5, + days-of-water: 5, + days-of-oxygen: 5 + } + } +); +``` + +## Using Configs + +To use configs, you can grab them using 2 different methods, `get-config`, and `get-configs`. These are available +in the `builtin:config` library. + +> Only get configs from within selection blocks, or functions that are only called from within selection blocks. If +> you do not do this, it will be an error as the configs will not be "ready" before selection blocks are run. +> +{style="warning"} + +### get-config($label,$name) + +This allows you to get the value of a single config object with its label and name, or if that config object does not +exist it returns `null` (allowing for you to do easy checking). + +Here is an example of using this: +``` +@use 'builtin:config'; + +:parts { + $override: get-config("ls-overrides",$$partName); // Get the possible override for the part name + @if $overrride { // if the override is not null, e.g. in the case where the part name is "cockpit_1v_m1_crew" + // Do stuff. + } +} +``` + +### get-configs($label) + +This gets a dictionary of all configs that are defined under the passed label, with the keys being the names of the configs, +if there are no such configs, it will return an empty dictionary. + +``` +@use 'builtin:config'; +:parts { + $test: get-configs("ls-constants") // returns {ls-day-length: 10} +} +``` + +### Specific Examples of Config Usage + +The following are a few specific examples as to what configs can be used for. + +#### Allowing Overrides for Specific Parts + +Say for the sake of example, that you are writing a life support mod that adds its resources in a small amount to every +single command pod, but, you wanted to allow other mods to be able to override this amount. There are a few ways that +you could go about this. +1. The mod author could just add its resources to the pod and you could check for this. + - This falls flat because this make the mods parts depend on your mod, when they may want to have an optional dependency +2. The mod author could do a patch after yours on its parts to update the values + - This also falls flat, because it requires making use of the staging system which can be a bit complex and can have + pitfalls +3. You could set up your mod to be moddable itself with configs for part overrides + - This requires more work from you, but makes your mod as easily moddable as possible for other modders + +For an example of how you could set this up, assuming you have 3 resources you want to add to parts `food`, `water`, and +`oxygen`. + +First make a library called `_configs.patch` for your mod or similar, this will contain a function for generating an +override config dictionary. The reason this is a function is such that if you add stuff to your mod for stuff you want +to add, or change what gets added, then it won't break old patches. And also it allows you to set up default arguments. + +``` +@use 'constants'; // Assume this has your default constants + +@func ls-create-override($days-of-food: $ls-DEFAULT-DAYS, $days-of-water: $days-of-food, $days-of-oxygen: $days-of-food) +{ + @return { + days-of-food: $days-of-food, + days-of-water: $days-of-water, + oxygen-per-day: $days-of-oxygen + }; +} +``` + +And then in your main patch for adding these resources to the parts, you can set it up like follows, grabbing the +config values at the start. + +``` +@use 'constants'; +@use 'builtin:config'; + +:parts { + $possible-override: get-config("ls-overrides",$$partName); // "ls-override" is your label for your configs. + $days-food: $possible-override["days-of-food"] @if $possible-override @else $ls-DEFAULT-DAYS; + $days-water: $possible-override["days-of-water"] @if $possible-override @else $ls-DEFAULT-DAYS; + $days-oxygen: $possible-override["days-of-oxygen"] @if $possible-override @else $ls-DEFAULT-DAYS; + * > resourceContainers { + $crewCapacity: $parent["crewCapacity"]; + @if $crewCapacity > 0 { + +Oxygen { + capacityUnits: $days-food * $ls-OXYGEN-PER-SECOND * $ls-DAY-LENGTH * $crewCapacity; + initialUnits: $days-food * $ls-OXYGEN-PER-SECOND * $ls-DAY-LENGTH * $crewCapacity; + } + +Water { + capacityUnits: $days-water * $ls-WATER-PER-SECOND * $ls-DAY-LENGTH * $crewCapacity; + initialUnits: $days-water * $ls-WATER-PER-SECOND * $ls-DAY-LENGTH * $crewCapacity; + } + +Food { + capacityUnits: $days-oxygen * $ls-FOOD-PER-SECOND * $ls-DAY-LENGTH * $crewCapacity; + initialUnits: $days-oxygen * $ls-FOOD-PER-SECOND * $ls-DAY-LENGTH * $crewCapacity; + } + } + } +} +``` + +And then any other modders can add override configs for their parts like the following for example: + +``` +@use 'builtin:meta'; +@if exists-mod("ls") { // Check first if the mod exists + @use 'ls:configs'; + @create-config "ls-overrides", "their_part_name": ls-create-override(10); // Utilize the default values to initialize days of food, water, and oxygen to 10 +} +``` + +#### Creating Overridable Constants + +Say now, you want the length of a day to be configurable inside your life support mod (for example if you are using some form of different solar system), +then, you can use the config system to create modifiable constants. + +To start, you should move the constants for your mod you want to be mutable into a file under the configs directory +with any name, lets go with `constants.patch` for this, in there you would define your constants as configs as follows +``` +@create-config "ls-constants", "day-length": 21600; +``` + +Then in your patches where you use these constants, you instead grab the value of the constant at patch time, for example +using the previous patch: + +``` +@use 'constants'; +@use 'builtin:config'; + +:parts { + $possible-override: get-config("ls-overrides",$$partName); // "ls-override" is your label for your configs. + $days-food: $possible-override["days-of-food"] @if $possible-override @else $ls-DEFAULT-DAYS; + $days-water: $possible-override["days-of-water"] @if $possible-override @else $ls-DEFAULT-DAYS; + $days-oxygen: $possible-override["days-of-oxygen"] @if $possible-override @else $ls-DEFAULT-DAYS; + $day-length: get-config("ls-constants","day-length"); + * > resourceContainers { + $crewCapacity: $parent["crewCapacity"]; + @if $crewCapacity > 0 { + +Oxygen { + capacityUnits: $days-food * $ls-OXYGEN-PER-SECOND * $day-length * $crewCapacity; + initialUnits: $days-food * $ls-OXYGEN-PER-SECOND * $day-length * $crewCapacity; + } + +Water { + capacityUnits: $days-water * $ls-WATER-PER-SECOND * $day-length * $crewCapacity; + initialUnits: $days-water * $ls-WATER-PER-SECOND * $day-length * $crewCapacity; + } + +Food { + capacityUnits: $days-oxygen * $ls-FOOD-PER-SECOND * $day-length * $crewCapacity; + initialUnits: $days-oxygen * $ls-FOOD-PER-SECOND * $day-length * $crewCapacity; + } + } + } +} +``` + +And then, other mods can easily change the day length for your mod using the `@update-config` statement, like the following +for example: + +``` +@update-config 0, "ls-constants", "ls-day-length": 86400; +``` \ No newline at end of file diff --git a/Writerside/topics/Getting-Started-With-Patch-Manager.md b/Writerside/topics/Getting-Started-With-Patch-Manager.md index b25e142..79297b8 100644 --- a/Writerside/topics/Getting-Started-With-Patch-Manager.md +++ b/Writerside/topics/Getting-Started-With-Patch-Manager.md @@ -118,6 +118,7 @@ Depending on your answer to the prior question, there are multiple ways to set u swinfo.json patches/ libraries/ + configs/ diff --git a/Writerside/topics/How-to-Use-the-Stage-System.md b/Writerside/topics/How-to-Use-the-Stage-System.md index 64fb01c..f82a386 100644 --- a/Writerside/topics/How-to-Use-the-Stage-System.md +++ b/Writerside/topics/How-to-Use-the-Stage-System.md @@ -1,6 +1,11 @@ # Stages +> This is going to be added in Patch Manager 0.5.0, it is currently not out +> +{style="note"} + + Patch Manager implicitly orders your patches into something called "stages", which are distinct temporal steps for when your patch will run in relation to others. A stage is essentially a name, with a list of relations to their location in time compared to other stages, either "before" certain stages, or "after" other stages. diff --git a/Writerside/topics/Making-Your-Part-Patches-More-Moddable-Using-Configs.md b/Writerside/topics/Making-Your-Part-Patches-More-Moddable-Using-Configs.md deleted file mode 100644 index 60428f7..0000000 --- a/Writerside/topics/Making-Your-Part-Patches-More-Moddable-Using-Configs.md +++ /dev/null @@ -1,3 +0,0 @@ -# Making Your Part Patches More Moddable Using Configs - -Start typing here... \ No newline at end of file diff --git a/Writerside/topics/Patch-Manager-C-Interop.md b/Writerside/topics/Patch-Manager-C-Interop.md new file mode 100644 index 0000000..841116f --- /dev/null +++ b/Writerside/topics/Patch-Manager-C-Interop.md @@ -0,0 +1,3 @@ +# Patch Manager C# Interop + +Start typing here... \ No newline at end of file diff --git a/Writerside/topics/Top-Level-Statements.md b/Writerside/topics/Top-Level-Statements.md index 8b43f94..a9a225a 100644 --- a/Writerside/topics/Top-Level-Statements.md +++ b/Writerside/topics/Top-Level-Statements.md @@ -97,4 +97,24 @@ this by writing `@patch` followed by a comma separated list of strings and a sem > Do not unnecessarily patch labels, the more labels that are patched, the slower patch manager will run on startups where it has to rebuild its cache. > -{style="warning"} \ No newline at end of file +{style="warning"} + +## Declare Configs + +You can declare configs as a top level statement, configs are described in [Configs](Config.md), which is an advanced tutorial. + +For an example config declaration: + +``` +@create-config "ls-constants", "day-length": 21600; +``` + +## Update configs + +You can also update configs as a top level statement. + +For an example of this: + +``` +@update-config 0, "ls-constants", "ls-day-length": 86400; +``` \ No newline at end of file