Difference between revisions of "Modding Tutorials/ConfigErrors"
(Created page with "//Todo") |
(Create page) |
||
Line 1: | Line 1: | ||
− | // | + | == Preamble == |
+ | Who this is for: | ||
+ | Modders that implement their own XML-loading classes, like new Def. | ||
+ | |||
+ | ConfigErrors are the red errors you are presented when the game launches and detects erroreous XML data, like a required field not being set or a value of a field being out of its range. | ||
+ | |||
+ | Chances are, you have seen plenty of these errors in the past, some may consider them an annoyance, but if done right, they inform both the modder and the user of potentially critical issues in the XML data provided. | ||
+ | |||
+ | === Subclassing Def === | ||
+ | The most applicable example of ConfigErrors is subclassing ''Def''. | ||
+ | |||
+ | <source lang="csharp"> | ||
+ | public class MyOwnDef : Def | ||
+ | { | ||
+ | float someValue = 4f; // only allow values bettwen 0-10 | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Let's assume we have our new Def here and it has a special value that is only allowed to be in the range of 0 - 10, with the default value being 4. | ||
+ | |||
+ | Anyone can easily add a new ''MyOwnDef'' to your mod, and you could put documentation out there in the hopes that someone reads it and properly only assigns values between 0-10 to your ''someValue'' or that they stumble over your tiny comment. | ||
+ | |||
+ | Or you can provide ConfigErrors that yell at anyone trying to use a value that you don't explicitly allow for your own Def. | ||
+ | |||
+ | <source lang="csharp"> | ||
+ | public class MyOwnDef : Def | ||
+ | { | ||
+ | float someValue = 4f; | ||
+ | const float minSomeValue = 0f; | ||
+ | const float maxSomeValue = 10f; | ||
+ | |||
+ | public override IEnumerable<string> ConfigErrors() | ||
+ | { | ||
+ | foreach(string error in base.ConfigErrors()) | ||
+ | yield return error; | ||
+ | if(someValue < minSomeValue || someValue > maxSomeValue) | ||
+ | yield return $"someValue is {someValue}, which is out of the valid range of {minSomeValue} - {maxSomeValue}!"; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | To break it down, ''Def'' already implements a virtual ConfigErrors(), which we can override in our ''MyOwnDef''. Because this is a virtual IEnumerable, it makes sense to call the base.ConfigErrors(), which will run the basic ''Def'' validation (like setting a defName) - and then yield our own desired config errors. | ||
+ | |||
+ | I personally dislike numbers anywhere in code, so I define constant values and compare to those, you could theoretically just compare directly to your desired limits. | ||
+ | |||
+ | ===Notes=== | ||
+ | In case you are a new comer, here are some things you may want to research via Google: | ||
+ | |||
+ | public override | ||
+ | Overriding a base member, in this case a public Method | ||
+ | |||
+ | yield return | ||
+ | Returns a single item in a collection, only works on methods with the method signature IEnumerable<T> | ||
+ | |||
+ | $"someValue is {someValue}, which is out of the valid range of {minSomeValue} - {maxSomeValue}!"; | ||
+ | The string here uses String Interpolation, which is a quick and easy way of embedding variables into a logging string |
Revision as of 12:17, 3 September 2022
Preamble
Who this is for: Modders that implement their own XML-loading classes, like new Def.
ConfigErrors are the red errors you are presented when the game launches and detects erroreous XML data, like a required field not being set or a value of a field being out of its range.
Chances are, you have seen plenty of these errors in the past, some may consider them an annoyance, but if done right, they inform both the modder and the user of potentially critical issues in the XML data provided.
Subclassing Def
The most applicable example of ConfigErrors is subclassing Def.
public class MyOwnDef : Def { float someValue = 4f; // only allow values bettwen 0-10 }
Let's assume we have our new Def here and it has a special value that is only allowed to be in the range of 0 - 10, with the default value being 4.
Anyone can easily add a new MyOwnDef to your mod, and you could put documentation out there in the hopes that someone reads it and properly only assigns values between 0-10 to your someValue or that they stumble over your tiny comment.
Or you can provide ConfigErrors that yell at anyone trying to use a value that you don't explicitly allow for your own Def.
public class MyOwnDef : Def { float someValue = 4f; const float minSomeValue = 0f; const float maxSomeValue = 10f; public override IEnumerable<string> ConfigErrors() { foreach(string error in base.ConfigErrors()) yield return error; if(someValue < minSomeValue || someValue > maxSomeValue) yield return $"someValue is {someValue}, which is out of the valid range of {minSomeValue} - {maxSomeValue}!"; } }
To break it down, Def already implements a virtual ConfigErrors(), which we can override in our MyOwnDef. Because this is a virtual IEnumerable, it makes sense to call the base.ConfigErrors(), which will run the basic Def validation (like setting a defName) - and then yield our own desired config errors.
I personally dislike numbers anywhere in code, so I define constant values and compare to those, you could theoretically just compare directly to your desired limits.
Notes
In case you are a new comer, here are some things you may want to research via Google:
public override
Overriding a base member, in this case a public Method
yield return
Returns a single item in a collection, only works on methods with the method signature IEnumerable<T>
$"someValue is {someValue}, which is out of the valid range of {minSomeValue} - {maxSomeValue}!";
The string here uses String Interpolation, which is a quick and easy way of embedding variables into a logging string