Ludeon Forums

RimWorld => Mods => Help => Topic started by: jecrell on June 03, 2017, 05:00:43 AM

Title: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:00:43 AM
How to Make a RimWorld Mod
STEP BY STEP
by Jecrell

#XML #C# #Beginner #Intermediate #Advanced
#Hediff #Weapon #Ranged_Weapon #Projectile #ThingDef

"Modding RW for dummies." -KapTaiN_KaVerN

Table of Contents
I. Introduction (https://ludeon.com/forums/index.php?topic=33219.msg338627#msg338627)
II. Required items (https://ludeon.com/forums/index.php?topic=33219.msg338628#msg338628)
III. XML Stage (https://ludeon.com/forums/index.php?topic=33219.msg338629#msg338629)
IV. Connecting XML and C# (https://ludeon.com/forums/index.php?topic=33219.msg338630#msg338630)
V. C# Assembly Setup (https://ludeon.com/forums/index.php?topic=33219.msg338631#msg338631)
VI. C# Coding (https://ludeon.com/forums/index.php?topic=33219.msg338632#msg338632)
VII. Localization (https://ludeon.com/forums/index.php?topic=33219.msg338633#msg338633)

Questions? Comments?
Let's mod RimWorld together.
Visit the Unofficial RimWorld Discord.
https://discord.gg/rimworld
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:01:14 AM
Introduction


In this tutorial we're going to create a weapon that covers many different aspects of RimWorld's systems. This provides us with a clearer understanding of how RimWorld works for modding.

By following this tutorial, you will be able to do your own complex RimWorld modding in XML and C# in the same way that I can. I will give you all my tools and know-how.

This weapon will be known as The Plague Gun. When fired, if it hits its target, it will have a chance to make the target catch the plague.

To make this mod happen, we will need to create the ThingDefs in XML for the bullet and gun, and create a C# assembly that uses the Projectile class to define a new Impact event for our plague projectile.

This tutorial cannot fully teach XML and C#, and it can help you familiarize yourself a bit with them, but there are lots of free resources online to learn them.
XML -> https://www.w3schools.com/xml/
C# -> http://www.learncs.org/
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:01:31 AM
Required Items


Notepad++ (https://notepad-plus-plus.org/) or
Atom (https://atom.io/) or
Sublimetext (https://www.sublimetext.com/)
|Use any text editor that allows you to edit XML files and use "Find in Files" for referencing.
Visual Studio Community (https://www.visualstudio.com/vs/community/)|Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.
dnSpy (https://github.com/0xd4d/dnSpy/releases)|This is for referencing the game's decompiled C# scripts.

Optional Goodies


Rimworld Mod Development Cookiecutter
This is a tool for developers to begin mods more quickly, eliminating the overhead of setting up a new project.
https://ludeon.com/forums/index.php?topic=39038.0
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:01:47 AM
XML Stage


1) Create a mod folder.
RimWorld>Mods>PlagueGun
- Go to your RimWorld's base folder. For myself, that is D:\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C:\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.
- Go into the Mods folder.
- Make a new folder with our mod's title: PlagueGun

2) Inside PlagueGun, make an About folder.
RimWorld>Mods>PlagueGun>About

3) Inside the About folder, make a new text file and rename it About.xml.
RimWorld>Mods>PlagueGun>About>About.xml
- You will need a good text editor to make a proper XML file -- Notepad++ or Atom. I always make a .TXT file first and change it to .XML. If you can't rename your file's type, make sure you have filetypes visible in your view settings.
- About.xml is the file that shows your mod in the mod list inside the RimWorld game. It is also used when creating a Workshop upload for Steam.
- At the top of an XML file, always include this for RimWorld.

Code: [Select]
<?xml version="1.0" encoding="utf-8"?>

- Then add the MetaData tags for the Workshop and in-game Mod list.

Code: [Select]
<ModMetaData>
<name>Test Mod - Plague Gun</name>
<author>YourName</author>
<targetVersion>0.17.0</targetVersion>
<description>V1.0
    This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.
</description>
</ModMetaData>

- Save the file.

4) Add a Preview.png or Preview.jpeg to your About folder.
RimWorld>Mods>PlagueGun>About>Preview.png
- This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.
- I prefer the dimensions of 480x300 pixels, but the Steam Workshop will be able to work with almost any resolution you specify.
- Example:
(https://images.discordapp.net/.eJwVxMsNgzAMANBdMkBs8oOyTRSigAp2FBtxqLp71Xd4H3OP06xmV-2yAmyHFB6bFeWRW7WNuZ0190Ns4Quyai77VUkFPAZMc5pjTNPkHQYH_xeMLrglofcvh3DTm_gh26mZ7w8DpyK_.m80Tb_ZrkoUbDY479tebuwl38Ng)

5) Make a Defs folder in your Mod's directory.
RimWorld>Mods>PlagueGun>Defs
- RimWorld will read your XML files in any directory. You can name your directories however you like under the /Defs/ subfolder. Defs/StrangeNewAlienGuns/MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.


What are Defs?
RimWorld uses something called Defs like blueprints for in-game objects. Instead of using hidden C# code, RimWorld will look up an XML Def and copy it to the game world. This makes things easier for us, the modders. Everything from characters, animals, floors, damages, buildings, and even diseases in RimWorld use Defs. We're going to make Defs for our Plague Gun and Plague Bullet.




6) Make a new ThingDefs folder in your Defs folder.
RimWorld>Mods>PlagueGun>Defs>ThingDefs

7) Make a new text file in your ThingDefs folder, and change it to RangedWeapon_PlagueGun.xml.
RimWorld>Mods>PlagueGun>Defs>ThingDefs>RangedWeapon_PlagueGun.xml
- This file will contain the blueprints (ThingDefs or Thing Definitions) for our new gun and bullets.
- Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.
- In RimWorld, it is often best to use the XML attribute ParentName="BaseBullet" when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps.

Code: [Select]
DO NOT USE THIS -- This is an incomplete preview.

<?xml version="1.0" encoding="utf-8"?>
<Defs>

<ThingDef ParentName="BaseBullet">
  <defName>TST_PlagueGun_Bullet</defName>
  <label>plague bullet</label>
  ...
</ThingDef>

<ThingDef ParentName="BaseHumanMakeableGun">
  <defName>TST_PlagueGun_Weapon</defName>
  <label>plague gun</label>
  ...
</ThingDef>

</Defs>

9a) First add our favorite line to the top.
Code: [Select]
<?xml version="1.0" encoding="utf-8"?>
Again, this line of code shows RimWorld that this is an XML file to extract data from.

9b) Add <Defs> opening and closing tags to the XML to hold our new code.

Code: [Select]
<?xml version="1.0" encoding="utf-8"?>
<Defs>


</Defs>

9c) Use your text editor. Use its "Find in Files" function to reference and copy Bullet_Revolver to your XML file.
For me, Find in Files is a function I use repeatedly. In Notepad++, if you press CTRL+SHIFT+F, you can go to the Find in Files screen. From there, you can enter a phrase to search for, and then you can enter the file path to search through. This makes it wildly easier to search for examples in RimWorld's Core. RimWorld holds copies of all of its weapons, items, buildings, etc. inside the Mods/Core directory.
- So, start by using Find in Files... and find this: defName>Bullet_Revolver
- When you find Bullet_Revolver, copy from its beginning <ThingDef> all the way until its closing </ThingDef> tag into your XML File.

10) Use your text editor. Use its "Find in Files" function to reference and copy Gun_Revolver to your XML file.
- Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.
- Repeat copying ThingDef code to your new XML file.

11) Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.
- TIP Use prefixes to avoid conflicting with other mods. RimWorld doesn't distinguish between two mods that both use <defName>Tobacco</defName>, for instance. If two modders use different prefixes, however, e.g. <defName>VegetableGarden_Tobacco</defName> and <defName>ROM_Tobacco</defName>, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix.
- Change the <defaultProjectile> tag inside the PlagueGun's Verbs to use the defName of your bullet (TST_Bullet_PlagueGun). Failing to do this will result in a no errors, but your gun will shoot regular bullets and not give the plague effect.

Once again, under the verbs. Please make sure <defaultProjectile> references the bullet.
e.g.
<defaultProjectile>TST_Bullet_PlagueGun</defaultProjectile>
[/b]
Example completed XML file:
Code: [Select]
<?xml version="1.0" encoding="utf-8"?>

<Defs>

  <ThingDef ParentName="BaseBullet">
    <defName>TST_Bullet_PlagueGun</defName>
    <label>plague bullet</label>
    <graphicData>
      <texPath>Things/Projectile/Bullet_Small</texPath>
      <graphicClass>Graphic_Single</graphicClass>
    </graphicData>
    <projectile>
      <flyOverhead>false</flyOverhead>
      <damageDef>Bullet</damageDef>
      <damageAmountBase>9</damageAmountBase>
      <speed>55</speed>
    </projectile>
  </ThingDef>

  <ThingDef ParentName="BaseHumanMakeableGun">
    <defName>TST_Gun_PlagueGun</defName>
    <label>plague gun</label>
    <description>A curious weapon notable for its horrible health effects.</description>
    <graphicData>
      <texPath>Things/Item/Equipment/WeaponRanged/Revolver</texPath>
      <graphicClass>Graphic_Single</graphicClass>
    </graphicData>
    <soundInteract>InteractRevolver</soundInteract>
    <statBases>
      <WorkToMake>15000</WorkToMake>
      <Mass>1.4</Mass>
      <AccuracyTouch>0.91</AccuracyTouch>
      <AccuracyShort>0.71</AccuracyShort>
      <AccuracyMedium>0.50</AccuracyMedium>
      <AccuracyLong>0.32</AccuracyLong>
      <RangedWeapon_Cooldown>1.26</RangedWeapon_Cooldown>
      <Weapon_Bulk>0.5</Weapon_Bulk>
    </statBases>
    <weaponTags>
      <li>SimpleGun</li>
    </weaponTags>
    <costList>
      <Steel>30</Steel>
      <Component>2</Component>
    </costList>
    <verbs>
      <li>
        <verbClass>Verb_Shoot</verbClass>
        <hasStandardCommand>true</hasStandardCommand>
        <defaultProjectile>TST_Bullet_PlagueGun</defaultProjectile>
        <warmupTime>0.3</warmupTime>
        <range>26</range>
        <soundCast>ShotRevolver</soundCast>
        <soundCastTail>GunTail_Light</soundCastTail>
        <muzzleFlashScale>9</muzzleFlashScale>
      </li>
    </verbs>
    <tools>
      <li>
        <label>grip</label>
        <capacities>
          <li>Blunt</li>
        </capacities>
        <power>8</power>
        <cooldownTime>1.6</cooldownTime>
      </li>
      <li>
        <label>barrel</label>
        <capacities>
          <li>Blunt</li>
          <li>Poke</li>
        </capacities>
        <power>8</power>
        <cooldownTime>1.6</cooldownTime>
      </li>
    </tools>
  </ThingDef>

