Skip to content

Race Support Development Guide

Niwatori401 edited this page Sep 29, 2023 · 2 revisions

Race Support

This guide will give a basic rundown of how to use the RimRound toolset to add support for alien races. It is expected you have at least a very basic understanding of XML before you start.

Essential RimWorld Knowledge

RimWorld was made with extensibility in mind. As a result, all items in the game are defined in simple plain text XML files. You can view these in the files of any install of the game. The most important thing to know is every "thing" in the game is defined by a "def" (definition). A def is like the recipe for something in the game. It lists its properties, where to look for its sprites and other things. There are countless def types in the game, but they all follow a few basic rules:

  • The only strictly required field is <defName>
  • <defName> must be unique
  • All other tags are somewhat optional (leaving them off may cause bugs). They usually have default values if you leave them off.

For our purposes here, we are interested in <AlienRace.ThingDef_AlienRace> type defs. These are what HAR uses to define alien race templates.

What is Humanoid Alien Races (HAR)?

Before we start, it's extremely important that we have a good grasp of what it is we're doing. For that, we need to understand exactly what Humanoid Alien Races is and what it does. Most people who have installed mods in their game will know of this mod as it is a requirement for almost all alien races. What HAR does is provide an easy way for others to add a race to the game by only using XML. I recommend you skim their wiki as it will clear up many questions you may have. It's written as a tutorial for using their framework to make a race, but is still useful to know for what comes next.

How does RimRound work?

Besides knowing how HAR works, you also need to know how RR works. On a fundemental level, RR simply adds a hediff to keep track of a pawn's weight (the things in the health tab in-game) and then updates the pawn's graphics based on this data. If you remember our earlier statement about defs, they are like blueprints. When you spawn a pawn, the game uses the definition from the XML file to give attributes to the newly spawned instance. Modders can add functionality to game objects by pasting references to their code inside of the blueprint. These are called "comps" (components).

RimRound has about six comps it adds to pawns. These are what allow the mod to run code on an individual pawn. The thing is, RimRound only adds the comps to the human def. This is because this process is not automatic. To alter a def, you need to write a patch. You can actually find all of the XML patches that RR uses inside of the 1.4/Patches/ folder. If you open any of the files in that folder, the first thing you may notice is that they are massive (or numerous depending on your RR version). At least, some of them are. While these patches were written by hand at the beginning of the project, it soon became apparent this approach would be sisyphean. So, the "patch maker" was written. To add race support you will almost exclusively use the patch maker.

What is "Race Support"?

Race support comes in two flavors: basic and full. For the most part, we don't ship basic only support for races because it looks terrible.

Basic support means that they get the custom RR gizmos (the buttons at the bottom of the screen when you click the pawn), they change sprites dynamically and the digestion system works. This is the easiest to add and technically, could be done automatically. However, there are good reasons for not doing this. For one, some races are really not so human. They may completely remove the hunger bar, they may have robotic sprites and they may have custom functionality that directly interferes with RR. Further, only basic support could reasonably be automatic.

The second and much more involved part of race support is making it look good. The villains in this story are tails and ears. Basic support often leaves races with their head floating away from their bodies, their tail on their face and ears floating in a pile off screen. To fix this, we have to oftentimes completely change how the orignal mod author aligned their body parts. This too is accomplished with the patch maker and instructions for what to look for are later in this guide. But, fundementally, race support consists of the following broad steps:

  1. Add comps to the new race and remove existing alignment details.
  2. Check that they:
    • Have the weight and fullness hediffs
    • Have dynamic sprites working (when they gain weight their sprite changes)
  3. Launch the game and use the in-game tools to get new alignment data.
  4. Create new patches that write your changes to the alien's def.
  5. Confirm that your changes look good in-game after a restart.

Using the Patch Maker

This is the meat of it. If you can use the patch maker, you can make race support for almost any HAR race work. There is a pretty steep learning curve for this tech though, so don't feel bad if it takes a while to get the hang of it. For demonstration, we will use the Revia race mod here. I recommend clicking through the github to follow along.

  1. Have RR (dev branch) and it's dependencies installed. You will also need to install Lua
  2. Download the current mod files for the race you want to use. This is most easily done with the workshop.
  3. Install it in your RimWorld installation.
  4. Open the alien race mod's folder. This will be one of the folders in Steam/steamapps/Workshop/294100/. It will look like a bunch of numbers. You may be able to open the folder directly from RimWorld's mod manager.
  5. Open the mod's About.xml file in the About folder. Take note of the contents of the <name> tag. For the revia mod, this is "Revia Race". We will need this later.
  6. Navigate to the mod's Defs folder. This may be nested inside of another folder like "1.4". Inside of the Defs folder, look for something that appears to be a race definition. There's no standard here, so you just have to look. You'll know you've found one when you see a <AlienRace.ThingDef_AlienRace> tag (usually at or near the top) in the file.
  7. Take note of the value in <defName>. For the Revia mod, this is "ReviaRaceAlien".
  8. Now we will make patch maker entries.
    • Navigate to the RimRound/1.4/Patches/PatchMaker/ folder.
    • You will see .csv files and .~xml files. You only need to edit the csv files.
    • Typically, you will need to add the mod name (from About.xml) in the first column and the defName in the second column for each entry.
    • Consult the table below for more information on which file you need to edit. When you have finished editing a set of csv's, you can generate patches by navigating to RimRound/1.4/Patches/ and running this command lua NeoPatchMaker.lua. Follow the prompts in the patch maker.
    • In general, you will do two passes of patches. First, make entries in:
      • compsPatches.csv
      • alignWithHeadPatches.csv (if applicable)
      • removeScaleWithBodyDrawsizeTag.csv (if applicable)
      • removeBodySpecificOffsetsPatches.csv (if applicable)
    • Then, you will run the patch maker, launch the game, align the body parts and make entries in these:
      • bodyPartAlignmentPatches.csv
      • bodyTypeSpecificAlignmentPatch.csv
    • There are more than just the csv's listed below. However, their use is rare and nuanced. Rather than explain every closet case its better to address their use when you find an issue you can't solve with the ones below.
