Difference between revisions of "Modding Tutorials/XML Defs"
(Filling some great big knowledge gaps) |
|||
Line 1: | Line 1: | ||
{{BackToTutorials}}<br/> | {{BackToTutorials}}<br/> | ||
+ | Defs are packages containing most of the content for the game. They are stored in human-readable XML files, and you can take a look at them right now by browsing the Mods/Core/Defs folder located in the RimWorld install directory. There are many different types of ''Defs'', the most common being [[Modding Tutorials/ThingDef|ThingDef]]. Other examples of Defs are RecipeDef, ResearchProjectDef and TerrainDef. | ||
− | + | Think of Defs as the system that turns a generic plant into a [[Potato plant|Potato-]], [[Rice plant|Rice-]] or [[Corn plant]]. The C# contains the plant and its behaviour like growing and getting harvested the Defs determine how fast it grows and what its harvest products are. | |
=Requirements= | =Requirements= | ||
Line 7: | Line 8: | ||
# A basic understanding of [https://www.w3schools.com/xml/ XML] is recommended. | # A basic understanding of [https://www.w3schools.com/xml/ XML] is recommended. | ||
# Some C# knowledge is helpful for a deeper understanding of the behind-the-scenes workings, but not required. | # Some C# knowledge is helpful for a deeper understanding of the behind-the-scenes workings, but not required. | ||
+ | |||
+ | =What you'll learn= | ||
+ | This tutorial will tell you about the structure of Defs. It will explain the link between C# and Defs, as well as go over some common errors. If you want to learn what every tag for a Def is, read the [[Modding Tutorials/ThingDef|ThingDef]] article. | ||
=Structure= | =Structure= |
Revision as of 09:57, 6 February 2019
< Modding Tutorials
Defs are packages containing most of the content for the game. They are stored in human-readable XML files, and you can take a look at them right now by browsing the Mods/Core/Defs folder located in the RimWorld install directory. There are many different types of Defs, the most common being ThingDef. Other examples of Defs are RecipeDef, ResearchProjectDef and TerrainDef.
Think of Defs as the system that turns a generic plant into a Potato-, Rice- or Corn plant. The C# contains the plant and its behaviour like growing and getting harvested the Defs determine how fast it grows and what its harvest products are.
Requirements
- You've read XML file structure.
- A basic understanding of XML is recommended.
- Some C# knowledge is helpful for a deeper understanding of the behind-the-scenes workings, but not required.
What you'll learn
This tutorial will tell you about the structure of Defs. It will explain the link between C# and Defs, as well as go over some common errors. If you want to learn what every tag for a Def is, read the ThingDef article.
Structure
As previously established, the root node of all defs in the game is <Defs>. RimWorld will try to interpret everything between the opening tag of <Defs> and <Defs> as a type of def. These types correspond to a C# class which inherits from the Def class. For example
<Defs> <ThingDef> </ThingDef> </Defs>
points to the ThingDef class, which in C# inherits from the Def class. All XML nodes inside the <ThingDef> tag are a field in the ThingDef class. These fields can hold references to simple values like integers or strings. defName is one such string in the base Def class, so we'll give our ThingDef a defName of SomeName. A field can also contain more complex values like IngestibleProperties. The XML tag (and field name) that corresponds to IngestibleProperties is called ingestible. IngestibleProperties also has fields of its own, and these would go inside the ingestible tag, as a childnode. IngestibleProperties has a field of type SoundDef with the name of ingestSound. RimWorld resolves these by both Type and defName. Fleshing out our example with an ingestSound, our example now looks like this:
<Defs> <ThingDef> <defName>SomeName</defName> <ingestible> <ingestSound>Slurp</ingestSound> </ingestible> </ThingDef> </Defs>
The rootnode of our example is <Defs>. The first childnode of <Defs> is <ThingDef>. <defName> and <ingestible> are both childnodes of <ThingDef> and they are siblingnodes of each other. Proper XML formatting will help you a lot in distinguishing the hierarchy of your XML. You can save yourself a lot of hassle if you get a text editor (or plugin) which can auto-format XML for you.
Common errors
For beginning coders, the most common errors are formatting or syntax errors. A missing bracket, unclosed tag, empty file - these can all be avoided by using the proper tools. Get a text editor (or plug-in) that highlights or warns for these basic issues. RimWorld will not warn you: at best it will overload you with errors, at worst it will refuse to start.
Other common errors are related to resolving cross-references. For instance: def A wants to use def B, but def B can't be found. These cross-references are by defName. Both Type and defName have to match. In our earlier example, if there isn't a SoundDef with the Slurp defName, the game will log the following error:
Could not resolve cross-reference: No SoundDef named Slurp found to give to ThingDef SomeName.
If the game can't find a cross-reference in a list, the error is slightly different:
Could not resolve cross-reference to Verse.ThingCategoryDef named BuldingsPower (wanter=thingCategories)
where wanter=thingCategories is an optional addition, but it's the xml tag containing the misspelled "BuildingsPower".
Other errors are:
- Defining the same field/tag twice
XML RimWorld.ThoughtDef defines the same field twice: stackLimit. Field contents: 1. Whole XML: <A lot of XML>
In this example, there is a ThoughtDef with two stackLimit entries. Likely the result of two mods patching the same Def. The first mod wins.
- Missing a Type
Could not find type named TurretExtensions.CompProperties_Upgradable from node <A lot of XML>
This happens when an XML mod refers to a type which isn't loaded. In practice, a missing (DLL) dependency, a (DLL) dependency which couldn't be loaded due to earlier errors, or an outdated mod.
- Referencing a non-existing field
XML error: <costStaffCount>50</costStaffCount> doesn't correspond to any field in type ThingDef. Context: <ThingDef ParentName="SculptureBase"><defName>SculptureSmall</defName><label>small sculpture</label><description>An artistic sculpture.</description><stuffCategories><li>Metallic</li><li>Woody</li><li>Stony</li></stuffCategories><costStaffCount>50</costStaffCount></ThingDef>
This happens when the parentnode (in this case ThingDef) does not contain an entry for the costStaffCount tag. This could be caused by a simple typo, by putting the tag in the wrong node, by a missing dependency, as a result of earlier errors, or an outdated mod. XML can only correspond to fields that are defined in C#.
Note about (solving) XML errors
XML errors cascade. Behind the scenes, RimWorld combines all Defs inside one massive XML document. If one <tag> is missing its closing </tag>, none of the XML will be readable by the parser and you will be greeted by a wall of red errors. Find the first XML error, and fix that one. Do not go chasing the other errors just yet. Reload the game, then fix the next error (if any).