</Defs>
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:02:15 AM
Connecting XML and C#

For the next part of the tutorial, we are going to use C# code to create a custom ThingDef blueprint type, and we're going to create a custom class for our Thing to use in-game when it spawns. Before we can get to C# however, we need to "bridge" XML and C# by pointing the XML to use our C# code. First, decide your mod's namespace. This prevents RimWorld from being confused by other mods. This is the name RimWorld knows to use for your C# code. For the purposes of this tutorial, we're going to use Plague.

The following XML will not work in-game until we've written the C# code and created an assembly (.dll file) for our mod.

12) Change the line for the ThingDef to reference a custom ThingDef class.
<ThingDef Class="Plague.ThingDef_PlagueBullet" ParentName="BaseBullet">
  <defName>TST_Bullet_PlagueGun</defName>

13) Add three more lines to the thing def before the closing tag (</ThingDef>).
Code: [Select]
<AddHediffChance>0.05</AddHediffChance>
<HediffToAdd>Plague</HediffToAdd>
<thingClass>Plague.Projectile_PlagueBullet</thingClass>
- AddHediffChance and HediffToAdd will give us a percentage of success to add a Hediff of our choice in XML (in this case we're using Plague). We will code how these parameters are used in the C# Coding section.

------See Attached File for Complete XML (A17)--------

[attachment deleted by admin due to age]
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:02:36 AM
Setting up the C# Assembly


15) Open your compiler of choice for C#.
-I use Visual Studio Community edition, a free Windows-based compiler for C# code.
-This part of the tutorial will assume you will use the same.

16) Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld>Mods>PlagueGun>Source

17) Go into the project properties.

18) In the Application tab, Make sure the assembly names and namespace match your XML assembly name.
-Earlier we used Plague.ThingDef_PlagueBullet. Plague should be our assembly namespace and assembly name.

19) In that same window, change the Target Framework version to .NET Framework 3.5
-Forgetting to do this will cause lots of errors.
-Select Yes when it asks you if you're sure to change the framework.

20) Go to the Build tab in the project properties.

21) Change the output path to be RimWorld\Mods\PlagueGun\Assemblies
- All .dll files will go into this directory when we "build" our code library.

22) In that same window, click the Advanced... button.

23) Change Debugging information to none.
- This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.

24) In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and version number as you like.
- This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.

25) In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.

26) Click Browse and go to RimWorld\RimWorldWin_Data\Managed

27) Add references to Assembly-CSharp.dll and UnityEngine.dll

28) In the Solution Explorer (typically on the right side of the application), look at the references drop down list.

29) Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.

30) Do this (Copy Local to FALSE) for UnityEngine as well.
- By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!

31) Go into the References; Delete the yellow triangle references, and click the Build button and Build Solution.
- If there are errors, be sure to delete unused References and delete lines for #using that aren't in use like #using System.Threading.Tasks

Now the workspace setup is complete and we can add C# code to RimWorld.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:02:50 AM
C# Coding


Let's make our XML blueprint (ThingDef) for our new projectile type.

31) Open your Class1.cs.
32) Right click and rename the .cs file to your liking.
33) Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).
Code: [Select]
using RimWorld;
using Verse;
- These are the shared libraries that hold RimWorld code references. Without these, our code will not be able to connect with RimWorld.
34) Rename the namespace to the namespace you used earlier in the options menu and in your XML (Plague).
35) Change public class Class1 to your new ThingDef class you wrote earlier and make it inherit the ThingDef from RimWorld. Then add in our custom ThingDef variable from earlier as a float.
- Floats are very large numbers in C#. RimWorld will use them to keep track of of percentages. 1.0f is 100% and 0.05% is 5%).
e.g.
Code: [Select]
namespace Plague
{
  public class ThingDef_PlagueBullet : ThingDef
  {
       public float AddHediffChance = 0.05f; //The default chance of adding a hediff.
       public HediffDef HediffToAdd = HediffDefOf.Plague;
  }
}
**TIP** Use ThingDefs to store useful variables for your classes. DamageDefs and other variables can be kept here and changed easily in XML.

Let's make the actual projectile. For this tutorial, we're going to make a new projectile that checks for impact and adds a Hediff (health differential - poison, toxins, implants, anything).
36) Add a new class  (Project->Add Class)
37) Rename the namespace (Plague) and give the class a title that matches your XML (Projectile_PlagueBullet).
38) Make your new class inherit the Bullet class (a child of the Projectile class), so the game will treat your new projectile like a bullet and not throw (fun) errors.
39) Write a 'property' method that finds and returns your ThingDef blueprint to easily grab its XML variables.
(e.g.)
Code: [Select]
namespace Plague
{
    public class Projectile_PlagueBullet: Bullet
    {
        #region Properties
        //
        public ThingDef_PlagueBullet Def
        {
            get
            {
                return this.def as ThingDef_PlagueBullet;
            }
        }
        #endregion Properties
    }
}

40) Open Zhentar's ILSpy Mono.
- Next we want to reference the original Projectile code, so we can write a new impact event.
- Often times, RimWorld code will be private or hidden, and we can't override the code with our own. However, in this case, we can override the Projectile's "Impact" method. Even so, let's take a look at the source code to understand what we're doing better.

41) Use File->Open (or click and drag) RimWorld's Assembly-CSharp into Zhentar's ILSpy Mono.
- Assembly-CSharp is where all the code for RimWorld is located. By loading it into Zhentar's ILSpy, we can take a closer look at code used in the game. This is INCREDIBLY HELPFUL to understand the inner workings of the game.
42) Search (CTRL+F) for the Projectile class.
43) Instead of Projectile, take a look at Projectile_DoomsdayRocket.
- Notice that it is overriding the Impact method safely by using protected override void Impact.
- Let's try using this code in our own project.
44) In our Projectile_PlagueBullet class, write out protected override void Impact and autocomplete using intellisense.
-Intellisense is the best thing about Visual Studio Community. The more you program with RimWorld mods the more familiar with it you'll be. It autocompletes and fixes up simple errors.
45) Add this code under Properties.
Code: [Select]

        #region Overrides
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);

            /*
             * Null checking is very important in RimWorld.
             * 99% of errors reported are from NullReferenceExceptions (NREs).
             * Make sure your code checks if things actually exist, before they
             * try to use the code that belongs to said things.
             */
            if (Def != null && hitThing != null && hitThing is Pawn hitPawn) //Fancy way to declare a variable inside an if statement. - Thanks Erdelf.
            {
                var rand = Rand.Value; // This is a random percentage between 0% and 100%
                if (rand <= Def.AddHediffChance) // If the percentage falls under the chance, success!
                {
                        /*
                         * Messages.Message flashes a message on the top of the screen.
                         * You may be familiar with this one when a colonist dies, because
                         * it makes a negative sound and mentioneds "So and so has died of _____".
                         *
                         * Here, we're using the "Translate" function. More on that later in
                         * the localization section.
                         */
                        Messages.Message("TST_PlagueBullet_SuccessMessage".Translate(new object[] {
                        this.launcher.Label, hitPawn.Label
                    }), MessageSound.Standard);

                    //This checks to see if the character has a heal differential, or hediff on them already.
                    var plagueOnPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);
                    var randomSeverity = Rand.Range(0.15f, 0.30f);
                    if (plagueOnPawn != null)
                    {
                        //If they already have plague, add a random range to its severity.
                        //If severity reaches 1.0f, or 100%, plague kills the target.
                        plagueOnPawn.Severity += randomSeverity;
                    }
                    else
                    {
                        //These three lines create a new health differential or Hediff,
                        //put them on the character, and increase its severity by a random amount.
                        Hediff hediff = HediffMaker.MakeHediff(Def.HediffToAdd, hitPawn, null);
                        hediff.Severity = randomSeverity;
                        hitPawn.health.AddHediff(hediff, null, null);
                    }
                }
                else //failure!
                {
                    /*
                     * Motes handle all the smaller visual effects in RimWorld.
                     * Dust plumes, symbol bubbles, and text messages floating next to characters.
                     * This mote makes a small text message next to the character.
                     */
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "TST_PlagueBullet_FailureMote".Translate(Def.AddHediffChance), 12f);
                }
            }
        }
        #endregion Overrides
46) Build your project again to save the new changes.
47) Go in-game to check to see if RimWorld found any errors and to check your own code's results.
48) In the options menu, make sure Development mode is enabled.
- This will give us an easy way to add our Weapon to the in-game map.
49) Start a map. Click the tool icons above. Explore them a bit. Pretty cool eh? When ready, find the Spawn Weapon command.
- IF for some reason you do not see your Plague Gun or new item available in the lists, press the ~ key on your keyboard. Check your error logs for anything mentioning the Plague Gun.
- These kinds of errors are very common.
50) In Spawn Weapon, click the Plague Gun and drop it in the map. Have a character equip it and start shooting.
51) There is at least one thing left to do (as you may have seen) translation!

--- Attached Below -- Complete .CS Files For Reference ---

[attachment deleted by admin due to age]
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 05:03:11 AM
Translations


Now it's time to turn our project's C# strings into text that everyone can translate if they switch to other languages.

Remember these lines in our C# project?

Code: [Select]
                        Messages.Message("TST_PlagueBullet_SuccessMessage".Translate(new object[] {
                        this.launcher.Label, hitPawn.Label
                    }), MessageSound.Standard);

and...

Code: [Select]
MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "TST_PlagueBullet_FailureMote".Translate(Def.AddHediffChance), 12f);
Both of these sections use the .Translate string sub-function.
Each .Translate can take a single argument (.Translate(stringGoesHere)) or multiple arguments (.Translate(new object[] {stringOne, stringTwo})).
In XML, these arguments are then referenced as {0} if singular, or {0} and {1} etc for multiple arguments. I'll show you what I mean below.

.Make a Languages folder.
RimWorld>Mods>PlagueGun>Languages

.Make an English folder.
RimWorld>Mods>PlagueGun>Languages>English