Reason csv file Additional notes
I want to add the basic functionality though comps compsPatches.csv Almost every single race needs an entry here first
I want to add the alignWithHead tag alignWithHeadPatches.csv
I want to remove the scaleWithPawnDrawsize tag removeScaleWithBodyDrawsizeTag.csv
I want to align a body part that is anchored on the head (ears/horns) bodyPartAlignmentPatches.csv
I want to align a body part that isn't anchored on the head (like tails) bodyTypeSpecificAlignmentPatch.csv This file is HUGE. More instructions on how to best get these values are provided elsewhere
I want to remove the offsets for a body part that are defined specifically for each body type removeBodySpecificOffsetsPatches.csv

Assigning the race a bodyset

In the background, RimRound uses a hashmap to map race names to body sets. This allows for things such as the Ratkins using a smaller body set than everyone else. While there are other effects for this, the primary use of this is to assign different "size" sprite sizes to races by default. It is worth noting that without following the steps in this section, no visual changes will happen for a given race. They will have all other relevant effects, but their body type will never change. Fortunately, this step is very easy to do.

First, open the file 1.4/Languages/English/Keyed/RimRound_Keys.xml

At the bottom of the file, find these two tags: <RR_RaceData> and <RR_TextureData>

Take note of these two tags and their content as you will have to edit them further later. Each of the two tags are described below.

  • RR_RaceData

    1. This is the more important of the two. Failure to fill out this section will results in non-changing sprites.
    2. To add support, simply add a new row anywhere in the tag (ideally in alphabetical order) and paste the race's defName followed by a comma.
    3. After the comma, put one of a few preset values. These represent body sets defined by RimRound. They must match exactly to one of the values below.
      • defaultSet
        • Typically, you will choose this set. It is the normal full size sprite set.
      • set090
        • Small races such as Ratkin use a smaller sprite prior to RimRound touching them. To keep this consistent, this set provides a slightly smaller set. it is meant to be roughly 90% of the standard set size.
      • set070
        • Extremely small races use this set. Examples include Dogbolds/Foxbolds. This set can look extremely weird, so use with caution.
      • ratkinSet
      • rabbieSet
      • antySet
        • The three above racial options should be largely ignored, but are presented here for completeness. Specifically, these sets are variations of the set090 and defaultSets with some of the default sprites removed. These bespoke sets usually address some unique aspect of a particular mod that requires special treatment.
  • RR_TextureData

    1. This tag contains sprite variations. While the above tag primarily controls how the sprites are rendered (size, position), this tag controls which sprite textures are used. Currently, the only option for this field is "BW" (Black/White). Bamboo's sprite set is ever so slightly skin colored by default. This is good most of the time, but often times furry races look bad with this texture. Particularly pure white pawns (polar bears, snow leopards etc.) look bad. If you'd like a race to use the colorless version, add an entry with the race's defName followed by a comma and "BW".

Body Type Specific Alignment

This is the single most painful part of the process. If your pawn doesn't have a tail, congratulations! You probably can skip this section. Otherwise, buckle up, it sucks.

  1. Make sure the pawn has basic RimRound support.
  2. Make sure you have stripped off all existing body type alignment from the pawn's def with removeBodySpecificOffsetsPatches.csv.
  3. Enable dev mode in RimWorld options.
  4. Load into a test world and spawn one of the pawns with dev tools.
  5. Go to the RR menu and enable special debug settings
  6. Make sure you have the debug console open. It's at the top of the screen and looks like a little "paper" symbol.

Now, you need to get familiar with the dev buttons. Some are self explanatory. A brief summary of some of the most important / least intutive follows.

