Basic Plant
This is a basic RimWorld mod tutorial for the purpose of creating a custom plant. We will also use the plant matter gathered from this custom plant in a later tutorial.
Goals[edit]
In this tutorial you will:
- Create ThingDefs for a new plant: theragold, a genetically modified cultivar of marigolds with both nutritional and medicinal benefits
- Learn how to use XML inheritance to share data between multiple ThingDefs
- Assign custom mature and immature plant textures to your new plant
- Add your new plant to existing vanilla and modded biomes
- Create a ThingDef for a new raw food item
- Create a new RecipeDef to craft herbal medicine using this new item
Recommended Reading[edit]
Sample Repository[edit]
A working implementation of this mod can be found in this GitHub repository. You can use it to compare against your work or as a basis for modification!
Folder Setup[edit]
First, you will want to create the files and folders necessary for this mod:
Mods └ MyModFolder ├ About │ ├ About.xml │ └ Preview.png ├ Defs │ ├ RecipeDefs │ │ └ ExampleRecipe_Theragold.xml │ ├ ThingDefs_Items │ │ └ ExampleItem_Theragold.xml │ └ ThingDefs_Plants │ └ ExamplePlant_Theragold.xml └ Textures └ ExampleMod ├ ImmatureTheragold │ └ ImmatureTheragold_a.png ├ Theragold │ └ Theragold_a.png └ RawTheragold.png
Please check out the mod folder structure guide for more information about individual folders.
About.xml[edit]
Your About.xml
is used to identify your mod to RimWorld; please see the About.xml reference page for more information. Be sure to replace "AuthorName" with your own name:
<?xml version="1.0" encoding="utf-8"?> <ModMetaData> <!-- This is the internal identifier for your mod. --> <!-- It is recommended that you make it unique to as to avoid potential collisions with other authors; --> <!-- if Rimworld detects multiple mods with the same packageId then it will refuse to load all of them. --> <packageId>AuthorName.ExamplePlant</packageId> <!-- This is both the displayed name of your mod as well as the name used for patch targeting. --> <name>Example Plant</name> <!-- Your name goes here. --> <author>AuthorName</author> <!-- A version number for your own tracking --> <!-- See wiki About.xml guide for concerns regarding this field for RimWorld versions prior to 1.4 --> <modVersion>1.0</modVersion> <!-- These are the RimWorld game versions that your mod supports. --> <!-- It is recommended that you only list versions that you have explicitly tested to ensure they work, --> <!-- as even basic XML options can change between major versions of the game. --> <supportedVersions> <li>1.4</li> </supportedVersions> <!-- This is the description of your mod shown in both the vanilla mod manager as well as modded managers. --> <description>This is an example melee weapon mod made for the RimWorld Wiki.</description> </ModMetaData>
Sample Assets[edit]
You can use these as the example textures:
Instructions[edit]
1. Create plant ThingDefs[edit]
Our first step is to create the XML that represents our new plant. Whenever possible, this is best accomplished by copying vanilla ThingDefs and modifying them; in this case we will use the three Defs that constitute the vanilla healroot as our starting point, as it is the most similar existing plant to what we want to create. The XML for healroot can be found in Data/Core/Defs/ThingDefs_Plants/Plants_Cultivated_Farm.xml
and Data/Core/Defs/ThingDefs_Plants/Plants_Wild_General.xml
.
In our own ExamplePlant_Theragold.xml
, we'll have the following three ThingDefs:
<?xml version="1.0" encoding="utf-8" ?> <Defs> <!-- Abstract base: TheragoldBase --> <!-- The data from this node will be inherited by our two "concrete" Defs --> <ThingDef ParentName="PlantBase" Name="TheragoldBase" Abstract="True"> <!-- pasted content omitted --> </ThingDef> <!-- Cultivated theragold --> <!-- This ThingDef will inherit all fields from the abstract base TheragoldBase --> <ThingDef ParentName="TheragoldBase"> <defName>ExamplePlant_Theragold</defName> <label>theragold</label> <!-- pasted content omitted --> </ThingDef> <!-- Wild theragold --> <!-- This ThingDef will inherit all fields from the abstract base TheragoldBase --> <ThingDef ParentName="TheragoldBase"> <defName>ExamplePlant_TheragoldWild</defName> <label>wild theragold</label> <!-- pasted content omitted --> </ThingDef> </Defs>
2. Modify our copied ThingDefs[edit]
In order to differentiate our plant from healroot, we'll make the following changes:
TheragoldBase
[edit]
By specifying Abstract="True"
as an attribute, our base ThingDef will not actually be loaded on its own, however its fields will be inherited by ThingDefs that specify its Name
as a parent via ParentName="TheragoldBase"
. This will allow us to share field values between two or more ThingDefs without copying each one.
XML | Description |
---|---|
<graphicData> <texPath>ExampleMod/Theragold</texPath> <graphicClass>Graphic_Random</graphicClass> </graphicData> |
This defines the default mature graphic for our new plant. Graphic_Random is a graphicClass that must be pointed at a folder; this is used by most vanilla plants and allows you to have multiple textures for more visual variety. In the specific case of plants, the texture will also be horizontally flipped at random for additional variety. |
<selectable>true</selectable> |
By default, plants that inherit from |
<plant> <immatureGraphicPath>ExampleMod/ImmatureTheragold</immatureGraphicPath> <growDays>8</growDays> <dieIfLeafless>false</dieIfLeafless> <harvestWork>400</harvestWork> <harvestTag>Standard</harvestTag> <harvestedThingDef>ExamplePlant_RawTheragold</harvestedThingDef> <harvestYield>8</harvestYield> <topWindExposure>0.1</topWindExposure> <visualSizeRange>0.3~1.0</visualSizeRange> <wildOrder>2</wildOrder> <allowAutoCut>false</allowAutoCut> </plant> |
The
|
ExamplePlant_Theragold
[edit]
This will represent the cultivated variant of our new plant. We will start with the vanilla Plant_Healroot
and modify the following:
XML | Description |
---|---|
<ThingDef ParentName="TheragoldBase"> |
We will use our new custom abstract base instead of |
<defName>ExamplePlant_Theragold</defName> |
The |
<label>theragold</label> |
A ThingDef's label is its in-game name. Unless it is a proper name, it should be in lowercase so that it can be injected naturally into sentences that use it. RimWorld will automatically capitalize it as necessary if used in titles or as the start of a sentence. |
<description>Engineered by a long-forgotten glitterworld, theragolds are a genetically modified cultivar of marigolds intended for seeding on terraformed garden worlds. While not particularly efficient at either, theragolds can be eaten for nutrition or processed into various medicinal products. Its hardiness and relative ease of cultivation makes it a valuable secondary crop for frontier colonies.\n\nThis secondary cultivar of theragold is faster-growing but less hardy, and intended for cultivation by frontier colonies.</description> |
This is the full description of our plant as shown in the full stat card when being inspected. |
<plant> <growDays>5</growDays> <sowWork>250</sowWork> <sowMinSkill>6</sowMinSkill> <sowTags> <li>Ground</li> <li>Hydroponic</li> </sowTags> <purpose>Food</purpose> </plant> |
We will add or override the following fields in our
|
ExamplePlant_TheragoldWild
[edit]
This will represent the wild variant of our new plant. We will start with the vanilla Plant_HealrootWild
and modify the following:
XML | Description |
---|---|
<ThingDef ParentName="TheragoldBase"> |
We will use our new custom abstract base instead of |
<defName>ExamplePlant_TheragoldWild</defName> |
The |
<label>wild theragold</label> |
A ThingDef's label is its in-game name. Unless it is a proper name, it should be in lowercase so that it can be injected naturally into sentences that use it. RimWorld will automatically capitalize it as necessary if used in titles or as the start of a sentence. |
<description>Engineered by a long-forgotten glitterworld, theragolds are a genetically modified cultivar of marigolds intended for seeding on terraformed garden worlds. While not particularly efficient at either, theragolds can be eaten for nutrition or processed into various medicinal products. Its hardiness and relative ease of cultivation makes it a valuable secondary crop for frontier colonies.\n\nThis original cultivar of theragold is hardier but slower-growing than the modified variant intended for human cultivation and can be found growing wild in a variety of biomes.</description> |
This is the full description of our plant as shown in the full stat card when being inspected. |
<neverMultiSelect>false</neverMultiSelect> |
By default, plants will not be selected when the player band-box selects regions of the map. We want to override this behavior as wild theragold is both edible and has medicinal value. |
<plant> <wildClusterRadius>4</wildClusterRadius> <wildClusterWeight>80</wildClusterWeight> <wildBiomes> <!-- These values match the vanilla weights of wild healroot --> <TemperateForest>0.05</TemperateForest> <TemperateSwamp>0.05</TemperateSwamp> <BorealForest>0.16</BorealForest> <Tundra>0.05</Tundra> <ColdBog>0.05</ColdBog> <!-- These are examples of optional compatibility entries for modded biomes --> <!-- This is the "feralisk-infested jungle" biome from Alpha Biomes by Sarg --> <AB_FeraliskInfestedJungle MayRequire="sarg.alphabiomes">0.05</AB_FeraliskInfestedJungle> <!-- This is the "idyllic meadow" biome from Alpha Biomes by Sarg --> <AB_IdyllicMeadows MayRequire="sarg.alphabiomes">0.05</AB_IdyllicMeadows> <!-- This is the "alpine meadow" biome from More Vanilla Biomes by Zylleon --> <ZBiome_AlpineMeadow MayRequire="zylle.MoreVanillaBiomes">0.05</ZBiome_AlpineMeadow> <!-- This is the "cloud forest" biome from More Vanilla Biomes by Zylleon --> <ZBiome_CloudForest MayRequire="zylle.MoreVanillaBiomes">0.05</ZBiome_CloudForest> <!-- This is the "desert oasis" biome from More Vanilla Biomes by Zylleon --> <ZBiome_DesertOasis MayRequire="zylle.MoreVanillaBiomes">0.05</ZBiome_DesertOasis> <!-- This is the "grasslands" biome from More Vanilla Biomes by Zylleon --> <ZBiome_Grasslands MayRequire="zylle.MoreVanillaBiomes">0.05</ZBiome_Grasslands> <!-- This is the "marsh" biome from More Vanilla Biomes by Zylleon --> <ZBiome_Marsh MayRequire="zylle.MoreVanillaBiomes">0.05</ZBiome_Marsh> <!-- This is the "boreal island" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_BorealIsland MayRequire="BiomesTeam.BiomesIslands">0.16</BiomesIslands_BorealIsland> <!-- This is the "temperate island" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_TemperateIsland MayRequire="BiomesTeam.BiomesIslands">0.05</BiomesIslands_TemperateIsland> <!-- This is the "temperate archipelago" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_TemperateArchipelago MayRequire="BiomesTeam.BiomesIslands">0.05</BiomesIslands_TemperateArchipelago> <!-- This is the "tropical island" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_TropicalIsland MayRequire="BiomesTeam.BiomesIslands">0.05</BiomesIslands_TropicalIsland> <!-- This is the "tropical archipelago" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_TropicalArchipelago MayRequire="BiomesTeam.BiomesIslands">0.05</BiomesIslands_TropicalArchipelago> <!-- This is the "tundra island" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_TundraIsland MayRequire="BiomesTeam.BiomesIslands">0.05</BiomesIslands_TundraIsland> <!-- This is the "tundra archipelago" biome from Biomes! Islands by the Biomes! team --> <BiomesIslands_TundraArchipelago MayRequire="BiomesTeam.BiomesIslands">0.05</BiomesIslands_TundraArchipelago> <!-- This is the "chromatic oasis" biome from Biomes! Oasis by the Biomes! team --> <BMT_ChromaticOasis MayRequire="BiomesTeam.Oasis">0.2</BMT_ChromaticOasis> </wildBiomes> </plant> |
In addition to vanilla biomes, we also have optional compatibility entries for several popular biome mods. These examples use MayRequire to safely disable themselves if the specified mod is not loaded, and have been listed here with their authors' permission. Note that this is not an exhaustive list of either vanilla biomes nor the modded biomes in their respective mods; these are the ones that our plant should plausibly appear in and individual choices are subject to creative liberty. |
3. Create a raw food ThingDef[edit]
Now, we will create a new ThingDef to represent the raw food item harvested from our new plant. As before, we can and should copy an existing vanilla ThingDef as a starting point; in this case, we can copy RawRice
, RawPotatoes
, or RawCorn
from Data/Core/Defs/ThingDefs_Items/Items_Resource_RawPlant.xml
:
<?xml version="1.0" encoding="utf-8" ?> <Defs> <!-- Example raw food: raw theragold --> <ThingDef ParentName="PlantFoodRawBase"> <!-- pasted content omitted --> </ThingDef> </Defs>
Modifying the ThingDef[edit]
This will represent the wild variant of our new plant. We will start with the vanilla Plant_HealrootWild
and modify the following:
XML | Description |
---|---|
<defName>ExamplePlant_RawTheragold</defName> |
The |
<label>theragold flowers</label> |
A ThingDef's label is its in-game name. Unless it is a proper name, it should be in lowercase so that it can be injected naturally into sentences that use it. RimWorld will automatically capitalize it as necessary if used in titles or as the start of a sentence. |
<description>Raw theragold flowers. This can be cooked into meals or crafted into various medicinal products.</description> |
This is the full description of our item as shown in the full stat card when being inspected. |
<graphicData> <texPath>ExampleMod/RawTheragold</texPath> </graphicData> |
This is the texture we will use for our food item. Note that |
<comps> <li Class="CompProperties_Rottable"> <daysToRotStart>30</daysToRotStart> <rotDestroys>true</rotDestroys> </li> </comps> |
Our <daysToRotStart> will be set to 30, which will make it rot slower than raw fruits and vegetables, but faster than grains such as rice or corn. |
4. Create a medicine RecipeDef[edit]
Finally, we will create a new RecipeDef that will allow us to craft herbal medicine from raw matter harvested from our custom plant. Since there is no direct vanilla analogue to this recipe, we will be created it from scratch, starting in our ExampleRecipe_Theragold.xml
file:
<?xml version="1.0" encoding="utf-8" ?> <Defs> <!-- Example recipe: make herbal medicine from theragold flowers --> <RecipeDef> <!-- content to be filled here --> </RecipeDef> </Defs>
Filling in the RecipeDef[edit]
This will represent the wild variant of our new plant. We will start with the vanilla Plant_HealrootWild
and modify the following:
XML | Description |
---|---|
<defName>ExamplePlant_Make_MedicineHerbal</defName> |
In addition to our mod prefix, vanilla naming convention -- including those for auto-generated crafting recipes -- is to prefix "Make_" onto the defName of the final product, so we will maintain the same general naming general convention to inform the nature of our custom RecipeDef. |
<label>make herbal medicine from theragold</label> |
For RecipeDefs, its label is what is shown in the Add Bill list for workbenches, so qualifying it with the primary ingredient can help differentiate it from other potential recipes for the same product. |
<description>Make herbal medicine from theragold flowers.</description> |
This is the full description of our recipe as shown in the full bill interface. |
<jobString>Making herbal medicine from theragold flowers.</jobString> |
This string is shown in a pawn's inspect pane when it is performing work on this recipe. |
<effectWorking>Cook</effectWorking> |
This specifies an EffecterDef that should be used while this recipe is being worked on. We will use the same one used for cooking meals. |
<soundWorking>Recipe_CookMeal</soundWorking> |
This specifies a SoundDef that should be sustained while this recipe is being worked on. We will also use the same sound effect used for cooking meals here. |
<workSkill>Cooking</workSkill> |
This specifies the primary skill associated with this recipe. This is the skill that will gain experience points when work is done on this recipe, as well as being the filtering skill used in the bill interface. |
<workAmount>300</workAmount> |
300 work matches the amount of work required for vanilla simple meals, and equates to approximately 5s of time at 100% work speed. |
<workSpeedStat>GeneralLaborSpeed</workSpeedStat> |
This is the StatDef used to determine how quickly a pawn performs the work required to complete this recipe. |
<recipeUsers> <li>CraftingSpot</li> <li>DrugLab</li> </recipeUsers> |
Specifies the workbenches that this recipe can be performed at via their Note that you can also accomplish this by using a PatchOperation on the targeted workbenches, but this is usually the easier way to introduce a new recipe, especially if you are not targeting your own workbenches. |
<ingredients> <li> <filter> <thingDefs> <li>ExamplePlant_RawTheragold</li> </thingDefs> </filter> <count>12</count> </li> </ingredients> |
The |
<fixedIngredientFilter> <thingDefs> <li>ExamplePlant_RawTheragold</li> </thingDefs> </fixedIngredientFilter> |
The |
<products> <MedicineHerbal>1</MedicineHerbal> </products> |
This specifies the items that should be produced by this recipe. Our goal is to produce a single herbal medicine for each instance of this recipe being performed. |
<skillRequirements> <Crafting>2</Crafting> </skillRequirements> |
Finally, we will put a low requirement of 2 Crafting skill needed to perform this recipe. Note that this entire tag can be omitted if you do not want a skill requirement at all. |
5. Done![edit]
Your first plant is complete! Boot up RimWorld and you should be able to see and enable the "Example Plant" mod in your mod manager. You can then start a new game on an appropriate biome, use dev mode tools to spawn the plant directly, or sow it in a growing zone with a sufficiently skilled colonist. Be sure to also check out the crafting recipe on the appropriate workbenches!
If you get any errors, be sure to check out the troubleshooting guide or join us on the #mod-development channel on the RimWorld Discord server.