.Make a Keyed folder
RimWorld>Mods>PlagueGun>Languages>English>Keyed
-Keyed means that our C# code references a "Key" in our mod's language dictionary.

.Make a text file and change it to an XML file named PlagueGun_Keys.xml

.Fill out the PlagueGun_Keys.xml with our string keys.
-First, add in this familiar line.
Code: [Select]
<?xml version="1.0" encoding="utf-8" ?>-Add in the tag for LanguageData
Code: [Select]
<LanguageData>
</LanguageData>
-In between LanguageData, add in the keys we used earlier, and define them.
-Earlier, we used the string keys TST_PlagueBullet_FailureMote and TST_PlagueBullet_SuccessMessage.
-Filling in the file should look something like this.
Code: [Select]
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
  <TST_PlagueBullet_FailureMote></TST_PlagueBullet_FailureMote>
  <TST_PlagueBullet_SuccessMessage></TST_PlagueBullet_SuccessMessage>
</LanguageData>
-Let's use our argument notes from earlier. We passed one argument to the failure mote. So we should use {0}, to represent the hit chance. We passed two arguments to the success message, so we should use {0}, to represent the launcher, and {1}, to represent the hit character.
-Fill out the text for the messages.
Code: [Select]
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
  <TST_PlagueBullet_FailureMote>Failure: {0} chance</TST_PlagueBullet_FailureMote>
  <TST_PlagueBullet_SuccessMessage>{0} infected {1} with the plague!</TST_PlagueBullet_SuccessMessage>
</LanguageData>

.Save the file.

.Translation complete.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 09:13:22 AM
Reserved
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 09:13:58 AM
Reserved
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 09:14:20 AM
Reserved
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 09:15:07 AM
Reserved
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 09:15:44 AM
Reserved
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: kaptain_kavern on June 03, 2017, 02:06:36 PM
(https://cdn.meme.am/cache/instances/folder298/250x250/49281298/chuck-norris-approves-im-chuck-norris-and-i-approve.jpg)



Thank you a-frackin'-ton for making this
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: milon on June 03, 2017, 02:17:29 PM
Thanks jecrell!  I'm stickying this.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: WalkingProblem on June 03, 2017, 02:27:04 PM
Camping
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Tynan on June 03, 2017, 11:17:03 PM
This is really great! But it might be even more useful on the wiki. The wiki is designed as a long-term info repository, while forums are for temporary discussion. If you put it on the wiki, others can also participate it and improve it, or add other tutorials alongside, and so on. Consider wiki-ing it!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 03, 2017, 11:42:51 PM
This is really great! But it might be even more useful on the wiki. The wiki is designed as a long-term info repository, while forums are for temporary discussion. If you put it on the wiki, others can also participate it and improve it, or add other tutorials alongside, and so on. Consider wiki-ing it!

*glows*

My good man. I'm working right now to convert this beast into Markdown and then I'll put it up on the wiki.

*gets back to work*
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: kaptain_kavern on June 04, 2017, 12:54:21 AM
Markdown is more universal even, you know for like ... posterity.

After all of this, When you'll have a bit of free time Jecrell, reminds me to show you the beauty of static site generators like Jekyll (https://jekyllrb.com/). This baby is eating Markdown (or even plaintext) files and outputs you a valid website directly from a github repo for free hosting even ;D

I could also set this up for you. If it can be of any interest for you.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: DrGenghis on June 04, 2017, 01:06:08 AM
Having some trouble with this, can't seem to figure out what the problem is and I've gone through the tutorial several times just in case I missed something.

Keep getting these errors.
Code: [Select]
Error CS1061 'ThingDef' does not contain a definition for 'AddHediffChance' and no extension method 'AddHediffChance' accepting a first argument of type 'ThingDef' could be found (are you missing a using directive or an assembly reference?) PlagueGun D:\SteamLibrary\SteamApps\common\RimWorld\Mods\PlagueGun\Source\PlagueGun\PlagueGun\Projectile_PlagueBullet.cs 36 Active
Error CS1061 'ThingDef' does not contain a definition for 'HediffToAdd' and no extension method 'HediffToAdd' accepting a first argument of type 'ThingDef' could be found (are you missing a using directive or an assembly reference?) PlagueGun D:\SteamLibrary\SteamApps\common\RimWorld\Mods\PlagueGun\Source\PlagueGun\PlagueGun\Projectile_PlagueBullet.cs 51 Active
Error CS1061 'ThingDef' does not contain a definition for 'HediffToAdd' and no extension method 'HediffToAdd' accepting a first argument of type 'ThingDef' could be found (are you missing a using directive or an assembly reference?) PlagueGun D:\SteamLibrary\SteamApps\common\RimWorld\Mods\PlagueGun\Source\PlagueGun\PlagueGun\Projectile_PlagueBullet.cs 63 Active
Error CS1061 'ThingDef' does not contain a definition for 'AddHediffChance' and no extension method 'AddHediffChance' accepting a first argument of type 'ThingDef' could be found (are you missing a using directive or an assembly reference?) PlagueGun D:\SteamLibrary\SteamApps\common\RimWorld\Mods\PlagueGun\Source\PlagueGun\PlagueGun\Projectile_PlagueBullet.cs 75 Active

Any help would be much appreciated. Just in case here is a gist with both .cs files and the xml. https://gist.github.com/anonymous/47f35abe717ce37aed28ae952983b3c1 (https://gist.github.com/anonymous/47f35abe717ce37aed28ae952983b3c1)
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: UncleIROH on June 04, 2017, 01:08:07 AM
I'm attempting to go through this but the C# file refuses to compile.
The line Visual Studio has issues with is:
Code: [Select]
if (Def != null && hitThing != null && hitThing is Pawn hitPawn) //Fancy way to declare a variable inside an if statement. - Thanks Erdelf.
I've changed it to this to get it to compile:
Code: [Select]
Pawn hitPawn = hitThing as Pawn;
if (this.Def != null && hitPawn != null)

With this change I am able to load up the gun in game equip and fire it. But notarget ever gets the plague. I've even edited the XML and C# AddHediffChance to 0.98f;
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: UncleIROH on June 04, 2017, 01:13:26 AM
@DrGenghis

I was having the same issue. The forum post looks like it might have a mistake in it because it doesn't match the example C# file.

The post has this line:
Code: [Select]
public ThingDef Def
{
     get { return this.def as ThingDef_PlagueBullet; }
}

But it should be:
Code: [Select]
public ThingDef_PlagueBullet Def
{
       get { return this.def as ThingDef_PlagueBullet; }
}

Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: DrGenghis on June 04, 2017, 01:28:27 AM
@UncleIROH

You rule! Thank you for fixing my problem! Not having any issues with compiling now.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Spdskatr on June 04, 2017, 03:32:01 AM
This needs to go on the wiki...
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 04, 2017, 04:19:04 AM
@DrGenghis

I was having the same issue. The forum post looks like it might have a mistake in it because it doesn't match the example C# file.

The post has this line:
Code: [Select]
public ThingDef Def
{
     get { return this.def as ThingDef_PlagueBullet; }
}

But it should be:
Code: [Select]
public ThingDef_PlagueBullet Def
{
       get { return this.def as ThingDef_PlagueBullet; }
}

Bless you fellow RimWorlder and my apologies! I'm not sure how that slipped through.
I fixed it in the post.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: mrofa on June 04, 2017, 04:38:37 AM
Some errors are becouse of the unneded dlls in your mods assembly, this is in regard to point 21 of the guide.
Here is my suggestion:
Leave output path as it was ( default "bin\Debug\") and instead use Build Events
In build events use Post-build with xcopy, post build will run its macro after you compile a build(press F7 on default settings)
Code: [Select]
xcopy "YourDllFile" "OutputDirectory" /i /y-YourDllFile is a path and file name
-OutputDirectory full path where the file should end up
-/i if OutputDirectory dont exist it will be created
-/y dont show file override propmpt and auto accept it

Here is how my looks:
Code: [Select]
xcopy "C:\Users\Mrowa\Documents\Visual Studio 2013\Projects\ClutterFurniture\ClutterFurniture\bin\Debug\ClutterFurniture.dll"
"C:\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\Clutter Furniture\Assemblies" /i /y
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: UncleIROH on June 04, 2017, 11:14:16 AM
Anyone get this gun to actually give someone the plague? I've killed bunches of pawns with it, no plague.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on June 04, 2017, 12:42:31 PM
Anyone get this gun to actually give someone the plague? I've killed bunches of pawns with it, no plague.

You probably forgot to set your ProjectileDef inside the PlagueGun def to your new Bullet def.

Hope that helps you find what you're looking for.

Otherwise, set the hediffChance to 1.0 in XML for 100% chance of giving the plague.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: steeveebr on June 04, 2017, 12:58:03 PM
Jecrell,

This is great ty! 

Out of curiosity:  Step 11 states to copy all of the ThingDef Parents and Bases to your XML...

Quote
11) Repeat and copy all of the ThingDef Parents and Bases for Bullet_Pistol and Pistol to your XML file.

And then your code snippet also includes BaseHumanGun.  Is that inclusion necessary?  I don't see it as a parent in either the Pistol Bullet or the Pistol Gun.  If it is necessary how would I determine that while working on another say another "Thing"?

Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: UncleIROH on June 04, 2017, 02:28:21 PM
@Jecrell Thanks that was it!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Toby Larone on June 06, 2017, 02:57:23 PM
Great guide, found it super helpful thank you, managed to get it working after a long while. In the example "RangedWeapon_PlagueGun.xml" for download:

Code: [Select]
<AddHediffChance>0.05<AddHediffChance>
missing the / at the end if anyone has a problem with the example check that you've added that.

P.S. is it normal to get a message in the top left corner of the game telling you whether the shot infected the target or not? I am getting them even with dev mode turned off.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Ghasty on June 07, 2017, 12:13:12 PM
P.S. is it normal to get a message in the top left corner of the game telling you whether the shot infected the target or not? I am getting them even with dev mode turned off.

Yeah I got the same message pop-up. I think it was to show off the translation feature.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: arenoobies on June 09, 2017, 12:34:47 AM
Thank you for this! I've been looking for a step by step in modding and I've been rummaging through the defs in RimWorld folder trying to learn how to mod or atleast modified something on my own, with this guide it helps me even better! Please do continue and perhaps in the future add a bit more complicated one like one of your mods, factions! Really appreciated! <3

Edit: I can't find the gun in dev mode spawn weapon, it says these:

Quote
RimWorld 0.17.1557 rev1153
Verse.Log:Message(String)
RimWorld.VersionControl:LogVersionNumber()
Verse.Root:CheckGlobalInit()
Verse.Root:Start()
Verse.Root_Entry:Start()

Exception reading RangedWeapon_PlagueGun.xml as XML: System.Xml.XmlException: 'AddHediffChance' is expected  Line 21, position 6.
  at Mono.Xml2.XmlTextReader.Expect (System.String expected) [0x00000] in <filename unknown>:0
  at Mono.Xml2.XmlTextReader.ReadEndTag () [0x00000] in <filename unknown>:0
  at Mono.Xml2.XmlTextReader.ReadContent () [0x00000] in <filename unknown>:0
  at Mono.Xml2.XmlTextReader.ReadContent () [0x00000] in <filename unknown>:0
  at Mono.Xml2.XmlTextReader.Read () [0x00000] in <filename unknown>:0
  at System.Xml.XmlTextReader.Read () [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.ReadNode (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.Load (System.Xml.XmlReader xmlReader) [0x00000] in <filename unknown>:0
  at System.Xml.XmlDocument.LoadXml (System.String xml) [0x00000] in <filename unknown>:0
  at Verse.LoadableXmlAsset..ctor (System.String name, System.String fullFolderPath, System.String contents) [0x00000] in <filename unknown>:0
Verse.Log:Warning(String)
Verse.LoadableXmlAsset:.ctor(String, String, String)
Verse.<XmlAssetsInModFolder>c__Iterator224:MoveNext()
System.Collections.Generic.List`1:AddEnumerable(IEnumerable`1)
System.Collections.Generic.List`1:.ctor(IEnumerable`1)
System.Linq.Enumerable:ToList(IEnumerable`1)
Verse.ModContentPack:LoadDefs(IEnumerable`1)
Verse.LoadedModManager:LoadAllActiveMods()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__84E()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__84C()

Loaded file (Scenario) is from version 0.17.1546 rev887, we are running version 0.17.1557 rev1153.
Verse.Log:Warning(String)
Verse.ScribeMetaHeaderUtility:LoadGameDataHeader(ScribeHeaderMode, Boolean)
Verse.GameDataSaveLoader:TryLoadScenario(String, ScenarioCategory, Scenario&)
RimWorld.ScenarioFiles:RecacheData()
RimWorld.ScenarioLister:RecacheData()
RimWorld.ScenarioLister:RecacheIfDirty()
RimWorld.<ScenariosInCategory>c__Iterator128:MoveNext()
System.Linq.Enumerable:FirstOrDefault(IEnumerable`1)
RimWorld.Page_SelectScenario:EnsureValidSelection()
RimWorld.Page_SelectScenario:PreOpen()
Verse.WindowStack:Add(Window)
RimWorld.MainMenuDrawer:<DoMainMenuControls>m__5FF()
Verse.ListableOption:DrawOption(Vector2, Single)
Verse.OptionListingUtility:DrawOptionListing(Rect, List`1)
RimWorld.MainMenuDrawer:DoMainMenuControls(Rect, Boolean)
RimWorld.MainMenuDrawer:MainMenuOnGUI()
Verse.UIRoot_Entry:DoMainMenu()
Verse.UIRoot_Entry:UIRootOnGUI()
Verse.Root:OnGUI()

Initializing new game with mods Core and PlagueGun
Verse.Log:Message(String)
Verse.Game:InitNewGame()
Verse.Root_Play:<Start>m__850()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__84C()
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Kappten on June 14, 2017, 12:13:53 PM
When I use ILSpy to decompile Assembly-CSharp I only get:
Code: [Select]
// C:\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin_Data\Managed\Assembly-CSharp.dll
// Assembly-CSharp, Version=0.17.6362.34601, Culture=neutral, PublicKeyToken=null

// Global type: <Module>
// Architecture: AnyCPU (64-bit preferred)
// Runtime: .NET 2.0

using System;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyVersion("0.17.6362.34601")]
[assembly: AssemblyCompany("Ludeon Studios")]
[assembly: AssemblyCopyright("Copyright Ludeon Studios.")]
[assembly: AssemblyTrademark("RimWorld is a registered trademark of Ludeon Studios.")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]