[Change magnitude] - Changes order of magnitude for changes. When using other settings you will need to change this to suit your use case. Cycles between 0.01, 0.1, 1, 10, 100, 1000, 10000, 100000.
[Change direction] - Positive or negative.
[Change cardinality] - North, West, East, South. Used in [Change extra body part offset]
[Change X/Y] - For offset buttons, which axis to affect.
[Add/Subtract Severity] - Causes pawn to lose/gain weight equal to magnitude * direction.
[Change offset item] - Changes which body part on an alien pawn is being adjusted. Cycles through all available body parts.
[Change extra body part offset] - Actually moves the body parts. Moves them an amount equal Magnitude * direction and is affected by X/Y and "Change offset item".
[Change head offset] - Shouldn't be necessary for race support, but is used rarely. It moves their head by an amount equal to magnitude * direction.

Align each body part. If it is something anchored to the head, use the instructions in the section below this. Otherwise let's continue. In RimRound/Source/RimRound/ there is a file called "AlignThatTail.ods" (It's a spreadsheet). It makes this process MUCH quicker. It interpolates where the tail should probably be aligned based on only a few data points that you find in-game. Because of this, however, you must make good measurements. Bad measurements will lead to bad predictions and make your work pointless. This is a measure twice, cut once sort of thing.

Usage of the file is a bit nuanced, so be careful. First, in the RR tab, navigate to the race settings at the top. Then, find your race. Switch their preset to the Bamboo 090 set. Then, align your body parts. When you get a tail where you think it should be, note the values in the debug log, and copy them into the apprpriate cells in the sheet. You don't need all cells filled out, just a few. Lastly, copy the table that says "OUTPUT" into the bodyTypeSpecificAlignmentPatch.csv file and run the patch maker. Check to see if it looks good. If it does, congratulations, you're done. Else, start over.

Body Type Alignment (ears/horns)

Assuming you're aligning ears/horns or something else that is stapled to their head, the process if pretty easy. First, remove any body specific offsets with removeBodySpecificOffsetsPatches.csv and make sure that the body parts are aligned to head with alignWithHeadPatches.csv if they aren't already. Then, do the following:

  1. Perform the steps in the section above to get the environment ready.
  2. You'll use all the same buttoms, but you only need to align the parts once.
  3. Once you get values for the body part, take note of the values in the console and copy them to bodyPartAlignmentPatches.csv. Run the patch maker.

Common Problems

My race has changing sprites, but some of the non-custom sprites don't work

If your race has a purple square for a body, but the custom RimRound bodies are not purple squares, this usually means that the race mod creator did two things:

  • They changed the graphic path for the race's bodies.
  • They didn't add replacements for at least some of the vanilla bodies.

To fix this, first locate where the original mod stores its body textures. You can find this by either reading the raceDef file or exploring the mod's Textures/ folder. When you find the texture folder containing their race's body textures, note the folder structure. We will need to copy that structure. For example, If their mod looks like this:

|-About
|-Defs
|-Source
|-Textures
..|-Pawn
....|-Bodytextures
......|-(a bunch of pngs)

  1. You will need to recreate a folder structure like XXModRaceSupport/Textures/Pawn/Bodytextures/
  2. Insides the deepest folder you made, you will need to add all of the missing vanilla body textures. You can find a copy of this in RimRound/Textures/VanillaBodies folder. Copy those into the newly created folder structure.
  3. Move your new folders into RimRound/1.4/ExternalMods. Copy the folder name (XXModSupport)
  4. Open RimRound/loadFolders.xml. Make a new entry in the <1.4> tag.
    • Now you will need to open the target mod's About.xml again. Look for the "packageID" tag. Copy the contents of that tag.
    • Copy that into the quote area of IfModActive in your new entry.
    • When RimWorld loads a mod, it loads everything in certain named folders. If mod makers want to load additional folders, they use loadFolders.xml which RimWorld looks at. The IfModActive property conditionally loads the folders only if a mod with the target package id is found.
    • Your final entry should look something like this: <li IfModActive="com.example.modname">1.4/ExternalMods/XXModSupport

A race used to work but now it doesn't

This happens somewhat frequently, unfortunately. If all functionality has stopped, the most likely scenario is that the mod author either updated the name of the mod in the About.xml or they changed the defName of the alien race.

If the alignments are busted, they either changed the sprite sheets (in which case you have to start over with the alignments) or they simply changed where they were applying the alignments within the def itself (in which case you just need to remove the new fields with the patchmaker).

The body parts (ears/tail) get bigger as the pawn sprite does

Check for a <scaleWithPawnDrawsize> tag in the race definition file. If this exists and is set to true, put an entry in removeScaleWithBodyDrawsizeTag.csv.

Other Questions

What about Biotech races?

They work on completely different tech, unfortunately. Support for this is coming, but will require an entirely different process.

Lastly...

Thank you! I appreciate your interest in contributing to RimRound Race support. It historically has been something that substantially detracted from my ability to develop other features. I have spent probably upward of 150 hours pinning-the-tail on the RimWorld pawn. Thankfully, this process has been improved over time so it takes much less time now. If you need help don't hesitate to ask me questions on discord.