Modding Tutorials/Mod folder structure
This page was originally created by Alistaire.
This tutorial introduces you to the mod folder structure and shows you a standard folder structure setup to help you start out.
Complete mod folder structure is a list of all folders you might find in your average mod directory. This includes /Core/.
Requirements
- Exploring the Folder Structure starts off explaining the folder structure. This is part two if you will.
What you'll learn
You'll learn the following mod structure:
YourModName/ About/ About.xml Preview.png Assemblies/ ProjectName.dll Defs/ (..) Languages/ English/ Strings/ NameBanks/ Patches/ Sounds/ Source/ ProjectName/ ProjectName.sln Textures/
.. Along with a few tips on how to keep your mod folder structure readable and functional.
Standard mod folder structure
Mod folders are located in the mods folder, which is located as such:
RimWorld******/ Mods/
..relative to your RimWorld install directory. Each mod is a sub folder of this Mods folder and each mod has to follow the following structure precisely. Your mod needs an About folder and optionally at least one of the following: Assemblies, Defs, Patches, Languages, Textures, Sounds. It is not recommended to have empty folders, and RimWorld will choke on empty or malformed xml files.
The About folder
Making a mod starts with you making a folder structure. Some mods need textures and sounds, while others are XML or even C# only.
Every mod does however require the following structure to show up in the mods list:
YourModName/ About/ About.xml
The folder must contain an About.xml file. Along with this vital information it's possible to add a preview image for your mod. This makes the structure as follows:
YourModName/ About/ About.xml Preview.png
The size of the base game Preview.png is 400x61 pixels, but some mods use higher preview images. The image is centered in the mod's description, and can be of any size.
After uploading your mod to Steam, another file named "PublishedFileId.txt" will appear in this folder. This file is an identifier that Steam uses to identify your mod. It is NOT the packageId of your mod.
The Defs folder
If your mod adds new content, chances are you're going to use XML files. These files are going to be stored in the folder structure as follows:
YourModName/ Defs/ BiomeDefs/ Biomes.xml BodyDefs/ Bodies.xml BodyPartDefs/ BodyParts.xml (..)
The contents of a Def folder don't follow a clear naming convention, but the folder names are generally the same in every mod.
Using a non-standard name is going to make it harder for others to navigate your mod's folders, so it is advised to keep the folder names consistent with the base game.
Typically, the files inside these folders are named after their contents:
Core/ Defs/ ThingDefs/ Apparel_Hats.xml Apparel_Shield.xml (..) Weapons_Melee.xml Weapons_RangedNeolithic.xml
This makes it easier for people to navigate XML code. If your mod is going to add both apparel and weapons, or even both hats and shoes, you're best off separating the XML code in their respective files.
Some mod authors choose to make a separate file for each of their items. This makes it easier for others to remove only part of your mod and keep the rest of it, but with very large mods it makes it harder to navigate the folder.
The Textures and Sounds folders
If you're using Defs chances are you're creating a content mod. This type of mod is most likely very dull without its own custom graphics and sounds. Adding such content requires the following folders:
YourModName/ Textures/ Sounds/
The contents of the Textures and Sounds folder usually aren't the same between mods. The base game sorts these files in various folders and subfolders, but in the end it's very hard to navigate them based on the folder names.
It's possible to categorize this content by item (submachinegun#1, pistol#3) or item type (guns, buildings), as an example. Whatever you do it's best to keep the structure consistent throughout both folders.
The Source and Assemblies folders
If you want to take a shot at C# modding, you want an empty Source and an empty Assemblies folder. You'll want to create the C# project inside your Source folder, and compile the class library into the Assemblies folder. These things are processed automatically by your IDE, so you don't have to make these folder structures yourself:
YourModName/ Assemblies/ ProjectName.dll Source/ SolutionName/ SolutionName.sln ProjectName/ ProjectName.csproj (..)
Or:
YourModName/ Assemblies/ ProjectName.dll Source/ ProjectName/ SolutionName.sln ProjectName.csproj (..)
Once again, the structure of these folders is decided almost entirely by the author's editing software. Therefore the only things you have to set up are the following folders:
YourModName/ Assemblies/ Source/
.. And then once you create a solution starting in ../YourModName/Source/ everything else will be sorted out by the software. People don't navigate these folders, they open ProjectName.sln to navigate it using their software of choice.
The Patches folder
If you wish to edit XML or Defs from another mod or from vanilla, the best way to do so is by using PatchOperations. PatchOperations allow you to edit precisely the data you want to edit, rather than replacing an entire Def.
YourModName/ Patches/
The Languages folder
Unless you're on a translation team or making a C# mod, you're unlikely to need these folders a lot.
YourModName/ Languages/ English/ Keyed/ Keys.xml/
Keys.xml (name is irrelevant) will contain keys you refer to in C#, and translate in XML. If you send a message and want to be able to translate that into other languages, you can use "MySentence".Translate() where you'd normally use a string, and keep the translation of <MySentence>This is my sentence.</MySentence> in the Keys.xml file. This allows you (and others) to translate your mod in their language.
If you want to translate Defs, refer to Ludeon instructions. Remember that Core is a mod as well. If you want to translate custom Defs, you'll need the following folder structure:
YourModName/ Languages/ Non-English/ DefInjected/ MyNameSpace.MyCustomDef/
If you want to randomly generate names using your own words, you will have to use this folder:
YourModName/ Languages/ English/ Strings/ NameBanks/
In this folder you put .txt files with a new word on every line. Using XML you will then be able to randomly pick one of the lines in the file.
Targetting specific game versions
Many top level mod folders (Assemblies, Defs, etc) can be placed under a parent matching a target game version. Such directories will be loaded by the game version matching the parent preventing the equivilent default directories from loading. Known exceptions:
About/
: must be in mod rootloadFolders.xml
: must be in mod rootLanguage/
: versions prior to 1.1 will only load mod root version
Example usage:
YourModName/ 1.0/ Patches/ # loads if version = 1.0 [...] 1.1/ Patches/ # loads if version = 1.1 [...] Patches/ # loads otherwise [...]
Folder loading can be customised using loadFolders.xml
file placed in mod root. Example:
<loadFolders> <v1.1> <li>/</li> <li>1.1</li> </v1.1> <v1.2> <li>/</li> <li>1.2</li> <li IfModActive="Royalty">RoyaltyDefs</li> </v1.2> </loadFolders>
loadFolders.xml
allowed a <default>
option which has since been removed.
Complete mod folder structure
*/ About/ About.xml Preview.png- Assemblies/- *.dll+ Defs/- *Defs/+ *.xml+ Languages/- */* DefInjected/- *Defs/+ *.xml+ Keyed/- *.xml+ Strings/- NameBanks/ *.txt+ FriendlyName.txt- LangIcon.png LanguageInfo.xml Patches/- *.xml+ Sounds/- */*# *.wav+ Source/- */*# bin/ Debug/ *.** obj/ Debug/ *.** Properties/- AssemblyInfo.cs Source-DLLs/- Assembly-CSharp.dll UnityEngine.dll *.csproj *.OpenCover.Settings *.sln */*# *.cs+ Textures/- */*# *.psd* *.psd.meta* *.png*
Anything with a / at the end is a folder; Anything with a . in it is a file; The * in *.* and */ stands for any arbitrary string; The * after a file/folder stands for an occurence of >= 0; The + after a file/folder stands for an occurrence of > 0; The - after a file/folder stands for an occurrence of <= 1; The # after a folder stands for a folder depth of >= 0.