Even when I press CTRL + F and search for "Projectile_" I get no results. I used the Link in the Post to download ILSpy. What am I doing wrong?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: mrofa on June 14, 2017, 07:40:57 PM
Thank you for this! I've been looking for a step by step in modding and I've been rummaging through the defs in RimWorld folder trying to learn how to mod or atleast modified something on my own, with this guide it helps me even better! Please do continue and perhaps in the future add a bit more complicated one like one of your mods, factions! Really appreciated! <3

Edit: I can't find the gun in dev mode spawn weapon, it says these:


This error regards XML, something is wrong in your xml file, prapobly missing "[/" somewhere

When I use ILSpy to decompile Assembly-CSharp I only get:
Code: [Select]
// C:\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin_Data\Managed\Assembly-CSharp.dll
// Assembly-CSharp, Version=0.17.6362.34601, Culture=neutral, PublicKeyToken=null

// Global type: <Module>
// Architecture: AnyCPU (64-bit preferred)
// Runtime: .NET 2.0

using System;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyVersion("0.17.6362.34601")]
[assembly: AssemblyCompany("Ludeon Studios")]
[assembly: AssemblyCopyright("Copyright Ludeon Studios.")]
[assembly: AssemblyTrademark("RimWorld is a registered trademark of Ludeon Studios.")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]

Even when I press CTRL + F and search for "Projectile_" I get no results. I used the Link in the Post to download ILSpy. What am I doing wrong?

Try this
(https://s30.postimg.org/7ygpbwe4h/fhfshfhh.png)



Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Kappten on June 15, 2017, 06:22:12 AM
Thanks found it.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Kappten on June 15, 2017, 07:55:41 AM
When I start the game no errors occur and when I go into "Spawn Weapon..." I can't find PlagueGun when I then go to "Spawn item collection..." and Spawn Weapons I get at some point an error:

Code: [Select]
Exception drawing PG_Gun_Plague60985: System.NullReferenceException: Object reference not set to an instance of an object
  at Verse.Projectile.get_StartingTicksToImpact () [0x00000] in <filename unknown>:0
  at Verse.Projectile.get_ExactPosition () [0x00000] in <filename unknown>:0
  at Verse.Projectile.get_DrawPos () [0x00000] in <filename unknown>:0
  at Verse.Projectile.Draw () [0x00000] in <filename unknown>:0
  at Verse.DynamicDrawManager.DrawDynamicThings (Verse.DrawTargetDef drawTarget) [0x00000] in <filename unknown>:0
Verse.Log:Error(String)
Verse.DynamicDrawManager:DrawDynamicThings(DrawTargetDef)
Verse.Map:MapUpdate()
Verse.Game:UpdatePlay()
Verse.Root_Play:Update()

Here is my Projectile_PlagueBullet.cs:
Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;

namespace Plague
{
    class Projectile_PlagueBullet : Bullet
    {
        #region Properties
        //
        public ThingDef_PlagueBullet Def
        {
            get
            {
                return this.def as ThingDef_PlagueBullet;

            }

        }


        #endregion Properties

        #region Overrides
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);

            /*
             * Null checking is very important in RimWorld.
             * 99% of errors reported are from NullReferenceExceptions (NREs).
             * Make sure your code checks if things actually exist, before they
             * try to use the code that belongs to said things.
             */
            if (Def != null && hitThing != null && hitThing is Pawn hitPawn) //Fancy way to declare a variable inside an if statement. - Thanks Erdelf.
            {
                var rand = Rand.Value; // This is a random percentage between 0% and 100%
                if (rand <= Def.AddHediffChance) // If the percentage falls under the chance, success!
                {
                    /*
                     * Messages.Message flashes a message on the top of the screen.
                     * You may be familiar with this one when a colonist dies, because
                     * it makes a negative sound and mentioneds "So and so has died of _____".
                     *
                     * Here, we're using the "Translate" function. More on that later in
                     * the localization section.
                     */
                    Messages.Message("PG_PlagueBullet_SuccessMessage".Translate(new object[] {
                        this.launcher.Label, hitPawn.Label
                    }), MessageSound.Standard);

                    //This checks to see if the character has a heal differential, or hediff on them already.
                    var plagueOnPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);
                    var randomSeverity = Rand.Range(0.15f, 0.30f);
                    if (plagueOnPawn != null)
                    {
                        //If they already have plague, add a random range to its severity.
                        //If severity reaches 1.0f, or 100%, plague kills the target.
                        plagueOnPawn.Severity += randomSeverity;
                    }
                    else
                    {
                        //These three lines create a new health differential or Hediff,
                        //put them on the character, and increase its severity by a random amount.
                        Hediff hediff = HediffMaker.MakeHediff(Def.HediffToAdd, hitPawn, null);
                        hediff.Severity = randomSeverity;
                        hitPawn.health.AddHediff(hediff, null, null);
                    }
                }
                else //failure!
                {
                    /*
                     * Motes handle all the smaller visual effects in RimWorld.
                     * Dust plumes, symbol bubbles, and text messages floating next to characters.
                     * This mote makes a small text message next to the character.
                     */
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "PG_PlagueBullet_FailureMote".Translate(Def.AddHediffChance), 12f);
                }
            }
        }
        #endregion Overrides

    }
}
What have I done wrong?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Kilroy232 on June 18, 2017, 10:42:47 PM
Just wanna say that this is a very good tutorial but I am having one problem. I am sure I just have done something silly but some help would be great.
As of right now I have just copy and pasted the example code to see if I did something wrong but I am still getting the error.

