Modding Tutorials/Smelter
This tutorial introduces how to make an interactive building. Currently, only work benches can be fully modified using .xml. The Comms console and Nutrient paste dispenser have hard-coded elements. So here we will set out to make a building that follows the work bench pattern.
Concept
All mods start with a concept. Some are grandiose (adding space pirates to the game). Some, like this one, are modest. The concept of the smelter is simple. Make a building where colonists can take slag debris to melt down into usable metal.
Overview
When you set out to make a building or piece of furniture that operates as a workbench, you need to define three things:
1) The building definition (ThingDef) 2) The work assignment definition (WorkGiverDef) 3) One or more recipe definitions (RecipeDef)
Step 3 is optional if your building duplicates the behavior of an already existing one. For example, if you are making a stone kitchen that uses stone blocks instead of metal to construct, you could skip step 3 and use the same recipes as the standard kitchen model.
Create the Building Definition
This part should be easy. You already did it in the first tutorial. But here is the boilerplate for a new building which will become our smelter. Save this in a file called "Buildings_Smelter.xml" in your mod folder in the Defs/ThingDefs/ subfolder.
<?xml version="1.0" encoding="utf-8" ?> <Buildings> <!-- Boilerplate --> <ThingDef Name="BuildingBase" Abstract="True"> <category>Building</category> <bulletImpactSound>BulletImpactMetal</bulletImpactSound> <selectable>true</selectable> <drawerType>MapMeshAndRealTime</drawerType> <surfaceNeeded>Light</surfaceNeeded> <constructionEffect>ConstructMetal</constructionEffect> <repairEffect>Repair</repairEffect> </ThingDef> <!-- Smelter building definition --> <ThingDef ParentName="BuildingBase"> <DefName>BuildingSmelter</DefName> <EType>BuildingComplex</EType> <Label>Smelter</Label> <ThingClass>Building</ThingClass> <Description>A large, hot furnace used to produce metal from ore.</Description> <TexturePath>Things/Building/TableStonecutter</TexturePath> <CostList> <li> <thingDef>Metal</thingDef> <count>30</count> </li> </CostList> <AltitudeLayer>BuildingTall</AltitudeLayer> <WorkToBuild>600</WorkToBuild> <maxHealth>200</maxHealth> <Size>(3,2)</Size> <surfaceNeeded>Heavy</surfaceNeeded> <DesignationCategory>Building</DesignationCategory> <Passability>Impassable</Passability> </ThingDef> </Buildings>
Go ahead and run the game to test out the above definition. You'll see your colonists build a 3x2 structure that looks about the same as the stone cutter's table (that's because we told it to use the same texture for simplicity's sake).
Now let's add the interaction space. To do this you will need to add the following:
<hasInteractionSquare>true</hasInteractionSquare> <interactionSquareOffset>(0,0,2)</interactionSquareOffset>
The first tag, "hasInteractionSquare" tells the game that this building has an interaction square. It's phrased sort of like a question: "The Smelter has an interaction square?" and then answers the question "Yes, that's true." The second tag, "interactionSquareOffset" tells the game where that square is. The three values refer to the x, y, and z coordinates in the game. This is a bit confusing unless you are are intimately aware of how the Unity engine works. Basically, since Unity is used for 3d games, x, y, and z are mandatory. But Rimworld is 2d so only the x and z coordinates matter. Wait, x and z?! Yes, because in Unity, the y coordinate refers to the vertical space. This value is always 0 because Rimworld is flat. It may be easier to just ignore all this and think of the value as "x, 0, y" instead. The offset is measured as distance from the origin of the object. The smelter is 3 units wide by 2 units tall. It's interaction square will be 2 units above its origin.
[ ][x][ ] x = the offset space (2 spaces above the origin) [■][■][■] [■][□][■] ^--------the origin.
Fire up the game and see what happens. Now when you build the smelter, you should see a yellow circle above it just like with the other interactive buildings in the game. You have successfully told Rimworld that your building has an interaction square! But so far, that's all. Your colonists still have no idea what to do with it.
The next thing to do is to tell the game that the smelter is used to make stuff from something else. This means updating the EType and ThingClass tags. We are going to tell the game that this building is a work table because that function best fits our concept. Edit the tags as follows:
<EType>Building_WorkTable</EType> <ThingClass>Building_WorkTable</ThingClass>
This is just more boilerplate necessary to make the building function as desired. Don't worry about the nuances of Building_WorkTable vs. BuildingComplex or Building_Worktable vs. Building. Those are advanced concepts beyond the scope of this tutorial.
The next thing to add is a definition for the inspector tab. When you click on a building, the inspector tab gives you information about it. We also want to give orders for the smelter on this tab. To do so add the following:
<inspectorTabs> <li>UI.ITab_Bills</li> </inspectorTabs>
This tells the game to use the Bills user interface in the inspection tab of this building. Launch the game again, build a smelter, then click on it to see what happens. You should notice a button called "Bills" above the inspector tab. You can press it just like you can on the kitchen or the stone cutter's table and open the bills menu! If you then click "Add bill"... nothing happens. That's because we haven't given the smelter any "recipes" yet. That is the final addition to the smelter building to make.
Recipes are listed under the recipes tag. For now, we will just add one recipe, the recipe for melting slag into metal:
<recipes> <li>SmeltDebrisSlag</li> </recipes>
You may be asking yourself, "Where does this recipe come from?" And the answer is nowhere yet. We've told the smelter to use a recipe called "SmeltDebrisSlag" but before we launch the game again, we'll have to write the recipe! For now, though, we are done with defining the smelter building. Close the file.
Create a Recipe
So we have a building that let's your colonists cook slag into metal using a recipe called "SmeltSlagDebris". Only one problem, we haven't written the recipe next. To do that make a file called "Recipe_Smelter.xml" in your mod folder in the Defs/RecipeDefs/ subfolder. In this file, add the following boilerplate:
<?xml version="1.0" encoding="utf-8" ?> <RecipeDefs> <RecipeDef> <defName>SmeltDebrisSlag</defName> <label>Smelt slag debris</label> <description>Decomposes slag to extract metal.</description> <jobString>Smelting slag.</jobString> <workAmount>1000</workAmount> <RecipeDef> </RecipeDefs>
Now that the recipe exists, you can start up the game again. Now when you click the "Add bill" button the recipe you just defined should appear! At this point you might be getting a bit tired of waiting for your colonists to build your smelter. There are a couple things you can do. You can either change the value of the "WorkToBuild" tag in the building definition to something much lower, or you can turn on "God mode" which will let you build anything instantly. This is very useful and now might be a good time to become familiar with it if you haven't already!
You might be asking, "What does this recipe actually do?" Well, nothing yet. That's the next step and it's also where things get interesting. Recipes consist of two important parts: ingredients and products. Ingredients go in; products come out.