Difference between revisions of "Modding Tutorials/ConfigErrors"

From RimWorld Wiki
Jump to navigation Jump to search
(Created page with "//Todo")
 
(Create page)
Line 1: Line 1:
//Todo
+
== 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