Code: [Select]
Severity Code Description Project File Line Suppression State
Error CS0103 The name 'hitPawn' does not exist in the current context PlagueGun C:\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\PlagueGun\PlagueGun\Projectile_PlagueBullet.cs 34 Active

Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: mrofa on June 19, 2017, 12:26:27 PM
Kilroy232 this means your missing variable hitPawn which is created in wierd way in
Code: [Select]
if (Def != null && hitThing != null && hitThing is Pawn hitPawn) //Fancy way to declare a variable inside an if statement. - Thanks Erdelf.Not sure if that statment need some special reference to work..
but to fix it you can try it like this
Code: [Select]
if (Def != null && hitThing != null ) //Fancy way to declare a variable inside an if statement. - Thanks Erdelf.
            {
                 Pawn hitPawn = hitThing as Pawn
               if(hitPawn!=null)
                {
                var rand = Rand.Value; // This is a random percentage between 0% and 100%
                if (rand <= Def.AddHediffChance) // If the percentage falls under the chance, success!
                {
                    /*
                     * Messages.Message flashes a message on the top of the screen.
                     * You may be familiar with this one when a colonist dies, because
                     * it makes a negative sound and mentioneds "So and so has died of _____".
                     *
                     * Here, we're using the "Translate" function. More on that later in
                     * the localization section.
                     */
                    Messages.Message("PG_PlagueBullet_SuccessMessage".Translate(new object[] {
                        this.launcher.Label, hitPawn.Label
                    }), MessageSound.Standard);

                    //This checks to see if the character has a heal differential, or hediff on them already.
                    var plagueOnPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);
                    var randomSeverity = Rand.Range(0.15f, 0.30f);
                    if (plagueOnPawn != null)
                    {
                        //If they already have plague, add a random range to its severity.
                        //If severity reaches 1.0f, or 100%, plague kills the target.
                        plagueOnPawn.Severity += randomSeverity;
                    }
                    else
                    {
                        //These three lines create a new health differential or Hediff,
                        //put them on the character, and increase its severity by a random amount.
                        Hediff hediff = HediffMaker.MakeHediff(Def.HediffToAdd, hitPawn, null);
                        hediff.Severity = randomSeverity;
                        hitPawn.health.AddHediff(hediff, null, null);
                    }
                }
                else //failure!
                {
                    /*
                     * Motes handle all the smaller visual effects in RimWorld.
                     * Dust plumes, symbol bubbles, and text messages floating next to characters.
                     * This mote makes a small text message next to the character.
                     */
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "PG_PlagueBullet_FailureMote".Translate(Def.AddHediffChance), 12f);
                }
              }
            }

It will take out the hitPawn creation from "if" statment and create it after that if check, then check if its not null(if thing is actually a pawn).
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Kilroy232 on June 19, 2017, 06:34:01 PM
There was a semicolon missing after the variable declaration but otherwise this fixed the problem I was having, thank you VERY much.

Code: [Select]
if (Def != null && hitThing != null ) //Fancy way to declare a variable inside an if statement. - Thanks Erdelf.
            {
                 Pawn hitPawn = hitThing as Pawn
               if(hitPawn!=null)

Also a big thank you to jecrell for this very well written tutorial!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jamaicancastle on June 21, 2017, 02:29:23 AM
Thanks for a remarkably in-depth tutorial! I have a question that might make for a good addition and/or follow-on tutorial. I'm working on a mod for new ship parts, and as part of it, I'd like to add a check to the launch report that the ship has enough thrust for its weight, etc. I know to do that I need to modify the existing starship code, and I know I'm supposed to use the Harmony library to do it, but I have no idea how to do either of these things. :-[ If anyone has a tutorial along those lines that would be spectacular.

Out of curiosity:  Step 11 states to copy all of the ThingDef Parents and Bases to your XML...
And then your code snippet also includes BaseHumanGun.  Is that inclusion necessary?  I don't see it as a parent in either the Pistol Bullet or the Pistol Gun.

You don't need to include core defs at all. Parenting them will work just fine using the core files (as long as you have the parent's name down correctly).
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Cryusaki on July 03, 2017, 04:23:21 PM
Probably the best modding tutorial for Rimworld on the internet but it is still missing so much detail that it's hard to follow
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jecrell on July 08, 2017, 05:28:51 AM
Probably the best modding tutorial for Rimworld on the internet but it is still missing so much detail that it's hard to follow
Where? I'd like to improve the tutorial. So what's confusing?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Spdskatr on July 09, 2017, 08:35:24 PM
Required Items


Notepad++ (https://notepad-plus-plus.org/) or
Atom (https://atom.io/) or
Sublimetext (https://www.sublimetext.com/)
|Use any text editor that allows you to edit XML files and use "Find in Files" for referencing.
Visual Studio Community (https://www.visualstudio.com/vs/community/)|Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.
Zentar's ILSpy (https://github.com/Zhentar/ILSpy/releases)|This is for referencing the game's decompiled C# scripts. **NOTE** Regular ILSpy will not give you the cleanest code. For best results, please use Zhentar's ILSpy.
Just a quick pointer (0x154ca6e7 hahahah) You may want to specify the Visual Studio Community version (2017). I see so many people asking questions because their VS is an earlier version that cannot read C# 7...

Cheers
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: MarvinKosh on July 12, 2017, 01:20:35 PM
Hey Jecrell,

Something that's sort of missing is a newbies guide to what to do after your mod is on Workshop.

For example, I have this problem where some of my mods are more well-known than others.

Now, I don't know if this is the best solution, but I figured it couldn't hurt to try. I added the following to the end of the description on my most popular mods on Workshop:

Code: [Select]
If you like this mod, why not consider looking at some of my other mods?

[b]Harsher Tundra[/b]
No trees in the tundra biome, fewer grazing animals. Ice patches.

[b]Really Toxic Fallout[/b]
Even brief exposure to toxic fallout can now cause life-threatening complications. Stay indoors!

[b]Less Annoying UI Sounds[/b]
You no longer need go berserk because of an annoying ding or boo-doop.

[b]No Doomed Friendlies[/b]
Friendlies will not show up if you haven't opened the ancient danger room.

[b]Solar Apocalypse & Rogue Planet[/b]
These planet-threatening game conditions will have you researching ship-building like a boss.

[b]Peaceful Fixes[/b]
Peaceful difficulty is new, and there are a few events which show up despite it supposedly being free of threats.

[b]Difficulty Expansion[/b]
Is Extreme not extreme enough for you? Are the easier difficultites not easy enough?

[b]Combat Readiness Check[/b]
Raids now scale mostly based on your colonists, how healthy they are, and what weapons or armour you can equip them with.

[b]No Doomed Newbies[/b]
Wanderers who join, and chased refugees who refuge, and even escape pod survivors will be more relevant to your colony.

Looks good, right? :)
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: SpaceDorf on July 16, 2017, 10:34:22 PM
post to follow ..
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Cayprol on July 24, 2017, 08:05:18 AM
Great guide! totally, good for newbies like me.

btw, the example file still hasn't been fixed, that missing "/".

Also, for this guide particularly, I did all this on a Mac.
Just to try out how the recently ported VS works.
Didn't encounter any problem so far, I even used the built-in decompiler to inspect assembly.
Visual Studio for Mac requires Mono 5.0 and higher, so no .NET3.5.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: D Mars on August 03, 2017, 05:59:31 PM
Hey so I followed your guide, I'm able to spawn the Plague gun in game but it doesn't work when I try shooting another colonist. I downloaded all 3 files so I can visually compare them and everything seems to match up. I get this error on load though(http://imgur.com/a/T7X7i), any ideas on where I went wrong? Thanks!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Wof on August 03, 2017, 08:36:42 PM
Hey so I followed your guide, I'm able to spawn the Plague gun in game but it doesn't work when I try shooting another colonist. I downloaded all 3 files so I can visually compare them and everything seems to match up. I get this error on load though(http://imgur.com/a/T7X7i), any ideas on where I went wrong? Thanks!

I had the same issue. The problem was that the .dll wasn't created in my Assemblies folder but instead in a new folder inside the Source folder. I just moved it and it was fine.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: D Mars on August 03, 2017, 10:03:54 PM

I had the same issue. The problem was that the .dll wasn't created in my Assemblies folder but instead in a new folder inside the Source folder. I just moved it and it was fine.

This was it! Plague gun works now with no issues! Thanks bro you're the best!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Wof on August 03, 2017, 10:12:34 PM
No problem! Glad I could help  :)
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: SpaceDorf on August 06, 2017, 05:57:16 AM
Thank you flying spaghetti monster for finally sending my to the right IDE

 sometimes microsoft gets it right  (https://sourceforge.net/projects/vscode-portable/)

it's fast, it's portable, it's beautiful ..
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Eck on August 06, 2017, 03:06:36 PM
Awesome tutorial, but I think there are some unnecessary steps. You don't need to (and I don't think you should) include all the parent base items in your custom RangedWeapon_PlagueGun.xml file. Those entries will already included from the Core game files so the copied entries aren't necessary (and might cause conflicts). Basically skip step 11, and remove every ThingDef in the RangedWeapon_PlagueGun.xml file after the BASES comment.

I followed the tutorial through and got everything working even though I raised my eyebrow at the copy/pasted base classes. After that, I deleted all the base def entries, changed some other things like fire rate and range, and everything still worked.

@Tynan - Could you double check my post and make sure I'm giving good advice. I only just started messing with modding Rim World and even though I tested what I said, I wouldn't mind a sanity check. :)

- Eck
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Spdskatr on August 19, 2017, 04:19:24 AM
Awesome tutorial, but I think there are some unnecessary steps. You don't need to (and I don't think you should) include all the parent base items in your custom RangedWeapon_PlagueGun.xml file. Those entries will already included from the Core game files so the copied entries aren't necessary (and might cause conflicts). Basically skip step 11, and remove every ThingDef in the RangedWeapon_PlagueGun.xml file after the BASES comment.

Always add the abstracts in. When I was developing my plastics mod (rip that mod) I had a weird conflict with Numbers (that I only discovered during casual play and probably wasn't the fault of the mod author) that meant the game wasn't recognizing the abstracts from other mod folders, causing errors like "ThingDef __ has null ThingClass". It disappeared only when I added the building and resource base abstracts.

The abstracts thing was supposedly meant to start inheriting from previous mods in A14, but I developed the mod in A16.

Moral of the story: Always add them in. You may get unexpected and obscure bugs.

P.S. If it works for you then you really don't need to read any of this. it's just a warning in case you encounter null ThingClass errors in the future :P
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: BinkyThePirate on August 21, 2017, 05:25:45 PM
This is a very useful intro to modding basics, and for the most part I know enough xml and C# to get what's going on in it, but with the 'var plagueOnPawn' section I'm not really clear on what is happening, just retyping what's there in the tutorial without really understanding why. Could someone give a basic rundown of what's actually going on there?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Jibbles on August 22, 2017, 06:05:08 AM
New to visual studios..and it's late.  Just don't hate me for asking. I sort of get stuck at step 18 and I want to make sure I'm doing this right.

He mentions going into the application tab.  Is "project options" the same thing?
http://i.imgur.com/dmwUfrw.png (http://i.imgur.com/dmwUfrw.png)
This window is the only place I see where I can change stuff like the namespace, framework etc. 


Quote
20) Go to the Build tab in the project properties.

21) Change the output path to be RimWorld\Mods\PlagueGun\Assemblies
- All .dll files will go into this directory when we "build" our code library.

22) In that same window, click the Advanced... button.

23) Change Debugging information to none.
- This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.

This is what makes me think I'm in the wrong place. I don't see an advanced button, or overlooking where I can change the debug information to none.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: BinkyThePirate on August 22, 2017, 07:00:13 AM
Mac layout of Visual Studio seems slightly different. For Windows, clicking on 'Build' from the menu tree on your left would bring up the Build properties tab, where you can set the options mentioned. Check under the 'Output' sub-menu, that might let you change the output path and give you the No Debugging Info option. But that's just a guess. Maybe someone with VS for Mac can offer more help. It's probably inside one of those sub-menus under Build, though.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: janospalfi on August 22, 2017, 10:11:55 PM
Thanks for the tutorial, easy to follow and actually goes into coding.  After putting it all together, I get the gun to spawn and everything works as intended, however, upon loading the mod I receive a bunch of XML errors:
XML error: Duplicate XML node name #text in this XML block: <ThingDef Name="BaseMakeableGun" ParentName="BaseGun" Abstract="True">
I've been through the xml file looking for a missing /
Tried removing the Bases
And haven't been able to figure out what the problem is
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Jibbles on August 23, 2017, 02:11:00 AM
Find it strange that there isn't a completed version to download so we can test and see how everything is supposed to look and work. Can someone share? I'm grateful for this tutorial but I'm not able to get it to work.

still missing the / in xml file.

I come across errors even though I've copied things word for word. Guess I'm doing something wrong when it comes building the project.

Could not find type named Plague.ThingDef_PlagueBullet from node
Could not find a type named Plague.Projectile_PlagueBullet
XML error: <AddHediffChance>0.05</AddHediffChance> doesn't correspond to any field in type ThingDef.
XML error: <HediffToAdd>Plague</HediffToAdd> doesn't correspond to any field in type ThingDef.
Config error in TST_Bullet_PlagueGun: TST_Bullet_PlagueGun has null thingClass.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Veridian on September 13, 2017, 11:45:37 AM
Find it strange that there isn't a completed version to download so we can test and see how everything is supposed to look and work. Can someone share? I'm grateful for this tutorial but I'm not able to get it to work.

still missing the / in xml file.

I come across errors even though I've copied things word for word. Guess I'm doing something wrong when it comes building the project.

Could not find type named Plague.ThingDef_PlagueBullet from node
Could not find a type named Plague.Projectile_PlagueBullet
XML error: <AddHediffChance>0.05</AddHediffChance> doesn't correspond to any field in type ThingDef.
XML error: <HediffToAdd>Plague</HediffToAdd> doesn't correspond to any field in type ThingDef.
Config error in TST_Bullet_PlagueGun: TST_Bullet_PlagueGun has null thingClass.

Hey, I found the solution to this problem after running into it myself.

For whatever reason, this tutorial has the wrong information regarding the file hierarchy of the mods folder. You can see the correct hierarchy here: http://rimworldwiki.com/wiki/Modding_Tutorials/Mod_folder_structure

I would recommend downloading a mod that adds guns, looking over their file format, and then restructuring the plague gun folder to look like theirs. I did that, and it fixed the issue.

Unfortunately, now that the gun can be spawned in the game, it doesn't appear to be causing the plague. Even though I get the text telling me that it was a successful plague inflict, the pawn does not have the plague. Will look into it more.

Otherwise, this is a wonderful resource when getting into modding. But, if you are new to modding and are looking to use this guide, I have to recommend looking over the modding wiki a few times first. This step by step tutorial has a few bumps that will be really difficult to overcome unless you use the resources on the wiki.

Edit: So as it turns out, the gun does work! Due to how the plague works, the gun will inflict a 'hidden' plague on the victim. This plague will develop overtime until it reaches a threshold upon which it will notify you that that pawn has the plague! Alternatively, you can just keep shooting the victim, and assuming they don't die first, you'll eventually be notified that they have the plague. This is because the C# code adds the severity to a pawn who already has the plague rather than resetting the severity. Neat!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: SpaceDorf on September 19, 2017, 12:29:58 PM
Thank you flying spaghetti monster for finally sending my to the right IDE

 sometimes microsoft gets it right  (https://sourceforge.net/projects/vscode-portable/)

it's fast, it's portable, it's beautiful ..

Or not .. VisualStudio it is then .. fascinating that the IDE has become the greatest obstacle to start programming...
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: CrazyMalk on October 07, 2017, 12:09:54 AM
Gosh... I'm getting my a** kicked from Visual Studio 2017... For some reasone there isn't any "build" tab in the Properties menu. Does anyone knows why?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: CrazyMalk on October 07, 2017, 11:44:20 PM
Nevermind, got it to work! But now i'm having a problem when trying to build the project:
Code: [Select]
Severity Code Description Project File Line Suppression State
Error CS0117 'HediffDefOf' does not contain a definition for 'Petrification' BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\BasiliskVision.cs 15 Active
Error CS1061 'Projectile_PetrifyBullet' does not contain a definition for 'def' and no extension method 'def' accepting a first argument of type 'Projectile_PetrifyBullet' could be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 16 Active
Error CS1061 'Projectile_PetrifyBullet' does not contain a definition for 'launcher' and no extension method 'launcher' accepting a first argument of type 'Projectile_PetrifyBullet' could be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 30 Active
Error CS0115 'Projectile_PetrifyBullet.Impact(Thing)': no suitable method found to override BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 21 Active
Error CS1061 'string' does not contain a definition for 'Translate' and no extension method 'Translate' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 29 Active
Error CS0103 The name 'HediffMaker' does not exist in the current context BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 40 Active
Error CS0103 The name 'Messages' does not exist in the current context BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 29 Active
Error CS0103 The name 'MessageSound' does not exist in the current context BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 31 Active
Error CS0103 The name 'Rand' does not exist in the current context BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 26 Active
Error CS0103 The name 'Rand' does not exist in the current context BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 33 Active
Error CS0246 The type or namespace name 'Bullet' could not be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 8 Active
Error CS0246 The type or namespace name 'Hediff' could not be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 40 Active
Error CS0246 The type or namespace name 'Pawn' could not be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 24 Active
Error CS0234 The type or namespace name 'Tasks' does not exist in the namespace 'System.Threading' (are you missing an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\BasiliskVision.cs 5 Active
Error CS0246 The type or namespace name 'Thing' could not be found (are you missing a using directive or an assembly reference?) BasiliskEye C:\Users\USUARIO\source\repos\BasiliskEye\BasiliskEye\Petrify.cs 21 Active

"Petrify" is the same as "Plague", on the tutorial :P Can anyone help me?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: DJRockXD on October 12, 2017, 06:48:33 AM
I couldn't find the "defName" file or the "Bullet_Pistol" document using that "find in file" thing. Plus I could only find that function in Notepad++, not in Atom...
I found a "Bullet_Pistol" reference manually in the "Weapons_Guns" XML document, but not a stand alone version of it...
And I am probably an idiot for not being able to make the "Find in Files" function work even in Notepad++, as it couldn't find anything on my computer when I tested it out multiple times... Help please ):
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: CrazyMalk on October 12, 2017, 08:10:25 AM
Try selecting only the "Core">"Defs" folder inside "Mods" on that browsing place. You need to set up a location to it search.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: DrMrEd on October 12, 2017, 09:16:11 AM
I couldn't find the "defName" file or the "Bullet_Pistol" document using that "find in file" thing. Plus I could only find that function in Notepad++, not in Atom...
I found a "Bullet_Pistol" reference manually in the "Weapons_Guns" XML document, but not a stand alone version of it...
And I am probably an idiot for not being able to make the "Find in Files" function work even in Notepad++, as it couldn't find anything on my computer when I tested it out multiple times... Help please ):
Kudos to the tutorial maker and suggesting folks learn to search the Defs -- you'll be doing a ton of this when you start down your own path. But for this one, no need to search blindly for strings in files. All the weapons stuff is in Defs\ThingDefs_Misc\Weapons_Guns.xml. There Bullet_Pistol def is at line 65. There is no standalone version - although each ThingDef could probably be spread out in its own file, but that would be a nightmare in other ways.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: CrazyMalk on October 22, 2017, 12:23:46 PM
Ok... I was able to build the mod into a single dll, but now i'm having in-game console errors. And i think they are caused because i used a custom hediff in the C# code... What should i do to perfectly insert my custom heddiff into the Visual Studio project?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: StoneWolf on November 06, 2017, 01:51:24 PM
To begin with must I compliment you on having made this excellent tutorial! This is the sixth time I've tried modding and it is for sure the easiest start I've ever had. All thanks to you and Tynan of course! ;)

I'm just a bit curious though. In your tutorial you advise on setting a prefix for the defName variable in order to increase mod compatability. Should I do the same for the file name? Or does it really not matter what its called?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jamaicancastle on November 22, 2017, 12:37:13 AM
One correction to update this for B18: the message syntax has changed. Where you have
Code: [Select]
                    }), MessageSound.Standard);in the huge block of code for the projectile class, it should be
Code: [Select]
                    }), MessageTypeDefOf.NeutralEvent);(or any of the other MessageTypeDef options, that just seemed the most like what it was doing before). I can verify that the rest of it works as advertised.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: kaptain_kavern on November 22, 2017, 12:56:57 AM
In your tutorial you advise on setting a prefix for the defName variable in order to increase mod compatability. Should I do the same for the file name? Or does it really not matter what its called?

Nope, for the file name, there is no problems, you can call them as you want. You could even have all your xml code in one file if you wanted ^^ - I don't see why doing this, but my point being: you can do anyhow you prefer
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: DrunkRussianBear on November 22, 2017, 06:48:15 PM
I'm lost right now, what is the reason behind the C# code? is it necessary? I read through the tutorial but fail to understand the purpose of the code(what each line actually does).
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: kaptain_kavern on November 22, 2017, 09:55:32 PM
For simple mods, you don't need C# at all. I've done lots of mods and still don't know C# yet.

Most of the time, you'll need C# if your mod needs to "something" that is not a vanilla "normal" mechanics. But you don't need C# at all to make new plants, animals, buildings, benches, etc... as long as they behave like vanilla do
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: DrunkRussianBear on November 22, 2017, 10:32:42 PM
So for a simple weapon/clothing mod all I need is XML? if so that's pretty neat, I'm currently working on a weapon/clothing mod that adds the full arsenal of my fictional nation(can be found here: https://www.nationstates.net/nation=velariya) including uniforms and all. Just gotta wait for CE to update so I can make a compatibility patch once I know my guns work in vanilla.

By the way any chance you could take a peek through my mod once I'm done? I'm not sure what has changed in B18(code syntax wise) so I'm a bit scared it won't work in B18.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: kaptain_kavern on November 22, 2017, 11:49:36 PM
Oh right, I sure can have a look.

But most of the time the (red) error message will tell you explicitly what is going wrong. My updating/debugging mods process is: launch the mod, copy paste the wall of errors (starting by the red ones only, yellow error are often less harmful) in my text editor, then for each error I searched for the exact location and do what the error message is saying... Doing that for each errors, relaunch and repeat the process.

But if I can help you, I'll do, no problems
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Son_Of_Diablo on November 25, 2017, 09:52:00 PM
Thanks for this tutorial!
Really explains everything well! :)


I got the test mod working, but I do have an issue where it won't add Plague to the attacked pawn (I do get the success message though).
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Bendigeidfran on December 06, 2017, 06:42:03 PM
Phenomenal, thank you. There were a couple places that could use a bit of clarity and the MessageSound doesn't exist, I had to change it to something else, but overall thank you very much.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: tudy on December 28, 2017, 05:02:41 PM
Hi,

I basically signed up to the forums to tell you what a good job you did on the tutorial. I followed the steps and so many things are much clearer now. I encountered a few little problems on the way that others already mentioned. To be precise:

This
Code: [Select]
if (Def != null && hitThing != null)
            {
            Pawn hitPawn = hitThing as Pawn;
            if(hitPawn != null)
helps, if you get an error in the if-clause, when initiating "hitPawn" inside of it.

This
Code: [Select]
Messages.Message("TST_PlagueBullet_SuccessMessage", new MessageTypeDef());
helped me with the error in the Message-function. I guess the game got an update, which is not taken care of yet, in the tutorial?

Then this line prevented me from building:
Code: [Select]
var plagueOnPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);

I cancelled out the question-marks, resulting in the buildable version:
Code: [Select]
var plagueOnPawn = hitPawn.health.hediffSet.GetFirstHediffOfDef(Def.HediffToAdd);

Not 100% sure what these "?" are actually doing, but the result works as intended, so, if anyone else got that problem, this might be your solution as well.

I do have a few questions, however, that maybe some helpful person can answer:
1) What is the first .cs file good for (Steps 31 - 35)? I can't wrap my head around, what it actually does. Isn't all of that done already in the XML-file? If it is just about making a blueprint, couldn't we put all of what's happening there just into the second .cs file created?
2) To test out the mod I wanted to put the chance to apply the Plague to 100%. So, I went into the first .cs file (the one I wonder what it actually is doing) and set the value to "1.0f". But it had no effect whatsoever. Only after I changed it in the XML to "1.0" it applied the Plague to each shot. Why is that? What's the difference between the value set in the .cs-file and the xml-file? Where should I actually change such values in good practice?

Thanks again for this great tutorial. Maybe the answers of the above could be implemented into it, to give more clarity to what's actually happening "behind the curtains".
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jamaicancastle on December 30, 2017, 12:24:46 AM
This
Code: [Select]
if (Def != null && hitThing != null)
            {
            Pawn hitPawn = hitThing as Pawn;
            if(hitPawn != null)
helps, if you get an error in the if-clause, when initiating "hitPawn" inside of it.
If I'm understanding correctly, the error-checking you're thinking of is encapsulated in the is operator already. It will return false if hitThing can't be coerced into being a Pawn, which will prevent the entire block from happening at all. (If you have as for is in the if statement, then you're correct, it is possible to get a null result stored in hitPawn if given a non-pawn object.)

Quote
Then this line prevented me from building:
Code: [Select]
var plagueOnPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);

I cancelled out the question-marks, resulting in the buildable version:
Code: [Select]
var plagueOnPawn = hitPawn.health.hediffSet.GetFirstHediffOfDef(Def.HediffToAdd);

Not 100% sure what these "?" are actually doing, but the result works as intended, so, if anyone else got that problem, this might be your solution as well.
I had no problems building with the ?s using the suggested IDE. It's possible it's a compatibility

As for what they do: "." means "from the object specified to the left, find the attribute specified to the right". "?." means "from the object specified to the left, if it isn't null, find the attribute specified to the right". It's a compact way of avoiding errors if for whatever bizarre reason the pawn doesn't have a hediff set or whatever.

Quote
1) What is the first .cs file good for (Steps 31 - 35)? I can't wrap my head around, what it actually does. Isn't all of that done already in the XML-file? If it is just about making a blueprint, couldn't we put all of what's happening there just into the second .cs file created?
Basically the class tells Rimworld that a def category exists. It's a bridge between the engine and the XML files; without that, it doesn't know how to parse the XML. It also allows other code to refer to a def class; that's not important for this specific class, but it's critical for many classes.

As for putting them in the same file: I think you could, if you wanted to, but having each class in its own file is considered better practice.

Quote
2) To test out the mod I wanted to put the chance to apply the Plague to 100%. So, I went into the first .cs file (the one I wonder what it actually is doing) and set the value to "1.0f". But it had no effect whatsoever. Only after I changed it in the XML to "1.0" it applied the Plague to each shot. Why is that? What's the difference between the value set in the .cs-file and the xml-file? Where should I actually change such values in good practice?
The values in the .cs file are basically placeholders or defaults. You can think of it like having a default parameter for a function. For example, if a default AddHediffChance exists in the code definition for ThingDef_PlagueBullet, then if your XML happens to have a ThingDef_PlagueBullet that lacks an AddHediffChance, it will use the default. If there's no default and nothing in the XML it will give an error when loaded.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Sandy on February 01, 2018, 06:08:45 PM
Then this line prevented me from building:
Code: [Select]
var plagueOnPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);

I cancelled out the question-marks, resulting in the buildable version:
Code: [Select]
var plagueOnPawn = hitPawn.health.hediffSet.GetFirstHediffOfDef(Def.HediffToAdd);

Not 100% sure what these "?" are actually doing, but the result works as intended, so, if anyone else got that problem, this might be your solution as well.

thanks man, i had this error too and u helped clear it..  :)

and Thanks VERY MUCH Jecrell, for this wonderful tutorial.. using this, i managed to make the plague gun.. i had some trouble, bcoz i was using SharpDevelop.. but the steps in the modding tutorial in the wiki made it easier.. :)
i decided to try my hand at this and made a small mod by copying the core weapons xml file and changing most of the weapons Bullet damage to Flame damage.. it worked nicely too.. raiders were burning and panicking and fleeing..  ;D ;D ;D
Thanks to everyone that provided tips and fixes..  :) :) :)
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: fyarn on February 13, 2018, 06:40:26 PM
Hey jecrell, great guide! Could I suggest you add the Rimworld cookiecutter template?
https://ludeon.com/forums/index.php?topic=39038

It has a command-line tool for setup without using VisualStudio, as well as a VisualStudio integration to create a mod without even leaving VS to make folders.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: ttamttam on March 03, 2018, 04:18:32 PM
Thank you for demystifying mods and c#. I've always wanted to get into more serious coding but setting up environments always scared me.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Khaligufzel on March 07, 2018, 04:24:04 PM
Hey, new moders!
Don't try to find 'Bullet_Gun' in your files!

Since v 0.18, you should search for Bullet_Revolver or Bullet_Autopistol. There is no more just 'Pistol' in RimWorld :)

@jecrell
Thanks for this tutorial mate!


edit:
Also <defaultProjectile> not <projectileDef>
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Jernfalk on March 15, 2018, 12:58:50 PM
The tutorial is fantastic. As a first-timer, there were a lot of things that I had no idea that existed.
However, to do different objects is still a struggle. Is there a more generic tutorial? One with only the absolute necessary amount of .xml and C#?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Negomir99 on April 11, 2018, 11:43:25 AM
This tutorial is great, I managed to get the gun into the game, even tweak its accuracy and other stats, but every time the bullet hits anything I get this error:
Quote
Exception ticking NEGO_Bullet_PlagueGun110669: System.StackOverflowException: The requested operation caused a stack overflow.
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
.
. have to shorten it because it's too long for the post...
.
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
Verse.Log:Error(String)
Verse.TickList:Tick()
Verse.TickManager:DoSingleTick()
Verse.TickManager:TickManagerUpdate()
Verse.Game:UpdatePlay()
Verse.Root_Play:Update()

I know this tutorial isn't really recent, but if anyone can help it would be greatly appreciated!!

here is the XML file:
Quote
<?xml version="1.0" encoding="utf-8"?>

<ThingDefs>

   <ThingDef Class="Plague.ThingDef_PlagueBullet" ParentName="BaseBullet">
    <defName>NEGO_Bullet_PlagueGun</defName>
    <label>pistol bullet</label>
    <graphicData>
      <texPath>Things/Projectile/Bullet_Small</texPath>
      <graphicClass>Graphic_Single</graphicClass>
    </graphicData>
    <projectile>
      <flyOverhead>false</flyOverhead>
      <damageDef>Bullet</damageDef>
      <DamageAmountBase>1</DamageAmountBase>
      <Speed>55</Speed>
   </projectile>
   <AddHediffChance>1.0</AddHediffChance>
   <HediffToAdd>Plague</HediffToAdd>
   <thingClass>Plague.Projectile_PlagueBullet</thingClass>
  </ThingDef>
 
  <ThingDef ParentName="BaseHumanMakeableGun">
    <defName>NEGO_Gun_PlagueGun</defName>
    <label>plague gun</label>
    <description>A curious weapon notable for its horrible health effects.</description>
    <graphicData>
      <texPath>Things/Item/Equipment/WeaponRanged/Pistol</texPath>
      <graphicClass>Graphic_Single</graphicClass>
    </graphicData>
    <soundInteract>InteractPistol</soundInteract>
    <statBases>
      <WorkToMake>15000</WorkToMake>
      <Mass>1.2</Mass>
      <AccuracyTouch>1.0</AccuracyTouch>
      <AccuracyShort>1.0</AccuracyShort>
      <AccuracyMedium>1.0</AccuracyMedium>
      <AccuracyLong>1.0</AccuracyLong>
      <RangedWeapon_Cooldown>1.26</RangedWeapon_Cooldown>
    </statBases>
    <costList>
      <Steel>30</Steel>
      <Component>2</Component>
    </costList>
    <verbs>
      <li>
        <verbClass>Verb_Shoot</verbClass>
        <hasStandardCommand>true</hasStandardCommand>
        <projectileDef>NEGO_Bullet_PlagueGun</projectileDef>
        <warmupTime>0.3</warmupTime>
        <range>24</range>
        <soundCast>ShotPistol</soundCast>
        <soundCastTail>GunTail_Light</soundCastTail>
        <muzzleFlashScale>9</muzzleFlashScale>
      </li>
    </verbs>
  </ThingDef>
 
</ThingDefs>

and the CS file
Quote
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;

namespace Plague
{
    class Projectile_PlagueBullet : Bullet
    {

        #region Properties
           
        public ThingDef_PlagueBullet Def
        {
            get
            {
                return this.Def as ThingDef_PlagueBullet;
            }
        }

        #endregion

        #region Overrides

        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);

            Pawn hitPawn = hitThing as Pawn;
            float randomSeverity = Rand.Value;

            if (Def != null && hitThing != null && hitPawn != null)
            {
                var rand = Rand.Value;
                if(rand <= Def.AddHediffChance)
                {
                    Messages.Message("NEGO_PlagueBullet_SuccessMessage".Translate(new object[]
                    {
                        this.launcher.Label, hitPawn.Label
                    }), MessageSound.Standard);
                }

                var plagueOrPawn = hitPawn?.health?.hediffSet?.GetFirstHediffOfDef(Def.HediffToAdd);
                if (plagueOrPawn != null)
                {
                    plagueOrPawn.Severity += randomSeverity;
                }
                else
                {
                    Hediff hediff = HediffMaker.MakeHediff(Def.HediffToAdd, hitPawn, null);
                    hediff.Severity = randomSeverity;
                    hitPawn.health.AddHediff(hediff, null, null);
                }
            }
            else
            {
                MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "NEGO_PlagueBullet_FailureMote".Translate(Def.AddHediffChance), 12f);
            }
        }

        #endregion
    }
}

and on top of that error, no plague is ever added.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: jamaicancastle on April 11, 2018, 01:01:34 PM
This tutorial is great, I managed to get the gun into the game, even tweak its accuracy and other stats, but every time the bullet hits anything I get this error:
Quote
Exception ticking NEGO_Bullet_PlagueGun110669: System.StackOverflowException: The requested operation caused a stack overflow.
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
As a general rule, a stack overflow happens when you cause RW to try to do something recursively and end up in an infinite loop. In this case, you can see that it's in the Def getter, here:

Code: [Select]
        public ThingDef_PlagueBullet Def
        {
            get
            {
                return this.Def as ThingDef_PlagueBullet;
            }
        }
In this case it's calling this.Def - which is to say, itself, hence the infinite loop. It should be calling this.def (note the capitalization), which is a property of the base object.

The code goes along fine until it actually tries to get Def, which it does in Impact, specifically in this line:
Code: [Select]
            if (Def != null && hitThing != null && hitPawn != null)Because it runs into the error, the rest of the Impact method doesn't get run, hence why it doesn't apply its impact effects.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Negomir99 on April 11, 2018, 05:11:27 PM
This tutorial is great, I managed to get the gun into the game, even tweak its accuracy and other stats, but every time the bullet hits anything I get this error:
Quote
Exception ticking NEGO_Bullet_PlagueGun110669: System.StackOverflowException: The requested operation caused a stack overflow.
  at Plague.Projectile_PlagueBullet.get_Def () [0x00000] in <filename unknown>:0
As a general rule, a stack overflow happens when you cause RW to try to do something recursively and end up in an infinite loop. In this case, you can see that it's in the Def getter, here:

Code: [Select]
        public ThingDef_PlagueBullet Def
        {
            get
            {
                return this.Def as ThingDef_PlagueBullet;
            }
        }
In this case it's calling this.Def - which is to say, itself, hence the infinite loop. It should be calling this.def (note the capitalization), which is a property of the base object.

The code goes along fine until it actually tries to get Def, which it does in Impact, specifically in this line:
Code: [Select]
            if (Def != null && hitThing != null && hitPawn != null)Because it runs into the error, the rest of the Impact method doesn't get run, hence why it doesn't apply its impact effects.

You are completely right, and I'm completely stupid.. Thank you very much!!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Negomir99 on April 12, 2018, 11:26:09 AM
ok another thing... my bullets keep giving the target severity 1 or 100% and killing them instantly.

here is the bullet in xml:
Quote
<ThingDef Class = "PlagueGun.ThingDef_PlagueBullet" ParentName="BaseBullet">
      <defName>Bullet_PlagueGun</defName>
      <label>PlagueGun bullet</label>
      <graphicData>
        <texPath>Things/Projectile/Bullet_Small</texPath>
        <graphicClass>Graphic_Single</graphicClass>
      </graphicData>
      <projectile>
        <flyOverhead>false</flyOverhead>
        <damageDef>Bullet</damageDef>
        <damageAmountBase>11</damageAmountBase>
        <speed>55</speed>
      </projectile>
      <AddHediffChance>0.5</AddHediffChance>
      <HediffToAdd>Plague</HediffToAdd>
      <thingClass>PlagueGun.Projectile_PlagueGun</thingClass>
  </ThingDef>

and here is the 2 classes:
Quote
namespace PlagueGun
{
    public class ThingDef_PlagueBullet : ThingDef
    {
        public float AddHediffChance = .5f;
        public HediffDef HediffToAdd = HediffDefOf.Plague;
    }
}
and
Quote
namespace PlagueGun
{
    class Projectile_PlagueGun : Bullet
    {
        public ThingDef_PlagueBullet Def
        {
            get
            {
                return this.def as ThingDef_PlagueBullet;
            }
        }

        #region Overrides
        protected override void Impact(Thing hitThing)
        {
            Pawn hitPawn = hitThing as Pawn;

            if (Def != null && hitThing != null && hitPawn != null)
            {
                var rand = Rand.Value;
                if (rand <= Def.AddHediffChance)
                {
                    var plagueOnPawn = hitPawn.health.hediffSet.GetFirstHediffOfDef(Def.HediffToAdd);
                    var randomSeverity = .3f;
                    if (plagueOnPawn != null)
                    {
                        plagueOnPawn.Severity += randomSeverity;
                    }
                    else
                    {
                        Hediff hediff = HediffMaker.MakeHediff(Def.HediffToAdd, hitPawn, null);
                        hediff.Severity = randomSeverity ;
                        hitPawn.health.AddHediff(hediff, null, null);
                    }
                }
            }
        }
        #endregion Overrides
    }
}
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: dninemfive on April 22, 2018, 06:34:38 PM
How do you get the .NET Framework 3.5 in a C# Library project? I have it loaded and can access it in projects of other types, but for that one in particular I can only access versions 1.0 through 2.0. I'm using Visual Studio 2017 Community.

edit: I figured it out. For anyone else with this problem, make sure you're creating a "Windows Classic Desktop" project.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Sokestu on April 28, 2018, 06:45:49 PM
Thank you dninemfive you save me there
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: zivshek on June 23, 2018, 12:20:03 AM
Awesome tutorial, but I think there are some unnecessary steps. You don't need to (and I don't think you should) include all the parent base items in your custom RangedWeapon_PlagueGun.xml file. Those entries will already included from the Core game files so the copied entries aren't necessary (and might cause conflicts). Basically skip step 11, and remove every ThingDef in the RangedWeapon_PlagueGun.xml file after the BASES comment.

I followed the tutorial through and got everything working even though I raised my eyebrow at the copy/pasted base classes. After that, I deleted all the base def entries, changed some other things like fire rate and range, and everything still worked.

@Tynan - Could you double check my post and make sure I'm giving good advice. I only just started messing with modding Rim World and even though I tested what I said, I wouldn't mind a sanity check. :)

- Eck

Hey Eck,

You are totally right, shouldn't have messed with the base classes. He changed the names of all the base classes, some of which don't even exist, such as "TST_BaseWeapon", he didn't create this one. It's not about confusion, it's wrong...
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: RogerZero on August 24, 2018, 04:27:49 PM
Hello there!

Thirst of all, thanks for the tutorial!
I even get the gun placed in the game but when a colonist trys to shoot it always has the same error:
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Thom Blair III on August 26, 2018, 02:49:05 AM
I use Mac. Do you have any recommendations on tutorials on how to learn the basics of VS for Mac? The layout of VS for Mac is so dramatically different from the Windows version that it's impossible to follow your tutorial.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Neceros on September 16, 2018, 08:02:03 PM
This is wonderful! Thank you.

However, I do have a question:

What namespace and assembly name should I use if I intend to alter the base rimworld files?

FOR INSTANCE I'm trying to alter the smooth speed. Tynan told me there's a few job constants that hold this information, and I found them in dnSpy "JobDriver_SmoothWall" and "JobDriver_SmoothFloor". What do I do if I'm not adding new Defs? Just add the assembly? Use the Rimworld namespace?

Thanks!!!
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Iamkriil on October 12, 2018, 05:57:18 PM
Thanks for this tutorial.

Is there documentation on all of the classes that we can inherit from?  I'm an expert in Java but a novice in C#. Java has Java Docs that show packages, classes and methods: https://javaee.github.io/javaee-spec/javadocs/

Does anything like this exist for RimWorld? If not, is there anyway to get a copy of the source code?
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Reize81 on January 02, 2019, 09:47:29 AM
Thanks for the tutorial.

I am a total newbie to modding and I have absolutely no clue what I am doing. I tried to go through the tutorial step by step and it seems to work until step 36.

Then it gets a little unclear what I should do. I tired my best and I end up with a bunch of errors when I try to build my project in step 46.

It would be really helpful to get files that work with the latest version of rimworld - I certainly have an error somewhere in the second "class" i created and i guess some things are obsolete or updated in the latest version of rimworld. The attached files have been removed by the admin due to age. Does someone have working files ? I'd like to compare and find out what I did wrong.

I want to learn. Plz help.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: Mehni on February 07, 2019, 09:36:39 AM
An updated version of this tutorial is now available on the wiki

https://rimworldwiki.com/wiki/Plague_Gun/Introduction

The wiki also links to a GitHub repository, where a working version of the mod resides.
Title: Re: [Tutorial] How to Make a RimWorld Mod, Step by Step
Post by: KetchupAddict on November 21, 2020, 11:11:49 PM
Hey, thanks for the guide! It was very useful!

So currently I am trying to make a similar melee weapon, but instead of applying plague, it will increase its damage if the target has plague. Can somebody help me with it? Mainly on which function I need to override and how to change the weapons damage conditionally.