<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://rimworldwiki.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dninemfive</id>
	<title>RimWorld Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://rimworldwiki.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dninemfive"/>
	<link rel="alternate" type="text/html" href="https://rimworldwiki.com/wiki/Special:Contributions/Dninemfive"/>
	<updated>2026-04-06T05:05:04Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.8</generator>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials&amp;diff=75769</id>
		<title>Modding Tutorials</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials&amp;diff=75769"/>
		<updated>2020-10-20T23:39:46Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Update plague gun link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--Top Nav Box--&amp;gt;&lt;br /&gt;
{| align=center&lt;br /&gt;
| {{Mods_Nav}}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is the table of contents for the modding tutorial. Here, you'll learn step by step how to create mods of gradually increasing complexity.&lt;br /&gt;
&lt;br /&gt;
In light of little official documentation, most of the knowledge here was gained by experience, trial-and-error, decompiling and learning from the source. Keep in mind that RimWorld is a big game that underwent substantial code changes during its alphas. While most of this wiki was updated for 1.0, some information you find may be outdated. &lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
==What's a mod?==&lt;br /&gt;
A mod is a folder containing data the game reads/loads. Mods can add, remove or alter the content of other mods (including the Core mod) in the broadest sense of the word. For more info, see also [[Modding]].&lt;br /&gt;
&lt;br /&gt;
==Introduction to modding==&lt;br /&gt;
# [[Modding Tutorials/First Steps|First Steps and Some Links]]&lt;br /&gt;
# [[Modding Tutorials/Essence| Essence of Modding]]&lt;br /&gt;
# [[Modding Tutorials/Folder structure|Exploring the Folder Structure]]&lt;br /&gt;
# [[Modding Tutorials/Mod folder structure|Mod Folder Structure]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The About folder|About folder]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The Defs folder|Defs folder]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The Source and Assemblies folders|Assemblies folder]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The Languages folder|Languages folder]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The Textures and Sounds folders|Textures folder]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The Textures and Sounds folders|Sounds folder]]&lt;br /&gt;
#* [[Modding Tutorials/Mod folder structure#The Patches folder|Patches folder]]&lt;br /&gt;
# [[Modding Tutorials/Recommended software|Recommended Software]]&lt;br /&gt;
&lt;br /&gt;
==General modding==&lt;br /&gt;
&lt;br /&gt;
* [[Modding Tutorials/Testing mods|Testing Mods]]&lt;br /&gt;
** [[Modding Tutorials/Testing mods#Development mode|Development Mode]]&lt;br /&gt;
* [[Modding Tutorials/Sounds|Adding and Testing Sounds]]&lt;br /&gt;
* [[Modding Tutorials/Assets|Decompiling Texture/Sound Assets]]&lt;br /&gt;
* [[Modding Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
* [[Modding_Tutorials/Distribution|Distribution]]&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Must-knows==&lt;br /&gt;
* [[Modding_Tutorials/Modifying defs|Modifying Defs]]&lt;br /&gt;
* [[Modding_Tutorials/Troubleshooting|Troubleshooting mods]]&lt;br /&gt;
&lt;br /&gt;
==XML tutorials==&lt;br /&gt;
&lt;br /&gt;
# [[Modding Tutorials/XML file structure|XML File Structure]]&lt;br /&gt;
# [[Modding Tutorials/XML Defs|Introduction to XML Defs]]&lt;br /&gt;
#* [[Modding Tutorials/Compatibility with defs|XML Def Compatibility]]&lt;br /&gt;
# In-depth XML Def tutorials&lt;br /&gt;
#* [[Modding Tutorials/ThingDef|ThingDef explained]]&lt;br /&gt;
#* [[Modding Tutorials/Weapons Guns|Weapons_Guns.xml explained]]. Slightly dated.&lt;br /&gt;
# [[Modding Tutorials/PatchOperations|PatchOperations]], replace specific xml elements of core files while keeping the rest untampered. Uses xpath.&lt;br /&gt;
&lt;br /&gt;
==C# tutorials==&lt;br /&gt;
# [[Modding_Tutorials/Setting up a solution|Setting up]]&lt;br /&gt;
# [[Modding_Tutorials/Hello World|Hello World]]&lt;br /&gt;
# [[Modding_Tutorials/Decompiling source code|Decompiling Source Code]]&lt;br /&gt;
# [[Modding_Tutorials/Writing custom code|Writing Custom Code]]&lt;br /&gt;
# [[Modding Tutorials/Linking XML and C#|Linking XML and C#]]&lt;br /&gt;
# [[Modding_Tutorials/Harmony | Alter Code at Runtime with Harmony]] - this is a best practice for modifying game code, replacing C# code injection to reduce Mod Conflicts&lt;br /&gt;
# The wonderful things you will want to do with C#&lt;br /&gt;
#* [[Modding_Tutorials/Modifying classes|Adding fields and methods to classes]]&lt;br /&gt;
# Useful things:&lt;br /&gt;
#* [[Modding Tutorials/ModSettings|Mod settings]] - Add settings to your mod&lt;br /&gt;
#* [[Modding Tutorials/DefModExtension|Def mod extensions]] - Add (custom) fields to Defs&lt;br /&gt;
#* [[Modding Tutorials/Custom Comp Classes|Custom Comp Classes]] - A quick overview of what types of Comps there are, and what they're suited for.&lt;br /&gt;
#** [[Modding_Tutorials/ThingComp|ThingComp]] - Learn all there is to know about ThingComps.&lt;br /&gt;
#** [[Modding Tutorials/GameComponent|Components]] - GameComponents, WorldComponents, and MapComponents&lt;br /&gt;
#* [[Modding_Tutorials/Def classes|Introduction to Def Classes]]&lt;br /&gt;
#* [[Modding_Tutorials/Compatibility_with_DLLs|Using Harmony to optionally patch other mods for the sake of compatibility]]&lt;br /&gt;
#* [[Modding Tutorials/TweakValue|TweakValues]] - Change values on the fly (handy for quick iteration!)&lt;br /&gt;
#* [[Modding Tutorials/ExposeData|ExposeData]] - Save stuff&lt;br /&gt;
#* [[Modding Tutorials/BigAssListOfUsefulClasses|The big ass list of useful classes]] - A non-exhaustive list of classes you'll use most&lt;br /&gt;
#* [[Modding Tutorials/GrammarResolver|Grammar Resolver]] - PAWN_objective, PAWN_possessive? Find out what it all means here.&lt;br /&gt;
#* [https://github.com/Mehni/ExampleJob/wiki ExampleJob] - Mehni's top to bottom breakdown of Jobs.&lt;br /&gt;
&lt;br /&gt;
==Art Tutorials==&lt;br /&gt;
* [https://spdskatr.github.io/RWModdingResources/artstyle Artstyle] - Officially unofficial guide to RimWorld's Artstyle&lt;br /&gt;
* [https://www.reddit.com/r/RimWorld/comments/5tn1pi/rimworldstyle_sprite_tutorials/ Ekksu's guide to creating RimWorld animals]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1114369188 ChickenPlucker's guide to creating apparel]&lt;br /&gt;
* [https://github.com/seraphile/rimshare/wiki/Colouring-in-Images Seraphile's guide to masks]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
==Examples==&lt;br /&gt;
* [[Modding Tutorials/Assembly Modding Example|Assembly Modding]]&lt;br /&gt;
* [[Plague Gun (1.1)|The Plague Gun]] tutorial originally by Jecrell, updated to 1.1+. &lt;br /&gt;
&lt;br /&gt;
===Dangerously Outdated===&lt;br /&gt;
* https://rimworldwiki.com/wiki/Modding_Tutorials/Smelter&lt;br /&gt;
* https://rimworldwiki.com/wiki/Modding_Tutorials/Items&lt;br /&gt;
* https://rimworldwiki.com/wiki/Modding_Tutorials/Weapons&lt;br /&gt;
* [[Plague Gun/Introduction|The Plague Gun]] based on the Plague Gun tutorial by Jecrell, updated for 1.0. {{LudeonThread|33219}}.&lt;br /&gt;
# [[Plague Gun/Required Items|Required Items]]&lt;br /&gt;
# [[Plague Gun/XML Stage|XML Stage]]&lt;br /&gt;
# [[Plague Gun/Connecting XML and Csharp|Connecting XML and C#]]&lt;br /&gt;
# [[Plague Gun/Csharp Assembly Setup|C# Assembly Setup]]&lt;br /&gt;
# [[Plague Gun/Csharp Coding|C# Coding]]&lt;br /&gt;
# [[Plague Gun/Localisation|Localisation]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [https://github.com/roxxploxx/RimWorldModGuide/wiki Roxxploxx's set of modding tutorials]&lt;br /&gt;
* [https://spdskatr.github.io/RWModdingResources/ RimWorld Modding Resources - A hub for guides, modders, practical tips]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;br /&gt;
[[Category:Modding tutorials]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=74896</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=74896"/>
		<updated>2020-09-14T02:07:17Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Delete a single apostrophe&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Introduction to reading Def classes ==&lt;br /&gt;
This article is intended for XML modders who don't want to work with C# (even though it's [[Plague Gun (1.1)|much less imposing than you think]]) but want to know what exactly they can write in their defs.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
'''Fields''' are variables in C# class defintions defined at the top of classes (when decompiled). For example, &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    public class ExampleDef : Def {&lt;br /&gt;
    public bool exampleBool = true;&lt;br /&gt;
    public int exampleInteger = 1;&lt;br /&gt;
    public float exampleFloat = 1.2f;&lt;br /&gt;
    public bool exampleNonInitializedField;&lt;br /&gt;
    public RaceProperties exampleClass;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nodes''' are XML entries, for example &amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ExampleDef ExampleAnnotation=&amp;quot;ExampleValue&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;exampleBool&amp;gt;true&amp;lt;/exampleBool?&lt;br /&gt;
    &amp;lt;exampleInteger&amp;gt;1&amp;lt;/exampleInteger&amp;gt;&lt;br /&gt;
    &amp;lt;exampleFloat&amp;gt;1.2&amp;lt;/exampleFloat&amp;gt;&lt;br /&gt;
    &amp;lt;exampleNonInitializedField&amp;gt;false&amp;lt;/exampleNonInitializedField&amp;gt;&lt;br /&gt;
    &amp;lt;exampleClass&amp;gt;&lt;br /&gt;
        &amp;lt;intelligence&amp;gt;Animal&amp;lt;/intelligence&amp;gt;&lt;br /&gt;
        &amp;lt;fleshType&amp;gt;Mechanoid&amp;lt;/fleshType&amp;gt;&lt;br /&gt;
        &amp;lt;hasGenders&amp;gt;false&amp;lt;/hasGenders&amp;gt;&lt;br /&gt;
    &amp;lt;/exampleClass&amp;gt;&lt;br /&gt;
&amp;lt;/ExampleDef&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== IfModLoaded ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;IfModLoaded&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IfModNotLoaded&amp;lt;/code&amp;gt; attributes in &amp;lt;code&amp;gt;LoadFolders.xml&amp;lt;/code&amp;gt; to conditionally load defs, treating Royalty as a mod.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;loadFolders&amp;gt;&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;/&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li IfModLoaded=&amp;quot;Royalty&amp;quot;&amp;gt;RoyaltyDefs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/default&amp;gt;&lt;br /&gt;
&amp;lt;/loadFolders&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* [O21] Toolbox&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* OgsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=74895</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=74895"/>
		<updated>2020-09-14T01:51:05Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Introduction to reading Def classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Introduction to reading Def classes ==&lt;br /&gt;
This article is intended for XML modders who don't want to work with C# (even though it's [[Plague Gun (1.1)|much less imposing than you think]]) but want to know what exactly they can write in their defs.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
'''Fields'''' are variables in C# class defintions defined at the top of classes (when decompiled). For example, &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    public class ExampleDef : Def {&lt;br /&gt;
    public bool exampleBool = true;&lt;br /&gt;
    public int exampleInteger = 1;&lt;br /&gt;
    public float exampleFloat = 1.2f;&lt;br /&gt;
    public bool exampleNonInitializedField;&lt;br /&gt;
    public RaceProperties exampleClass;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nodes''' are XML entries, for example &amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ExampleDef ExampleAnnotation=&amp;quot;ExampleValue&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;exampleBool&amp;gt;true&amp;lt;/exampleBool?&lt;br /&gt;
    &amp;lt;exampleInteger&amp;gt;1&amp;lt;/exampleInteger&amp;gt;&lt;br /&gt;
    &amp;lt;exampleFloat&amp;gt;1.2&amp;lt;/exampleFloat&amp;gt;&lt;br /&gt;
    &amp;lt;exampleNonInitializedField&amp;gt;false&amp;lt;/exampleNonInitializedField&amp;gt;&lt;br /&gt;
    &amp;lt;exampleClass&amp;gt;&lt;br /&gt;
        &amp;lt;intelligence&amp;gt;Animal&amp;lt;/intelligence&amp;gt;&lt;br /&gt;
        &amp;lt;fleshType&amp;gt;Mechanoid&amp;lt;/fleshType&amp;gt;&lt;br /&gt;
        &amp;lt;hasGenders&amp;gt;false&amp;lt;/hasGenders&amp;gt;&lt;br /&gt;
    &amp;lt;/exampleClass&amp;gt;&lt;br /&gt;
&amp;lt;/ExampleDef&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== IfModLoaded ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;IfModLoaded&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IfModNotLoaded&amp;lt;/code&amp;gt; attributes in &amp;lt;code&amp;gt;LoadFolders.xml&amp;lt;/code&amp;gt; to conditionally load defs, treating Royalty as a mod.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;loadFolders&amp;gt;&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;/&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li IfModLoaded=&amp;quot;Royalty&amp;quot;&amp;gt;RoyaltyDefs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/default&amp;gt;&lt;br /&gt;
&amp;lt;/loadFolders&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* [O21] Toolbox&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* OgsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=74894</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=74894"/>
		<updated>2020-09-14T00:17:14Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Add IfModLoaded&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Introduction to reading Def classes ==&lt;br /&gt;
This article is intended for XML modders who don't want to work with C# (even though it's [[Modding Tutorials/Plague Gun (1.1)|much less imposing than you think]]) but want to know what exactly they can write in their defs.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
'''Fields'''' are variables in C# class defintions defined at the top of classes (when decompiled). For example, &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    public class ExampleDef : Def {&lt;br /&gt;
    public bool exampleBool = true;&lt;br /&gt;
    public int exampleInteger = 1;&lt;br /&gt;
    public float exampleFloat = 1.2f;&lt;br /&gt;
    public bool exampleNonInitializedField;&lt;br /&gt;
    public RaceProperties exampleClass;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nodes''' are XML entries, for example &amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ExampleDef ExampleAnnotation=&amp;quot;ExampleValue&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;exampleBool&amp;gt;true&amp;lt;/exampleBool?&lt;br /&gt;
    &amp;lt;exampleInteger&amp;gt;1&amp;lt;/exampleInteger&amp;gt;&lt;br /&gt;
    &amp;lt;exampleFloat&amp;gt;1.2&amp;lt;/exampleFloat&amp;gt;&lt;br /&gt;
    &amp;lt;exampleNonInitializedField&amp;gt;false&amp;lt;/exampleNonInitializedField&amp;gt;&lt;br /&gt;
    &amp;lt;exampleClass&amp;gt;&lt;br /&gt;
        &amp;lt;intelligence&amp;gt;Animal&amp;lt;/intelligence&amp;gt;&lt;br /&gt;
        &amp;lt;fleshType&amp;gt;Mechanoid&amp;lt;/fleshType&amp;gt;&lt;br /&gt;
        &amp;lt;hasGenders&amp;gt;false&amp;lt;/hasGenders&amp;gt;&lt;br /&gt;
    &amp;lt;/exampleClass&amp;gt;&lt;br /&gt;
&amp;lt;/ExampleDef&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== IfModLoaded ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;IfModLoaded&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IfModNotLoaded&amp;lt;/code&amp;gt; attributes in &amp;lt;code&amp;gt;LoadFolders.xml&amp;lt;/code&amp;gt; to conditionally load defs, treating Royalty as a mod.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;loadFolders&amp;gt;&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;/&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li IfModLoaded=&amp;quot;Royalty&amp;quot;&amp;gt;RoyaltyDefs&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/default&amp;gt;&lt;br /&gt;
&amp;lt;/loadFolders&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* [O21] Toolbox&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* OgsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Recommended_software&amp;diff=74495</id>
		<title>Modding Tutorials/Recommended software</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Recommended_software&amp;diff=74495"/>
		<updated>2020-09-02T06:32:08Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: update .NET version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{BackToTutorials}}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=What you'll learn=&lt;br /&gt;
&lt;br /&gt;
This tutorial lists a few programs you could use to edit XML and C# code.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=XML Code Editors=&lt;br /&gt;
&lt;br /&gt;
===Basic Editors===&lt;br /&gt;
&lt;br /&gt;
Just about any text editor can write XML code, but some are better suited than others. Rich text editors (WordPad, anything part of any Office suite) should be avoided. Windows' simple notepad will work, but you'll want something which offers things like &amp;quot;Find in Files&amp;quot; functionality and syntax highlighting. If you're even somewhat serious about modding, the following software will help you immensely:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Software !! OS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepadqq.com/s/ NotepadQQ] || Linux || Notepadqq is a Notepad++-like editor for the Linux desktop so has the exact same UI and functions as Notepad++&lt;br /&gt;
|-&lt;br /&gt;
| [http://notepad-plus-plus.org/download/ Notepad++] || Windows || Light-weight editor with extension support.&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.sublimetext.com/ Sublime Text] || Linux/Windows/Mac || Natively supports many programming languages and markup languages, and its functionality can be extended by users with plugins - A brief overview of its functionality can be found [http://webdesign.tutsplus.com/tutorials/useful-shortcuts-for-a-faster-workflow-in-sublime-text-3--cms-22185 here] and a full course [http://code.tutsplus.com/courses/perfect-workflow-in-sublime-text-2 here]&lt;br /&gt;
|-&lt;br /&gt;
| [https://atom.io/ Atom] || Linux/Windows/Mac || A hackable electron-based text editor with emphasis on extensions and GitHub collaboration.&lt;br /&gt;
|-&lt;br /&gt;
| [https://code.visualstudio.com/ Visual Studio Code] || Linux/Windows/Mac || A text editor with emphasis on productivity and extension support.&lt;br /&gt;
|-&lt;br /&gt;
| [http://xmlnotepad.codeplex.com/releases/ XML Notepad] || Windows || XML-oriented editor with a lot of features you will most likely never use in Rimworld modding&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.geany.org/ Geany] || Linux/Windows/Mac || Extremely lightweight text editor with syntax highlighting and some other basic features oriented towards XML and code editing.&lt;br /&gt;
|}&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Advanced Editors===&lt;br /&gt;
&lt;br /&gt;
There's many editors out there specifically made for XML code. Because Rimworld uses XML in a very simple way, advanced code editors are rarely needed. In case you're ever in need of one, however, the following ones might help:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Software !! OS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [http://sourceforge.net/projects/xpontus/files/ XPontus] || Windows || Has a tree view and is capable of checking XML for errors, fixing tabs and creating schema's detailing every tag's data types&lt;br /&gt;
|-&lt;br /&gt;
| [http://xmlgrid.net/ XMLGrid] || - || Capable of validating XML and turning it into Excel Spreadsheets, XSD Charts and an online table detailing each tag of a certain type and its contents&lt;br /&gt;
|-&lt;br /&gt;
| [http://codebeautify.org/xmlviewer Codebeautify's xmlviewer] || - || Can display as a tree view, automatically format/indent your code and can validate and show errors too. Also have a function share code (like [http://codebeautify.org/xmlviewer/b39586 that])&lt;br /&gt;
|}&amp;lt;br/&amp;gt;&lt;br /&gt;
An alternative to &amp;quot;Advanced editors&amp;quot; are plugins/extensions. Good extensions can highlight syntax (if not already standard), format XML, find xpath, auto-close XML tags, supports renaming tags, and more.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=IDEs=&lt;br /&gt;
&lt;br /&gt;
C# code is best edited in an IDE (Integrated Development Environment) to make the process of editing code, managing a solution's content and compiling its projects both easier and faster. Any IDE for C# will probably work just fine, so here's a list of suggested editors:&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Software !! OS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.visualstudio.com/ Visual Studio] || Windows || Very extensive IDE with paid, trial and free versions. Any of these versions will probably work, so you might as well take [https://www.visualstudio.com/products/visual-studio-community-vs Visual Studio Community] which is free for individuals and small teams. Always the most up-to-date&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.icsharpcode.net/OpenSource/SD/Download/ SharpDevelop] || Windows || Free IDE specifically made for C#&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.monodevelop.com/download/ MonoDevelop] || Linux/Windows/Mac || Free, cross-platform IDE with customizable user interface. Has support for C# as well as some other languages you won't need for Rimworld&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.xamarin.com/platform Xamarin] || Mac || It's free but you need to register to download it. Probably your best option on a mac.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''For Linux users:''' See also [https://ludeon.com/forums/index.php?topic=46775.0 this thread] about working with C# on ArchLinux - it may be useful.&lt;br /&gt;
&lt;br /&gt;
Whichever IDE you choose, make sure it's capable of compiling for .NET Framework 4.7.2. If you for whatever reason don't have this framework installed, you can download it [https://dotnet.microsoft.com/download/dotnet-framework/net472 here].&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional C# Software=&lt;br /&gt;
&lt;br /&gt;
Besides your IDE it's strongly recommended to install the following software for decompiling:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Software !! OS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy dnSpy] || Windows || Software which is capable of [[Modding Tutorials/Decompiling source code|decompiling source code]], which is very useful in Rimworld modding (some authors have had better luck with dnSpy than ILSpy?)&lt;br /&gt;
|-&lt;br /&gt;
| [http://ilspy.net/ ILSpy] || Windows || Software which is capable of [[Modding Tutorials/Decompiling source code|decompiling source code]], which is very useful in Rimworld modding&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.monodevelop.com/download/ MonoDevelop] || Linux/Windows/Mac || The Linux version of the software has an integrated decompiler for .DLLs&lt;br /&gt;
|}&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Graphics Software=&lt;br /&gt;
&lt;br /&gt;
For making textures you will need graphics software. Any image editing program should work, and if you have an alternative to the following links that's probably okay:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Software !! OS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.photofiltre-studio.com/download-en.htm Photofiltre Studio] || Windows || Functional software with very little user interface clutter for its applications. Doesn't support pen tablet, and has a 100% free (non-trial) version called [http://photofiltre.free.fr/download_en.htm Photofiltre]&lt;br /&gt;
|-&lt;br /&gt;
| [http://inkscape.org/en/download/ Inkscape] || Linux/Windows/Mac || Free vector graphic program with a steeper learning curve due to the vector based image editing. Vector graphics can look better than bitmap graphics in Rimworld&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.photoshop.com/products Photoshop] || Windows/Mac || Paid software with a trial version. Rimworld's original graphics are made in Photoshop (they're .PSD files)&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.gimp.org/ Gimp] || Linux/Windows/Mac || A free, open-source alternative to Photoshop that's been around since 1998. Gimp has a large user community, with great list of [http://www.gimp.org/tutorials/ tutorials] on the official sites&lt;br /&gt;
|-&lt;br /&gt;
| [https://krita.org/en/homepage/ Krita] || Linux/Windows/Mac || A free digital painting software. Better suited than GIMP for painting and should feel like home pretty quick for Photoshop users.&lt;br /&gt;
|}&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Audio Software=&lt;br /&gt;
&lt;br /&gt;
Recording your own audio for mods might be too much to ask, but editing audio is always possible. This can be done with the following software or your own alternative:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Software !! OS !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [http://sourceforge.net/projects/audacity/ Audacity] || Linux/Windows/Mac || Audio editing software with many tutorials online, lots of useful functionality and a relatively readable interface&lt;br /&gt;
|}&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Next up=&lt;br /&gt;
&lt;br /&gt;
# [[Modding Tutorials/XML file structure|XML File Structure]] starts you off with the XML side of modding.&lt;br /&gt;
# [[Modding_Tutorials/Setting up a solution|Setting up]] starts you off with the C# side of modding. Knowledge of the XML part can and will be very useful.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding tutorials]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=73228</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=73228"/>
		<updated>2020-08-05T05:34:02Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Sandbox */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Introduction to reading Def classes ==&lt;br /&gt;
This article is intended for XML modders who don't want to work with C# (even though it's [[Modding Tutorials/Plague Gun (1.1)|much less imposing than you think]]) but want to know what exactly they can write in their defs.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
'''Fields'''' are variables in C# class defintions defined at the top of classes (when decompiled). For example, &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    public class ExampleDef : Def {&lt;br /&gt;
    public bool exampleBool = true;&lt;br /&gt;
    public int exampleInteger = 1;&lt;br /&gt;
    public float exampleFloat = 1.2f;&lt;br /&gt;
    public bool exampleNonInitializedField;&lt;br /&gt;
    public RaceProperties exampleClass;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nodes''' are XML entries, for example &amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ExampleDef ExampleAnnotation=&amp;quot;ExampleValue&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;exampleBool&amp;gt;true&amp;lt;/exampleBool?&lt;br /&gt;
    &amp;lt;exampleInteger&amp;gt;1&amp;lt;/exampleInteger&amp;gt;&lt;br /&gt;
    &amp;lt;exampleFloat&amp;gt;1.2&amp;lt;/exampleFloat&amp;gt;&lt;br /&gt;
    &amp;lt;exampleNonInitializedField&amp;gt;false&amp;lt;/exampleNonInitializedField&amp;gt;&lt;br /&gt;
    &amp;lt;exampleClass&amp;gt;&lt;br /&gt;
        &amp;lt;intelligence&amp;gt;Animal&amp;lt;/intelligence&amp;gt;&lt;br /&gt;
        &amp;lt;fleshType&amp;gt;Mechanoid&amp;lt;/fleshType&amp;gt;&lt;br /&gt;
        &amp;lt;hasGenders&amp;gt;false&amp;lt;/hasGenders&amp;gt;&lt;br /&gt;
    &amp;lt;/exampleClass&amp;gt;&lt;br /&gt;
&amp;lt;/ExampleDef&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* [O21] Toolbox&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* OgsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=73110</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=73110"/>
		<updated>2020-07-26T06:29:47Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: fix INCREDIBLY INCORRECT lack of newlines&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community Edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Code you write on your own should not look like this - for one thing, it should be well-commented so that others (even if it's just you in the future) know exactly what you're trying to do and how you're doing it. The code [https://github.com/dninemfive/PlagueGun/blob/master/PlagueGun/Projectile_PlagueBullet.cs in the repo] is probably over-commented and designed for a general audience but I recommend reviewing it.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/UTaMDWc Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=73109</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=73109"/>
		<updated>2020-07-26T06:27:35Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: fix EXTREMELY GLARING typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community Edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Code you write on your own should not look like this - for one thing, it should be well-commented so that others (even if it's just you in the future) know exactly what you're trying to do and how you're doing it. The code [https://github.com/dninemfive/PlagueGun/blob/master/PlagueGun/Projectile_PlagueBullet.cs in the repo] is probably over-commented and designed for a general audience but I recommend reviewing it.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/UTaMDWc Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=73079</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=73079"/>
		<updated>2020-07-20T22:12:40Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Framework Mods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Introduction to reading Def classes ==&lt;br /&gt;
This article is intended for XML modders who don't want to work with C# (even though it's [[Modding Tutorials/Plague Gun (1.1)|much less imposing than you think]]) but want to know what exactly they can write in their defs.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
'''Fields'''' are variables in C# class defintions defined at the top of classes (when decompiled). For example, &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    public class ExampleDef : Def {&lt;br /&gt;
    public bool exampleBool = true;&lt;br /&gt;
    public int exampleInteger = 1;&lt;br /&gt;
    public float exampleFloat = 1.2f;&lt;br /&gt;
    public bool exampleNonInitializedField;&lt;br /&gt;
    public RaceProperties exampleClass;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nodes''' are XML entries, for example &amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ExampleDef ExampleAnnotation=&amp;quot;ExampleValue&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;exampleBool&amp;gt;true&amp;lt;/exampleBool?&lt;br /&gt;
    &amp;lt;exampleInteger&amp;gt;1&amp;lt;/exampleInteger&amp;gt;&lt;br /&gt;
    &amp;lt;exampleFloat&amp;gt;1.2&amp;lt;/exampleFloat&amp;gt;&lt;br /&gt;
    &amp;lt;exampleNonInitializedField&amp;gt;false&amp;lt;/exampleNonInitializedField&amp;gt;&lt;br /&gt;
    &amp;lt;exampleClass&amp;gt;&lt;br /&gt;
        &amp;lt;intelligence&amp;gt;Animal&amp;lt;/intelligence&amp;gt;&lt;br /&gt;
        &amp;lt;fleshType&amp;gt;Mechanoid&amp;lt;/fleshType&amp;gt;&lt;br /&gt;
        &amp;lt;hasGenders&amp;gt;false&amp;lt;/hasGenders&amp;gt;&lt;br /&gt;
    &amp;lt;/exampleClass&amp;gt;&lt;br /&gt;
&amp;lt;/ExampleDef&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* OgsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=73060</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=73060"/>
		<updated>2020-07-16T23:35:45Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Sandbox */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Introduction to reading Def classes ==&lt;br /&gt;
This article is intended for XML modders who don't want to work with C# (even though it's [[Modding Tutorials/Plague Gun (1.1)|much less imposing than you think]]) but want to know what exactly they can write in their defs.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
'''Fields'''' are variables in C# class defintions defined at the top of classes (when decompiled). For example, &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    public class ExampleDef : Def {&lt;br /&gt;
    public bool exampleBool = true;&lt;br /&gt;
    public int exampleInteger = 1;&lt;br /&gt;
    public float exampleFloat = 1.2f;&lt;br /&gt;
    public bool exampleNonInitializedField;&lt;br /&gt;
    public RaceProperties exampleClass;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Nodes''' are XML entries, for example &amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ExampleDef ExampleAnnotation=&amp;quot;ExampleValue&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;exampleBool&amp;gt;true&amp;lt;/exampleBool?&lt;br /&gt;
    &amp;lt;exampleInteger&amp;gt;1&amp;lt;/exampleInteger&amp;gt;&lt;br /&gt;
    &amp;lt;exampleFloat&amp;gt;1.2&amp;lt;/exampleFloat&amp;gt;&lt;br /&gt;
    &amp;lt;exampleNonInitializedField&amp;gt;false&amp;lt;/exampleNonInitializedField&amp;gt;&lt;br /&gt;
    &amp;lt;exampleClass&amp;gt;&lt;br /&gt;
        &amp;lt;intelligence&amp;gt;Animal&amp;lt;/intelligence&amp;gt;&lt;br /&gt;
        &amp;lt;fleshType&amp;gt;Mechanoid&amp;lt;/fleshType&amp;gt;&lt;br /&gt;
        &amp;lt;hasGenders&amp;gt;false&amp;lt;/hasGenders&amp;gt;&lt;br /&gt;
    &amp;lt;/exampleClass&amp;gt;&lt;br /&gt;
&amp;lt;/ExampleDef&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72957</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72957"/>
		<updated>2020-07-07T03:40:45Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Framework Mods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* Advanced Animal Frameworks&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72956</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72956"/>
		<updated>2020-07-06T16:35:45Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Royalty compatibility */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other Options ===&lt;br /&gt;
If you set your mod to require [https://github.com/dninemfive/d9framework D9 Framework], you can use &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; (with the packageId &amp;lt;code&amp;gt;Ludeon.RimWorld.Royalty&amp;lt;/code&amp;gt;) or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt; to check whether Royalty is installed, with the former checking whether it's enabled and the latter checking if the user owns it. Using the vanilla &amp;lt;code&amp;gt;PatchOperationFindMod&amp;lt;/code&amp;gt; would not be sufficient because it would be enabled if any local mod was called Royalty.&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72954</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72954"/>
		<updated>2020-07-05T22:31:05Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Framework Mods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other ===&lt;br /&gt;
D9 Framework: &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
* Universal Fermenter&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72953</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72953"/>
		<updated>2020-07-05T22:29:06Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Sandbox */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other ===&lt;br /&gt;
D9 Framework: &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Framework Mods ==&lt;br /&gt;
''intended to be a comprehensive list of mods which add features for XML users''&lt;br /&gt;
* BiomesKit&lt;br /&gt;
* D9 Framework&lt;br /&gt;
* HugsLib ''(I think)''&lt;br /&gt;
* JecsTools&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72952</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72952"/>
		<updated>2020-07-05T22:24:55Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Royalty compatibility */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
#* The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other ===&lt;br /&gt;
D9 Framework: &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72951</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72951"/>
		<updated>2020-07-05T22:24:45Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Royalty compatibility */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
After the release of Royalty, mods are governed by rules 13b and c of the [https://ludeon.com/forums/index.php?topic=40838.0 Ludeon community rules]. Unfortunately, these are inconsistently applied and end up being vaguer than intended, but a good TL;DR to follow would be:&lt;br /&gt;
# Don't use any code flagged as Royalty only. They will throw errors when loaded for people without Royalty, so these are easy to tell.&lt;br /&gt;
  * The page lists explicit exceptions; at the time of writing, only gendered apparel and &amp;lt;code&amp;gt;Sketch&amp;lt;/code&amp;gt;es are exempt.&lt;br /&gt;
# Avoid using features added in 1.1 or later. Unfortunately, not all Royalty-specific code is flagged and it's ambiguous whether some features are permitted.&lt;br /&gt;
# Avoid making anything included in Royalty, broadly defined. Another unfortunate ambiguity is the nuance in this rule - it's currently unclear whether some Royalty features, like shield projectors, count as &amp;quot;royalty features&amp;quot; for this purpose as old mods which included them have not been banned but no new ones have yet been made.&lt;br /&gt;
# If in doubt, set your mod to require Royalty to install on Steam, and you'll be fine.&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;MayRequire&amp;lt;/code&amp;gt; annotation on XML nodes to disable Royalty-specific features when Royalty is not installed.&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
In C#, the canonical check for whether Royalty is installed is &amp;lt;code&amp;gt;ModLister.RoyaltyInstalled&amp;lt;/code&amp;gt;. Notably, this check whether the Steam user ''owns'' Royalty, rather than whether it's enabled in the load order.&lt;br /&gt;
=== Other ===&lt;br /&gt;
D9 Framework: &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72950</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72950"/>
		<updated>2020-07-05T22:15:42Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Royalty compatibility */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
=== Other ===&lt;br /&gt;
D9 Framework: &amp;lt;code&amp;gt;PatchOperationFindPackage&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PatchOperationRoyaltyInstalled&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72949</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72949"/>
		<updated>2020-07-05T22:15:15Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Sandbox */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Royalty compatibility ==&lt;br /&gt;
&lt;br /&gt;
=== MayRequire ===&lt;br /&gt;
=== ModLister.RoyaltyInstalled ===&lt;br /&gt;
=== Other ===&lt;br /&gt;
D9 Framework: [code]PatchOperationFindPackage[/code] or [code]PatchOperationRoyaltyInstalled[/code]&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72777</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72777"/>
		<updated>2020-07-01T04:05:49Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: fix Discord invite&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community Edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Code you write on your own should not look like this - for one thing, it should be well-commented so that others (even if it's just you in the future) know exactly what you're trying to do and how you're doing it. The code [https://github.com/dninemfive/PlagueGun/blob/master/PlagueGun/Projectile_PlagueBullet.cs in the repo] is probably over-commented and designed for a general audience but I recommend reviewing it.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/UTaMDWc Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72621</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72621"/>
		<updated>2020-06-27T21:48:37Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Version Control Intro ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72620</id>
		<title>User:Dninemfive</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=User:Dninemfive&amp;diff=72620"/>
		<updated>2020-06-27T21:48:20Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Sandbox */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello! I'm a modder who's trying to clean up the modding tutorials pages, which are quite out-of-date. So far, I've [[Plague Gun (1.1)|rewritten]] the classic [[Plague Gun/Introduction|Plague Gun tutorial]].&lt;br /&gt;
&lt;br /&gt;
If you've been helped by my contributions on this site please check out my mods on [https://github.com/users/dninemfive/projects/1 Github] and [https://steamcommunity.com/id/dninemfive/myworkshopfiles/?appid=294100 Steam].&lt;br /&gt;
&lt;br /&gt;
= Sandbox =&lt;br /&gt;
&lt;br /&gt;
== Version Control Into ==&lt;br /&gt;
&lt;br /&gt;
An introduction to using Github for version control, with an eye toward Rimworld modding. Will go through my particular setup, and various tips and tricks, like:&lt;br /&gt;
* Having a separate dev folder from the Rimworld mods folder&lt;br /&gt;
* Build events copying from the dev folder into the build folder&lt;br /&gt;
* .gitignore settings&lt;br /&gt;
&amp;amp;c&lt;br /&gt;
&lt;br /&gt;
== Example Comp Project ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use &amp;lt;code&amp;gt;ThingComp&amp;lt;/code&amp;gt;s, load textures in C#, and make gizmos.&lt;br /&gt;
&lt;br /&gt;
== Introduction to core mods ==&lt;br /&gt;
&lt;br /&gt;
This project will teach players how to use basic Harmony patches and demonstrate the use of &amp;lt;code&amp;gt;MapComponent&amp;lt;/code&amp;gt;s (or maybe game/world ones, idk)&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72617</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72617"/>
		<updated>2020-06-27T06:10:35Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: capitalize&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community Edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Code you write on your own should not look like this - for one thing, it should be well-commented so that others (even if it's just you in the future) know exactly what you're trying to do and how you're doing it. The code [https://github.com/dninemfive/PlagueGun/blob/master/PlagueGun/Projectile_PlagueBullet.cs in the repo] is probably over-commented and designed for a general audience but I recommend reviewing it.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Setting_up_a_solution&amp;diff=72616</id>
		<title>Modding Tutorials/Setting up a solution</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Setting_up_a_solution&amp;diff=72616"/>
		<updated>2020-06-27T06:07:47Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: 3.5 -&amp;gt; 4.7.2 (and remove reference to it being ancient)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{BackToTutorials}}&lt;br /&gt;
{{Credit|[[User:Alistaire|Alistaire]]}}&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn how to set up a solution, along with instructions on setting the output directory and files for more convenient building right into the Assemblies folder.&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&lt;br /&gt;
* The manual option in this tutorial requires you to have [[Modding_Tutorials/Mod_folder_structure#The Source and Assemblies folders|set up a Source and Assemblies folder]] (the Visual Studio automatic option sets this up for you).&lt;br /&gt;
* You will want to have an IDE installed: [[Modding Tutorials/Recommended software#IDE's|Recommended IDE's]].&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Setting up a solution=&lt;br /&gt;
Setting up can be different for different IDE's. Feel free to add '''''complete''''' instructions for your IDE of choice.&lt;br /&gt;
&lt;br /&gt;
===Visual Studio Community 2017===&lt;br /&gt;
''NOTE: Visual Studio 2017 is a rather heavy application (2-3 GB for basic functionality) but has a bit more functionality. Only Install if your computer can handle it! The tutorial is similar for Visual Studio 2015.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Option 1 (Manual Method):====&lt;br /&gt;
# Create a new class library project&lt;br /&gt;
## Once loaded, go to File -&amp;gt; New -&amp;gt; Project...&lt;br /&gt;
## Go to Templates -&amp;gt; Visual C# -&amp;gt; Class Library (Be sure to select the *.NET Framework* version, not *.NET Standard*) [[File:Capture.png|200px|thumb|right|Installing the .NET framework]]&lt;br /&gt;
## Enter your name and solution name in the lower pane.&lt;br /&gt;
## Choose a location, preferably:&amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;(RimWorldInstallFolder)/Mods/(YourModName)/Source&amp;lt;/pre&amp;gt;&lt;br /&gt;
## ''Optional'': Untick &amp;quot;Create directory for solution&amp;quot;&lt;br /&gt;
# In your project, set target framework and various other porperties&lt;br /&gt;
## In your Solution Explorer, right click your project -&amp;gt; Properties&lt;br /&gt;
## Once in your properties, select Application -&amp;gt; Set Target Framework to .NET Framework 4.7.2 (No client profile)&lt;br /&gt;
## ''Optional'': Change your Assembly and Namespace names to anything of your choice&lt;br /&gt;
## Go to Build -&amp;gt; Advanced... and set &amp;quot;Debugging information&amp;quot; to none&lt;br /&gt;
## Leave Advanced..., and set the Output Path to &amp;quot;..\..\Assemblies\&amp;quot; (The Assemblies folder in your mod folder)&lt;br /&gt;
# Add references to RimWorld code&lt;br /&gt;
## Expand your project. Then right click &amp;quot;References&amp;quot; -&amp;gt; Add Reference...&lt;br /&gt;
## Click Browse...&lt;br /&gt;
## Navigate towards &amp;lt;pre&amp;gt;RimWorld******/RimWorld******_Data/Managed&amp;lt;/pre&amp;gt; and select files: &amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;Assembly-CSharp.dll&amp;amp;#10;UnityEngine.dll&amp;lt;/pre&amp;gt;&lt;br /&gt;
## Click &amp;quot;Add&amp;quot;&lt;br /&gt;
## Click &amp;quot;OK&amp;quot; to close the Reference Manager.&lt;br /&gt;
## Right click on both Assembly-CSharp.dll and UnityEngine.dll and set Copy Local to False (Properties pane).&lt;br /&gt;
&lt;br /&gt;
====Option 2 (Automatic Method):====&lt;br /&gt;
This option uses the [https://ludeon.com/forums/index.php?topic=39038.0 Rimworld Mod Development Cookiecutter] tool.&amp;lt;/br&amp;gt;&lt;br /&gt;
'''Note: despite being automatic and potentially taking away some of the tedium away, the environment it sets up is very particular and this tool is currently not recommended for newcomers.'''&amp;lt;/br&amp;gt;&lt;br /&gt;
''As of Jan 2019, the cookiecutter is set up for Windows development.  Linux/Mac people can still use it, but they will have a few errors to clean up.''&amp;lt;/br&amp;gt;&lt;br /&gt;
# Open Visual Studio&lt;br /&gt;
# Once loaded, go to File -&amp;gt; New -&amp;gt; From Cookiecutter...&lt;br /&gt;
# Search for ''rimworld''&lt;br /&gt;
# Double-click ''cookiecutter-rimworld-mod-development''&lt;br /&gt;
# Change the Template Options:&lt;br /&gt;
## ''Create To'' =&amp;gt; ''Your/Rimworld/Mod/Directory''&lt;br /&gt;
## ''mod_name''&lt;br /&gt;
## ''namespace_name'' (don't change if unsure)&lt;br /&gt;
## ''author'' =&amp;gt; ''your steam username''&lt;br /&gt;
## ''target_version'' =&amp;gt; current RW version (can leave blank for most up-to-date)&lt;br /&gt;
## ''in_game_description'' (not required, can change later in About-Release.xml)&lt;br /&gt;
## ''url'' (can leave blank for link to your Steam Workshop profile)&lt;br /&gt;
# Click &amp;quot;Create and Open Folder&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Sharpdevelop===&lt;br /&gt;
'''Caution:''' Sharpdevelop (or #develop) does NOT CURRENTLY allow for C# 6.0+ syntax without plugins and does NOT ALLOW for C# 7.0+ syntax at all. For your average project this does not matter, however some existing projects are already built entirely upon C# 6.0+ syntax which can not be compiled anymore in Sharpdevelop. Visual Studio does not have these issues and should be your go-to for compiling large projects such as Combat Extended.&lt;br /&gt;
&lt;br /&gt;
# Create a new class library project in your [[Modding Tutorials/Recommended software#IDE.27s|IDE of choice]];&lt;br /&gt;
## Go to File -&amp;gt; New -&amp;gt; Solution;&lt;br /&gt;
## Go to C# or .NET -&amp;gt; Library or Class Library (NOT portable);&lt;br /&gt;
## Enter a project name (solution name automatically updated);&lt;br /&gt;
## Choose a location, preferably:&amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;(RimWorldInstallFolder)/Mods/(YourModName)/Source&amp;lt;/pre&amp;gt;&lt;br /&gt;
## ''Optional'': Untick &amp;quot;Create a directory for solution&amp;quot;/&amp;quot;Create a project within the solution directory&amp;quot;,&lt;br /&gt;
# In your project, add references to Assembly-CSharp.dll and UnityEngine.dll:&lt;br /&gt;
## In your IDE project file browser, right-click the &amp;quot;References&amp;quot; folder and &amp;quot;Add reference&amp;quot;;&lt;br /&gt;
## Choose the &amp;quot;.NET Assembly Browser&amp;quot; tab and &amp;quot;Browse...&amp;quot;;&lt;br /&gt;
## Navigate towards &amp;lt;pre&amp;gt;RimWorld******/RimWorld******_Data/Managed&amp;lt;/pre&amp;gt; and select files: &amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;Assembly-CSharp.dll&amp;amp;#10;UnityEngine.dll&amp;lt;/pre&amp;gt;&lt;br /&gt;
## Click &amp;quot;Open&amp;quot; then &amp;quot;OK&amp;quot;;&lt;br /&gt;
## In the References folder, right-click Assembly-CSharp -&amp;gt; Properties and change &amp;quot;Local copy&amp;quot; to False. Do the same for UnityEngine,&lt;br /&gt;
# In your project properties, change the target framework to .NET 4.7.2:&lt;br /&gt;
## In your IDE project file browser, right-click &amp;quot;(YourSolutionName)&amp;quot;;&lt;br /&gt;
## Choose Properties;&lt;br /&gt;
## Go to the &amp;quot;Compiling&amp;quot; tab, &amp;quot;Output&amp;quot;, &amp;quot;Target framework&amp;quot;, &amp;quot;Change&amp;quot; and choose &amp;quot;.NET Framework 4.7.2&amp;quot;,&lt;br /&gt;
# In your project properties, change the build events so only a single file is built:&lt;br /&gt;
## Go to the &amp;quot;Compiling&amp;quot; tab, &amp;quot;Output&amp;quot;, &amp;quot;Debug info&amp;quot; and choose &amp;quot;No debug information&amp;quot;;&lt;br /&gt;
## Right-click your .cs files -&amp;gt; Properties and change &amp;quot;Copy to output&amp;quot; (If you haven't resized the properties bar, this will be truncated to &amp;quot;Copy to out&amp;quot;) to Never,&lt;br /&gt;
# In your project properties, fix the output location to put the DLL in the Assemblies folder:&lt;br /&gt;
## Go to the &amp;quot;Compiling&amp;quot; tab, &amp;quot;Output&amp;quot;, &amp;quot;Output path&amp;quot; and change the output path to &amp;quot;..\..\Assemblies\&amp;quot;.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Xamarin/MonoDevelop===&lt;br /&gt;
The setup is similar as the one above. A few special points to address:&lt;br /&gt;
# Mono 4.X isn't backward compatible so you may need to install an older 3.X version of Mono in order to compile against .NET4.7.2 dlls.&lt;br /&gt;
# Make sure you uncheck &amp;quot;Use MSBuild build engine (recommended for this project type)&amp;quot; under project &amp;gt; options &amp;gt; build &amp;gt; general   (You might find this by right-clicking on your project - not solution - name and selecting options)&lt;br /&gt;
# Changing the framework to 4.7.2 can be found (for Linux anyway) in the same place.&lt;br /&gt;
&lt;br /&gt;
More detailed installation instructions for Linux can be found [https://blog.rubenwardy.com/2016/07/21/rimworld-setup-monodevelop/ here] and [https://spdskatr.github.io/RWModdingResources/mono-arch here].&lt;br /&gt;
&lt;br /&gt;
===Rider (good for Mac)===&lt;br /&gt;
JetBrains Rider is a great cross-platform C# IDE, but it isn't cheap. It's $140 for the first year, including perpetual access to that version (access to future updates gets cheaper, but it's still over $100/year). However, the Early Access versions are a bit unstable but free. They also offer free student licenses.&lt;br /&gt;
&lt;br /&gt;
# Open Rider and click New Solution in the welcome dialog.&lt;br /&gt;
## Click Class Library under .NET on the left. The option may a second to show up.&lt;br /&gt;
## Under Solution Name (and Project Name), enter the name of your mod.&lt;br /&gt;
## Set the Solution Directory to [your mod folder]/Source.&lt;br /&gt;
## Optionally check &amp;quot;put solution and project in the same directory.&amp;quot; This is probably a good idea.&lt;br /&gt;
## Change Framework to .Net Framework 4.7.2.&lt;br /&gt;
## Click Create.&lt;br /&gt;
# In the left side bar, expand your solution, right click your project (mod name with &amp;quot;C#&amp;quot; icon) and click Properties.&lt;br /&gt;
## In the Properties window, select Configurations &amp;gt; Debug on the left and uncheck Debug Symbols.&lt;br /&gt;
## For both configurations, change the Output Path to ../../Assemblies.&lt;br /&gt;
## Click OK.&lt;br /&gt;
# Expand your project, right click References and click Add Reference.&lt;br /&gt;
## Click Add From.&lt;br /&gt;
## Browse to the folder with the RimWorld DLLs (Mac: /Users/[username]/Library/Application Support/Steam/steamapps/common/RimWorld/RimWorldMac.app/Contents/Resources/Data/Managed).&lt;br /&gt;
## Select both Assembly-CSharp.dll and UnityEngine.dll and click OK.&lt;br /&gt;
## Expand Assemblies under References. For both of the assemblies that you just added:&lt;br /&gt;
### Right click the assembly and click Properties.&lt;br /&gt;
### Uncheck &amp;quot;Copy Local&amp;quot; (you may need to scroll down) and click OK.&lt;br /&gt;
&lt;br /&gt;
You're done! Note that Rider has a built-in decompiler—to view the source of a RimWorld class or method, just right-click its name and click Go To &amp;gt; Definition.&lt;br /&gt;
&lt;br /&gt;
=Common issues=&lt;br /&gt;
* Can't find the option to target .NET Framework 4.7.2? It may require additional installation steps. In Visual Studio, Tools =&amp;gt; Get Tools and features =&amp;gt; Individual Components =&amp;gt; Select ''.NET Framework 4.7.2 development tools'' (or google installation instructions). Also make sure your project is a ''Class Library (.NET '''Framework''')''. Not .NET Core or .NET Standard.&lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
* [[Modding Tutorials/Writing custom code|Writing custom code]] continues on setting up your solution.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding tutorials]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Setting_up_a_solution&amp;diff=72615</id>
		<title>Modding Tutorials/Setting up a solution</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Setting_up_a_solution&amp;diff=72615"/>
		<updated>2020-06-27T06:06:33Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: .NET 3.5 -&amp;gt; 4.7.2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{BackToTutorials}}&lt;br /&gt;
{{Credit|[[User:Alistaire|Alistaire]]}}&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn how to set up a solution, along with instructions on setting the output directory and files for more convenient building right into the Assemblies folder.&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&lt;br /&gt;
* The manual option in this tutorial requires you to have [[Modding_Tutorials/Mod_folder_structure#The Source and Assemblies folders|set up a Source and Assemblies folder]] (the Visual Studio automatic option sets this up for you).&lt;br /&gt;
* You will want to have an IDE installed: [[Modding Tutorials/Recommended software#IDE's|Recommended IDE's]].&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Setting up a solution=&lt;br /&gt;
Setting up can be different for different IDE's. Feel free to add '''''complete''''' instructions for your IDE of choice.&lt;br /&gt;
&lt;br /&gt;
===Visual Studio Community 2017===&lt;br /&gt;
''NOTE: Visual Studio 2017 is a rather heavy application (2-3 GB for basic functionality) but has a bit more functionality. Only Install if your computer can handle it! The tutorial is similar for Visual Studio 2015.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Option 1 (Manual Method):====&lt;br /&gt;
# Create a new class library project&lt;br /&gt;
## Once loaded, go to File -&amp;gt; New -&amp;gt; Project...&lt;br /&gt;
## Go to Templates -&amp;gt; Visual C# -&amp;gt; Class Library (Be sure to select the *.NET Framework* version, not *.NET Standard*) [[File:Capture.png|200px|thumb|right|Installing the .NET framework]]&lt;br /&gt;
## Enter your name and solution name in the lower pane.&lt;br /&gt;
## Choose a location, preferably:&amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;(RimWorldInstallFolder)/Mods/(YourModName)/Source&amp;lt;/pre&amp;gt;&lt;br /&gt;
## ''Optional'': Untick &amp;quot;Create directory for solution&amp;quot;&lt;br /&gt;
# In your project, set target framework and various other porperties&lt;br /&gt;
## In your Solution Explorer, right click your project -&amp;gt; Properties&lt;br /&gt;
## Once in your properties, select Application -&amp;gt; Set Target Framework to .NET Framework 4.7.2 (No client profile)&lt;br /&gt;
## ''Optional'': Change your Assembly and Namespace names to anything of your choice&lt;br /&gt;
## Go to Build -&amp;gt; Advanced... and set &amp;quot;Debugging information&amp;quot; to none&lt;br /&gt;
## Leave Advanced..., and set the Output Path to &amp;quot;..\..\Assemblies\&amp;quot; (The Assemblies folder in your mod folder)&lt;br /&gt;
# Add references to RimWorld code&lt;br /&gt;
## Expand your project. Then right click &amp;quot;References&amp;quot; -&amp;gt; Add Reference...&lt;br /&gt;
## Click Browse...&lt;br /&gt;
## Navigate towards &amp;lt;pre&amp;gt;RimWorld******/RimWorld******_Data/Managed&amp;lt;/pre&amp;gt; and select files: &amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;Assembly-CSharp.dll&amp;amp;#10;UnityEngine.dll&amp;lt;/pre&amp;gt;&lt;br /&gt;
## Click &amp;quot;Add&amp;quot;&lt;br /&gt;
## Click &amp;quot;OK&amp;quot; to close the Reference Manager.&lt;br /&gt;
## Right click on both Assembly-CSharp.dll and UnityEngine.dll and set Copy Local to False (Properties pane).&lt;br /&gt;
&lt;br /&gt;
====Option 2 (Automatic Method):====&lt;br /&gt;
This option uses the [https://ludeon.com/forums/index.php?topic=39038.0 Rimworld Mod Development Cookiecutter] tool.&amp;lt;/br&amp;gt;&lt;br /&gt;
'''Note: despite being automatic and potentially taking away some of the tedium away, the environment it sets up is very particular and this tool is currently not recommended for newcomers.'''&amp;lt;/br&amp;gt;&lt;br /&gt;
''As of Jan 2019, the cookiecutter is set up for Windows development.  Linux/Mac people can still use it, but they will have a few errors to clean up.''&amp;lt;/br&amp;gt;&lt;br /&gt;
# Open Visual Studio&lt;br /&gt;
# Once loaded, go to File -&amp;gt; New -&amp;gt; From Cookiecutter...&lt;br /&gt;
# Search for ''rimworld''&lt;br /&gt;
# Double-click ''cookiecutter-rimworld-mod-development''&lt;br /&gt;
# Change the Template Options:&lt;br /&gt;
## ''Create To'' =&amp;gt; ''Your/Rimworld/Mod/Directory''&lt;br /&gt;
## ''mod_name''&lt;br /&gt;
## ''namespace_name'' (don't change if unsure)&lt;br /&gt;
## ''author'' =&amp;gt; ''your steam username''&lt;br /&gt;
## ''target_version'' =&amp;gt; current RW version (can leave blank for most up-to-date)&lt;br /&gt;
## ''in_game_description'' (not required, can change later in About-Release.xml)&lt;br /&gt;
## ''url'' (can leave blank for link to your Steam Workshop profile)&lt;br /&gt;
# Click &amp;quot;Create and Open Folder&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Sharpdevelop===&lt;br /&gt;
'''Caution:''' Sharpdevelop (or #develop) does NOT CURRENTLY allow for C# 6.0+ syntax without plugins and does NOT ALLOW for C# 7.0+ syntax at all. For your average project this does not matter, however some existing projects are already built entirely upon C# 6.0+ syntax which can not be compiled anymore in Sharpdevelop. Visual Studio does not have these issues and should be your go-to for compiling large projects such as Combat Extended.&lt;br /&gt;
&lt;br /&gt;
# Create a new class library project in your [[Modding Tutorials/Recommended software#IDE.27s|IDE of choice]];&lt;br /&gt;
## Go to File -&amp;gt; New -&amp;gt; Solution;&lt;br /&gt;
## Go to C# or .NET -&amp;gt; Library or Class Library (NOT portable);&lt;br /&gt;
## Enter a project name (solution name automatically updated);&lt;br /&gt;
## Choose a location, preferably:&amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;(RimWorldInstallFolder)/Mods/(YourModName)/Source&amp;lt;/pre&amp;gt;&lt;br /&gt;
## ''Optional'': Untick &amp;quot;Create a directory for solution&amp;quot;/&amp;quot;Create a project within the solution directory&amp;quot;,&lt;br /&gt;
# In your project, add references to Assembly-CSharp.dll and UnityEngine.dll:&lt;br /&gt;
## In your IDE project file browser, right-click the &amp;quot;References&amp;quot; folder and &amp;quot;Add reference&amp;quot;;&lt;br /&gt;
## Choose the &amp;quot;.NET Assembly Browser&amp;quot; tab and &amp;quot;Browse...&amp;quot;;&lt;br /&gt;
## Navigate towards &amp;lt;pre&amp;gt;RimWorld******/RimWorld******_Data/Managed&amp;lt;/pre&amp;gt; and select files: &amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;Assembly-CSharp.dll&amp;amp;#10;UnityEngine.dll&amp;lt;/pre&amp;gt;&lt;br /&gt;
## Click &amp;quot;Open&amp;quot; then &amp;quot;OK&amp;quot;;&lt;br /&gt;
## In the References folder, right-click Assembly-CSharp -&amp;gt; Properties and change &amp;quot;Local copy&amp;quot; to False. Do the same for UnityEngine,&lt;br /&gt;
# In your project properties, change the target framework to .NET 4.7.2:&lt;br /&gt;
## In your IDE project file browser, right-click &amp;quot;(YourSolutionName)&amp;quot;;&lt;br /&gt;
## Choose Properties;&lt;br /&gt;
## Go to the &amp;quot;Compiling&amp;quot; tab, &amp;quot;Output&amp;quot;, &amp;quot;Target framework&amp;quot;, &amp;quot;Change&amp;quot; and choose &amp;quot;.NET Framework 4.7.2&amp;quot;,&lt;br /&gt;
# In your project properties, change the build events so only a single file is built:&lt;br /&gt;
## Go to the &amp;quot;Compiling&amp;quot; tab, &amp;quot;Output&amp;quot;, &amp;quot;Debug info&amp;quot; and choose &amp;quot;No debug information&amp;quot;;&lt;br /&gt;
## Right-click your .cs files -&amp;gt; Properties and change &amp;quot;Copy to output&amp;quot; (If you haven't resized the properties bar, this will be truncated to &amp;quot;Copy to out&amp;quot;) to Never,&lt;br /&gt;
# In your project properties, fix the output location to put the DLL in the Assemblies folder:&lt;br /&gt;
## Go to the &amp;quot;Compiling&amp;quot; tab, &amp;quot;Output&amp;quot;, &amp;quot;Output path&amp;quot; and change the output path to &amp;quot;..\..\Assemblies\&amp;quot;.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Xamarin/MonoDevelop===&lt;br /&gt;
The setup is similar as the one above. A few special points to address:&lt;br /&gt;
# Mono 4.X isn't backward compatible so you may need to install an older 3.X version of Mono in order to compile against .NET4.7.2 dlls.&lt;br /&gt;
# Make sure you uncheck &amp;quot;Use MSBuild build engine (recommended for this project type)&amp;quot; under project &amp;gt; options &amp;gt; build &amp;gt; general   (You might find this by right-clicking on your project - not solution - name and selecting options)&lt;br /&gt;
# Changing the framework to 4.7.2 can be found (for Linux anyway) in the same place.&lt;br /&gt;
&lt;br /&gt;
More detailed installation instructions for Linux can be found [https://blog.rubenwardy.com/2016/07/21/rimworld-setup-monodevelop/ here] and [https://spdskatr.github.io/RWModdingResources/mono-arch here].&lt;br /&gt;
&lt;br /&gt;
===Rider (good for Mac)===&lt;br /&gt;
JetBrains Rider is a great cross-platform C# IDE, but it isn't cheap. It's $140 for the first year, including perpetual access to that version (access to future updates gets cheaper, but it's still over $100/year). However, the Early Access versions are a bit unstable but free. They also offer free student licenses.&lt;br /&gt;
&lt;br /&gt;
# Open Rider and click New Solution in the welcome dialog.&lt;br /&gt;
## Click Class Library under .NET on the left. The option may a second to show up.&lt;br /&gt;
## Under Solution Name (and Project Name), enter the name of your mod.&lt;br /&gt;
## Set the Solution Directory to [your mod folder]/Source.&lt;br /&gt;
## Optionally check &amp;quot;put solution and project in the same directory.&amp;quot; This is probably a good idea.&lt;br /&gt;
## Change Framework to .Net Framework 4.7.2.&lt;br /&gt;
## Click Create.&lt;br /&gt;
# In the left side bar, expand your solution, right click your project (mod name with &amp;quot;C#&amp;quot; icon) and click Properties.&lt;br /&gt;
## In the Properties window, select Configurations &amp;gt; Debug on the left and uncheck Debug Symbols.&lt;br /&gt;
## For both configurations, change the Output Path to ../../Assemblies.&lt;br /&gt;
## Click OK.&lt;br /&gt;
# Expand your project, right click References and click Add Reference.&lt;br /&gt;
## Click Add From.&lt;br /&gt;
## Browse to the folder with the RimWorld DLLs (Mac: /Users/[username]/Library/Application Support/Steam/steamapps/common/RimWorld/RimWorldMac.app/Contents/Resources/Data/Managed).&lt;br /&gt;
## Select both Assembly-CSharp.dll and UnityEngine.dll and click OK.&lt;br /&gt;
## Expand Assemblies under References. For both of the assemblies that you just added:&lt;br /&gt;
### Right click the assembly and click Properties.&lt;br /&gt;
### Uncheck &amp;quot;Copy Local&amp;quot; (you may need to scroll down) and click OK.&lt;br /&gt;
&lt;br /&gt;
You're done! Note that Rider has a built-in decompiler—to view the source of a RimWorld class or method, just right-click its name and click Go To &amp;gt; Definition.&lt;br /&gt;
&lt;br /&gt;
=Common issues=&lt;br /&gt;
* Can't find the option to target .NET Framework 3.5? Due to its age, it may require additional installation steps. In Visual Studio, Tools =&amp;gt; Get Tools and features =&amp;gt; Individual Components =&amp;gt; Select ''.NET Framework 3.5 development tools'' (or google installation instructions). Also make sure your project is a ''Class Library (.NET '''Framework''')''. Not .NET Core or .NET Standard. &lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
* [[Modding Tutorials/Writing custom code|Writing custom code]] continues on setting up your solution.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding tutorials]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72419</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72419"/>
		<updated>2020-06-19T23:33:01Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Add note about commenting, per JC and Garthor&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Code you write on your own should not look like this - for one thing, it should be well-commented so that others (even if it's just you in the future) know exactly what you're trying to do and how you're doing it. The code [https://github.com/dninemfive/PlagueGun/blob/master/PlagueGun/Projectile_PlagueBullet.cs in the repo] is probably over-commented and designed for a general audience but I recommend reviewing it.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72418</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72418"/>
		<updated>2020-06-19T23:26:14Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: remove yet another digression&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72417</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72417"/>
		<updated>2020-06-19T23:22:06Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Add link to ModExtensions page at Jamaican Castle's suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
{{Main|Modding Tutorials/DefModExtension}}&lt;br /&gt;
&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.addHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72416</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72416"/>
		<updated>2020-06-19T23:20:26Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Remove digression about property at Garthor's suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.addHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72415</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72415"/>
		<updated>2020-06-19T23:12:39Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Delete &amp;quot;base&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.addHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72414</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72414"/>
		<updated>2020-06-19T23:09:39Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Reword another note, at Garthor's suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. We're just making a new file for organizational purposes.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.addHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72413</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72413"/>
		<updated>2020-06-19T23:07:54Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Reword a note, at Garthor's suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Note the XML tags match the names of the fields in the C# class. This allows the XML to provide data to the program.  When the mod is loaded, the XML will be read, and used to fill in the corresponding fields.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.addHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72412</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72412"/>
		<updated>2020-06-19T23:03:51Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Standardize on camelCase, at Garthor's suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float addHediffChance = 0.05f;&lt;br /&gt;
public HediffDef hediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field addHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Standard modding practice is to give fields exposed to XML camelCase names, for consistency with vanilla XML.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;addHediffChance&amp;gt;0.05&amp;lt;/addHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;hediffToAdd&amp;gt;Plague&amp;lt;/hediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between addHediffChance and hediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of addHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.addHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.addHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.addHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.hediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.hediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.addHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72411</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72411"/>
		<updated>2020-06-19T22:59:53Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Clarify defNames, at Garthor's recommendation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''A word on defNames:''' &amp;lt;code&amp;gt;defName&amp;lt;/code&amp;gt;s are how the game references defs anywhere they're used in XML, since they're unique. When telling your plague gun to fire plague bullets, for instance, set its &amp;lt;code&amp;gt;defaultProjectile&amp;lt;/code&amp;gt; to your projectile's defName, like so:&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72410</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72410"/>
		<updated>2020-06-19T22:52:15Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Explain the RimWorld folder location better, at Garthor's suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Locate your RimWorld folder.&lt;br /&gt;
#* On Steam, you can find it by right-clicking the game in your games list &amp;gt; Properties &amp;gt; Local Files &amp;gt; Browse Local Files...&lt;br /&gt;
#** By default, it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\Steam\steamapps\common\RimWorld&amp;lt;/code&amp;gt; if you bought it through Steam on Windows.&lt;br /&gt;
#* If you bought the DRM-free version, it will be located wherever you unzipped it.&lt;br /&gt;
#* On GOG, you can find it by right-clicking the game in your games list &amp;gt; Manage Installation &amp;gt; Show Folder&lt;br /&gt;
#** By default it will be located at &amp;lt;code&amp;gt;C:\Program Files (x86)\GOG Galaxy\Games\RimWorld&amp;lt;/code&amp;gt; if you bought it through GOG on Windows.&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72409</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72409"/>
		<updated>2020-06-19T22:14:56Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: link my name bc why not&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by [[User:Dninemfive|dninemfive]].&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72408</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72408"/>
		<updated>2020-06-19T22:11:59Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Formatting tweak: remove backticks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML ThingDefs for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72407</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72407"/>
		<updated>2020-06-19T22:11:19Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Formatting tweak: add missing &amp;lt;code&amp;gt; block&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;code&amp;gt;&amp;lt;thingClass&amp;gt;&amp;lt;/code&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/First_Steps&amp;diff=72406</id>
		<title>Modding Tutorials/First Steps</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/First_Steps&amp;diff=72406"/>
		<updated>2020-06-19T22:07:41Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Link to the updated Plague Gun tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{BackToTutorials}}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Roaring to go? [[Plague Gun (1.1)|Here's a good tutorial that introduces a lot of things gradually]]. Want to take it slow? Smart. It's '''strongly''' recommended to do the following before you start making a mod:&lt;br /&gt;
&lt;br /&gt;
= Step 1: Search for a mod already doing what you want =&lt;br /&gt;
&lt;br /&gt;
Seriously. There are so many mods, there is generally one, probably of high quality, doing what you want it to. You might not need to make a mod!&lt;br /&gt;
&lt;br /&gt;
* Search [https://steamcommunity.com/workshop/about/?appid=294100 Steam's Workshop]. These have ready to go and managed by Steam mods. Click to use them.&lt;br /&gt;
* Check the [https://ludeon.com/forums/index.php?board=12.0 RimWorld Mod Forum]&lt;br /&gt;
* Use [http://google.com Google] because it works.&lt;br /&gt;
* Ask on [https://discord.gg/RimWorld Discord] or [https://reddit.com/r/RimWorld reddit] to see if they know of one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 2: Read Other Info On Modding =&lt;br /&gt;
&lt;br /&gt;
* [[Modding | RimWorld Wiki - Modding ]]&lt;br /&gt;
* [[Modding_Tutorials | RimWorld Wiki - Modding Tutorials]]&lt;br /&gt;
* [https://ludeon.com/forums/index.php?board=14.0 RimWorld Forum - Modding Help]&lt;br /&gt;
* Tynan's Readme.txt in your Rimworld directory (in RimWorldMac.app for Mac people)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 3: One Time Reads =&lt;br /&gt;
&lt;br /&gt;
* [[Modding_Tutorials/XML_file_structure | RimWorld Wiki - XML file structure and loading]]&lt;br /&gt;
* [[Modding_Tutorials/Testing_mods | RimWorld Wiki - Testing]] &lt;br /&gt;
* A17 Modding Updates - https://ludeon.com/forums/index.php?topic=32735.0 - by ZorbaTHut&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 4: Useful Links, Reference Constantly =&lt;br /&gt;
&lt;br /&gt;
* [[Modding_Tutorials/Folder_structure | Wiki - Folder Structure]]&lt;br /&gt;
* [https://ludeon.com/forums/index.php?board=14.0 Ludeon Forum - Modding Help]&lt;br /&gt;
* [https://github.com/RimWorldMod/RimworldModdingFiles RimWorld XML Database] - xml explained for XML modders &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 5: Tutorials by Others =&lt;br /&gt;
&lt;br /&gt;
* How to make a .dll-mod (Power Generation) - https://ludeon.com/forums/index.php?topic=3408.0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Step 6: Reference the works of others =&lt;br /&gt;
&lt;br /&gt;
It's how most of us learned how2mod.&lt;br /&gt;
&lt;br /&gt;
* Core. If it's (close to) something that already exists in RimWorld, use what RimWorld provides you. What better source of &amp;quot;how to do X&amp;quot; than the game itself?&lt;br /&gt;
* Maybe there's some inspiration [https://spdskatr.github.io/RWModdingResources/telephonebook on this list of modders and their GitHub links]&lt;br /&gt;
* Use [https://github.com/search?q=RimWorld+worldcomponent&amp;amp;type=Code GitHub search] to find how other modders handled a problem&lt;br /&gt;
* Use [http://google.com Google] because it works.&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72405</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72405"/>
		<updated>2020-06-19T22:07:09Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72404</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72404"/>
		<updated>2020-06-19T22:06:07Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Finish(?) article&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This concludes this tutorial. Congratulations on making it this far; you now have a solid understanding of XML and C# modding, and of connecting these two. There's a lot more to learn, especially on the C# end, so make sure to practice. If you have any questions don't hesitate to hit up the [https://discord.gg/rimworld Discord]#mod-development or the [https://ludeon.com/forums/index.php?board=14.0 forums] for help.&lt;br /&gt;
&lt;br /&gt;
As for this mod, you might want to add custom textures or sounds. For your next, you might want to try messing around with [[Modding Tutorials/Harmony|Harmony]] or see other [[Modding Tutorials|tutorials]] for inspiration.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding Tutorials/Setting up a solution|Setting up a solution]]&lt;br /&gt;
* [[Modding Tutorials/Distribution|Distribution]]&lt;br /&gt;
* [[Modding Tutorials/Harmony|Harmony]]&lt;br /&gt;
* [[Modding_Tutorials/Mod_folder_structure#The_Languages_folder|Language support]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Modding tutorials]]&lt;br /&gt;
[[Category: Modding]]&lt;br /&gt;
[[Category: Plague Gun]]&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72403</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72403"/>
		<updated>2020-06-19T21:59:14Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Finish localization section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
...well, almost. If you did test the gun just now, you'll have seen that the text was all distorted, using special characters which looked like the normal ones instead of text you expected. This is because of the use of &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; on keys which do not have translations in the language database. We just need to add those, and we'll be all set!&lt;br /&gt;
&lt;br /&gt;
# First, create a bunch of folders, starting in the root of your mod folder:{{br}}&amp;lt;small&amp;gt;Languages&amp;gt;English&amp;gt;Keyed&amp;lt;/small&amp;gt;&lt;br /&gt;
# Next, create a new file called PlagueGun_Keys.xml, with our favorite header.&lt;br /&gt;
# This will be really quick. Add the opening and closing &amp;lt;code&amp;gt;&amp;lt;LanguageData&amp;gt;&amp;lt;/code&amp;gt; tags:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# And, finally, add translations for the two keys used in the projectile class.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;{0}&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; in these keys will be replaced with the first and second arguments, respectively, of the &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; calls. For reference:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// successful hit message&lt;br /&gt;
&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(this.launcher.Label, hitPawn.Label)&lt;br /&gt;
// unsuccessful hit mote&lt;br /&gt;
&amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* If you give &amp;lt;code&amp;gt;.Translate()&amp;lt;/code&amp;gt; more arguments, you can use &amp;lt;code&amp;gt;{2}&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;{3}&amp;lt;/code&amp;gt;, &amp;amp;c.&lt;br /&gt;
#* Note that, since you only passed one argument to the failure message, &amp;lt;code&amp;gt;{1}&amp;lt;/code&amp;gt; would not be replaced with anything.&lt;br /&gt;
# Your PlagueGun_Keys.xml file should look like this:&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;LanguageData&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_FailureMote&amp;gt;Failure: {0} chance&amp;lt;/TST_PlagueBullet_FailureMote&amp;gt;&lt;br /&gt;
	&amp;lt;TST_PlagueBullet_SuccessMessage&amp;gt;{0} infected {1} with the plague!&amp;lt;/TST_PlagueBullet_SuccessMessage&amp;gt;&lt;br /&gt;
&amp;lt;/LanguageData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72402</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72402"/>
		<updated>2020-06-19T21:48:59Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: ...well, almost&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just compile and test your work; the plague will be properly applied and everything.&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72401</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72401"/>
		<updated>2020-06-19T21:48:24Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Actually finish projectile section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We're done! Your final Projectile_PlagueBullet class should look like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72400</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72400"/>
		<updated>2020-06-19T21:46:10Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ====&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 2 ===&lt;br /&gt;
* Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72399</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72399"/>
		<updated>2020-06-19T21:45:01Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Finish projectile section, I think&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Whew. ===&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Don't worry, we're almost finished. In fact, if you compile right now the gun ''will'' work - there just won't be any feedback if the shooter misses. This might be desirable, but let's add some feedback anyway.&lt;br /&gt;
&lt;br /&gt;
Well, that's a little bit of a lie. You'd also need to add the &amp;lt;thingClass&amp;gt; node to the XML, given below.&lt;br /&gt;
&lt;br /&gt;
We want to add an &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; block to our &amp;lt;code&amp;gt;if (rand &amp;lt;= Props.AddHediffChance))&amp;lt;/code&amp;gt; statement. This is where keeping track of curly braces comes in; Visual Studio should draw vertical lines between the correct curlies. Add this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, &amp;quot;TST_PlagueBullet_FailureMote&amp;quot;.Translate(Props.AddHediffChance), 12f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This throws a mote (particle effect, essentially), with text stating that the plague was not applied, at the target's position.&lt;br /&gt;
#* Fun fact: the &amp;lt;code&amp;gt;.ToVector3()&amp;lt;/code&amp;gt; call is the entire reason we needed to reference UnityEngine and UnityEngine.CoreModule.&lt;br /&gt;
# Finally, we need to make sure our projectile's def tells the game to use our new Projectile_PlagueBullet class instead of Bullet.&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thingClass&amp;gt;TST_PlagueGun.Projectile_PlagueBullet&amp;lt;/thingClass&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72398</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72398"/>
		<updated>2020-06-19T21:36:10Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: /* Writing the Projectile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's take a break and recap for a second. If you've followed the projectile section so far, this is the code you should have in your new .cs file:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Verse;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
&lt;br /&gt;
namespace TST_PlagueGun&lt;br /&gt;
{&lt;br /&gt;
    public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
    {&lt;br /&gt;
        public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        protected override void Impact(Thing hitThing)&lt;br /&gt;
        {&lt;br /&gt;
            base.Impact(hitThing);&lt;br /&gt;
            if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
            {&lt;br /&gt;
                float rand = Rand.Value;&lt;br /&gt;
                if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
                {&lt;br /&gt;
                    Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
                        this.launcher.Label, hitPawn.Label&lt;br /&gt;
                    ), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
                    Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
                    float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
                    if (plagueOnPawn != null)&lt;br /&gt;
                    {&lt;br /&gt;
                        plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
                        hediff.Severity = randomSeverity;&lt;br /&gt;
                        hitPawn.health.AddHediff(hediff);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72397</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72397"/>
		<updated>2020-06-19T21:33:58Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: More projectile stuff&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;br /&gt;
# First, let's call the base version of this method so we don't need to rewrite all the logic about damaging a pawn - we only care about adding the hediff ''after'' damage occurs. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
base.Impact(hitThing);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Next, we check to make sure the ModExtension was properly loaded, that we hit something, and that what we hit was a [[Pawns|Pawn]].&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
if (Props != null &amp;amp;&amp;amp; hitThing != null &amp;amp;&amp;amp; hitThing is Pawn hitPawn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Null checking is a very important skill, especially for Rimworld modding. If you ever get a &amp;lt;code&amp;gt;NullReferenceException&amp;lt;/code&amp;gt;, check to make sure you're correctly handling null values.&lt;br /&gt;
#* Also, note that we initialize a &amp;lt;code&amp;gt;Pawn&amp;lt;/code&amp;gt; version of the &amp;lt;code&amp;gt;hitThing&amp;lt;/code&amp;gt; while checking its type; we'll use this later. This statement ''also'' null-checks this new variable, in case you were wondering.&lt;br /&gt;
# Now that we know we hit a pawn, we generate a random number to see whether to apply the hediff.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float rand = Rand.Value;&lt;br /&gt;
if (rand &amp;lt;= Props.AddHediffChance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Rand&amp;lt;/code&amp;gt; is the base game's randomness generation class. &amp;lt;code&amp;gt;Value&amp;lt;/code&amp;gt; grabs the next random number between 0 and 1 and updates the class.&lt;br /&gt;
#* You could avoid declaring the &amp;lt;code&amp;gt;rand&amp;lt;/code&amp;gt; variable (i.e. doing &amp;lt;code&amp;gt;if (Rand.Value &amp;lt;= Props.AddHediffChance)&amp;lt;/code&amp;gt;), since it's not used later, but there's no harm in declaring it.&lt;br /&gt;
# If a hediff is applied, we want to alert the player, so we create a message in the top-left of the screen.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Messages.Message(&amp;quot;TST_PlagueBullet_SuccessMessage&amp;quot;.Translate(&lt;br /&gt;
	this.launcher.Label, hitPawn.Label&lt;br /&gt;
), MessageTypeDefOf.NeutralEvent);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Before adding the hediff, we need to check if the pawn already has it, so we get the hediff from the pawn, if it exists.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
Hediff plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(Props.HediffToAdd);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' The &amp;lt;code&amp;gt;?.&amp;lt;/code&amp;gt; is called the [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- null conditional operator]. It's basically an in-line null check; if the hit pawn's health tracker (&amp;lt;code&amp;gt;health&amp;lt;/code&amp;gt;) or hediff set (&amp;lt;code&amp;gt;hediffSet&amp;lt;/code&amp;gt;) are null it sets &amp;lt;code&amp;gt;plagueOnPawn&amp;lt;/code&amp;gt; to null instead of throwing an error.&lt;br /&gt;
# Now we finally add the hediff. If the pawn already has the plague we just increase its severity; otherwise, we create and add a new hediff with a random severity.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
float randomSeverity = Rand.Range(0.15f, 0.30f);&lt;br /&gt;
if (plagueOnPawn != null)&lt;br /&gt;
{&lt;br /&gt;
	plagueOnPawn.Severity += randomSeverity;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	Hediff hediff = HediffMaker.MakeHediff(Props.HediffToAdd, hitPawn);&lt;br /&gt;
	hediff.Severity = randomSeverity;&lt;br /&gt;
	hitPawn.health.AddHediff(hediff);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72396</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72396"/>
		<updated>2020-06-19T21:01:17Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: fix typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72395</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72395"/>
		<updated>2020-06-19T21:00:31Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: Formatting pass: add &amp;lt;code/&amp;gt; blocks in various places&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute &amp;lt;code&amp;gt;ParentName=&amp;quot;BaseBullet&amp;quot;&amp;lt;/code&amp;gt; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;code&amp;gt;&amp;lt;Defs&amp;gt;&amp;lt;/code&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* Find in Files is one of my most-used functions. 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: &amp;lt;code&amp;gt;defName&amp;gt;Bullet_Revolver&amp;lt;/code&amp;gt;&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;code&amp;gt;&amp;lt;ThingDef&amp;gt;&amp;lt;/code&amp;gt; all the way until its closing &amp;lt;code&amp;gt;&amp;lt;/ThingDef&amp;gt;&amp;lt;/code&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;/code&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;code&amp;gt;&amp;lt;defaultProjectile&amp;gt;&amp;lt;code/&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;&amp;lt;/code&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the &amp;lt;code&amp;gt;texturePath&amp;lt;/code&amp;gt; to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
	<entry>
		<id>https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72394</id>
		<title>Modding Tutorials/Plague Gun</title>
		<link rel="alternate" type="text/html" href="https://rimworldwiki.com/index.php?title=Modding_Tutorials/Plague_Gun&amp;diff=72394"/>
		<updated>2020-06-19T20:54:48Z</updated>

		<summary type="html">&lt;p&gt;Dninemfive: A bit more&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial is a rewrite of the [[Plague Gun/Introduction|original]] by Jecrell ({{LudeonThread|33219}}), updated to 1.1 by dninemfive.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we will be using most of the tools available to a Rimworld modder to create a custom weapon, known as the Plague Gun.&lt;br /&gt;
&lt;br /&gt;
This weapon will, when its shots hit a living target, have a chance to apply the Plague hediff (&amp;quot;health difference&amp;quot;) to that target.&lt;br /&gt;
&lt;br /&gt;
To do this, we will create XML `ThingDefs` for the gun and projectile, create a C# assembly which determines what happens when the projectile hits a target, and link that behavior back to the XML.&lt;br /&gt;
&lt;br /&gt;
This tutorial will assume a basic familiarity with XML and C# syntax. It should be simple enough to follow if you're only a beginner. &lt;br /&gt;
&lt;br /&gt;
If you have no XML or C# experience, there are good tutorials for XML [https://www.w3schools.com/xml/ here] and C# [https://www.learncs.org/ here].&lt;br /&gt;
&lt;br /&gt;
=== The Completed Mod ===&lt;br /&gt;
For a working example, check out [https://github.com/dninemfive/PlagueGun this GitHub repo].&lt;br /&gt;
&lt;br /&gt;
== Required Items ==&lt;br /&gt;
&lt;br /&gt;
Make sure to have the following installed, at least one per row:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| [https://notepad-plus-plus.org/ Notepad++] or [https://atom.io Atom] or [https://www.sublimetext.com/ Sublimetext] or [https://code.visualstudio.com/ VSCode] || Use any text editor that allows you to edit XML files and use &amp;quot;Find in Files&amp;quot; for referencing.&lt;br /&gt;
|-&lt;br /&gt;
| [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] || Use this or any other C# compiler to turn scripts into .dll files that RimWorld can use.&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/0xd4d/dnSpy/releases dnSpy] or [https://github.com/icsharpcode/ILSpy/releases ILSpy]|| This is for referencing the game's decompiled C# scripts.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For more detailed recommendations, see [[Modding Tutorials/Recommended software|here]].&lt;br /&gt;
&lt;br /&gt;
== XML Stage ==&lt;br /&gt;
&lt;br /&gt;
In this stage we will set up the mod and create XML files which add our things to the database.&lt;br /&gt;
&lt;br /&gt;
# Create a mod folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;lt;/small&amp;gt;&lt;br /&gt;
#* Go to your RimWorld's base folder. For myself, that is D&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\SteamLibrary\steamapps\common\RimWorld\. Others may find it in C&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;\Program Files (x86)\Steam\steamapps\common\RimWorld or a custom directory.&lt;br /&gt;
#* Go into the Mods folder.&lt;br /&gt;
#* Make a new folder with our mod's title: '''PlagueGun'''&lt;br /&gt;
# Inside '''PlagueGun''', make an '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;lt;/small&amp;gt;&lt;br /&gt;
# Inside the '''About''' folder, make a new text file and rename it About.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;About.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* You will need a good text editor to make a proper XML file -- see [[#Required Items|required items]]. 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 operating system's file view settings.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* At the top of an XML file, always include this for RimWorld. It basically just gives the game some info about how to read the file. &amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt; ''Note: the'' version '' tag should always be &amp;quot;1.0&amp;quot;. It has no relation with the current RimWorld version.''&lt;br /&gt;
#* Then add the MetaData tags for the Workshop and in-game Mod list.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;ModMetaData&amp;gt;&lt;br /&gt;
  &amp;lt;name&amp;gt;Test Mod - Plague Gun&amp;lt;/name&amp;gt; &amp;lt;!-- The name of your mod in the mod list --&amp;gt;&lt;br /&gt;
  &amp;lt;author&amp;gt;YourNameHere&amp;lt;/author&amp;gt;&lt;br /&gt;
  &amp;lt;packageId&amp;gt;YourNameHere.PlagueGun&amp;lt;/packageId&amp;gt; &amp;lt;!-- a unique identifier for your mod. Must contain only a-z and periods, no spaces. --&amp;gt;&lt;br /&gt;
  &amp;lt;supportedVersions&amp;gt; &amp;lt;!-- the version(s) your mod supports --&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;1.1&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/supportedVersions&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;This mod adds a plague gun, a weapon that has a chance to give your enemies the plague.\n\nFor version 1.1.&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/ModMetaData&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Save the file.&lt;br /&gt;
# Add a Preview.png or Preview.jpeg to your '''About''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;About&amp;gt;Preview.png&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This lets users see what your mod looks like in the RimWorld mod list or on the Steam Workshop.&lt;br /&gt;
#* The conventional dimensions to fit the preview image on Steam are 640x360. The image must be smaller than 1mb. &lt;br /&gt;
#* Example: [[File:Preview.png]]&lt;br /&gt;
# Make a '''Defs''' folder in your Mod's directory.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;lt;/small&amp;gt;&lt;br /&gt;
#* RimWorld will read your XML files in any subdirectory of '''Defs'''. You can name your directories however you like under that folder. Defs&amp;gt;StrangeNewAlienGuns&amp;gt;MyGuns.xml will work. For the purposes of this tutorial, however, we will use the RimWorld standard structure.&lt;br /&gt;
#* What are Defs? Main article: [[Modding Tutorials/XML Defs|Defs]]&lt;br /&gt;
#** RimWorld uses things called Defs (short for &amp;quot;definitions&amp;quot;) 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.&lt;br /&gt;
# Make a new '''ThingDefs''' folder in your '''Defs''' folder.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;lt;/small&amp;gt;&lt;br /&gt;
# Make a new text file in your '''ThingDefs''' folder, and change it to RangedWeapon_PlagueGun.xml.{{br}}&amp;lt;small&amp;gt;RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Defs&amp;gt;ThingDefs&amp;gt;RangedWeapon_PlagueGun.xml&amp;lt;/small&amp;gt;&lt;br /&gt;
#* This file will contain the blueprints (ThingDefs) for our new gun and bullets.&lt;br /&gt;
#* Next we will fill out our XML file by copying an existing revolver's ThingDef and a revolver bullet ThingDef.&lt;br /&gt;
#* In RimWorld, it is often best to use the XML attribute ParentName=&amp;quot;BaseBullet&amp;quot; when making a bullet, because it will copy XML code from a pre-existing BaseBullet ThingDef, which can save us time and key taps. Main article: [[Modding Tutorials/XML file structure#Inheritance|Inheritance]]&lt;br /&gt;
# First, add our favourite line to the top.&amp;lt;source lang = &amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
# Add the &amp;lt;Defs&amp;gt; opening and closing tags to the XML to hold our new code.&amp;lt;source lang = &amp;quot;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Use your text editor. Use its &amp;quot;Find in Files&amp;quot; function to reference and copy Bullet_Revolver to your XML file.&lt;br /&gt;
#* 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.&lt;br /&gt;
#* So, start by using Find in Files... and find this: defName&amp;gt;Bullet_Revolver&lt;br /&gt;
#* When you find Bullet_Revolver, copy from its beginning &amp;lt;ThingDef&amp;gt; all the way until its closing &amp;lt;/ThingDef&amp;gt; tag into your XML File.&lt;br /&gt;
# Use your text editor's &amp;quot;Find in Files&amp;quot; function to reference and copy Gun_Revolver to your XML file.&lt;br /&gt;
#* Typically, Gun_Revolver is right below Bullet_Revolver in XML, so hopefully this will be easy to find and copy.&lt;br /&gt;
#* Again, copy the ThingDef block to your new XML file.&lt;br /&gt;
# Change the defName, labels, and other stats of Bullet_Revolver and Revolver in your XML file to make them unique.&lt;br /&gt;
#* '''Change the &amp;lt;defaultProjectile&amp;gt; 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). {{br}}Once again, under the verbs. Please make sure &amp;lt;defaultProjectile&amp;gt; references the bullet. e.g.&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''TIP:''' Use prefixes to avoid conflicting with other mods. RimWorld will overwrite any def with &amp;lt;defName&amp;gt;Tobacco&amp;lt;/defName&amp;gt;, for instance, if it finds another with the same defName. If two modders use different prefixes, however, e.g. &amp;lt;defName&amp;gt;VGP_Tobacco&amp;lt;/defName&amp;gt; and &amp;lt;defName&amp;gt;ROM_Tobacco&amp;lt;/defName&amp;gt;, no conflict will occur, and both mods can co-exist. This tutorial uses TST_ for its example prefix. Main article: [[Modding_Tutorials/Compatibility|Compatibility]]&lt;br /&gt;
#* By contrast, labels, descriptions, and other non-defName tags can generally be non-unique without a risk of conflicts, except perhaps confusion for the end user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''If all you were interested in is making a gun mod, you are done.'''&amp;lt;/big&amp;gt; You'll of course want to edit values like the damage it does, and [[Modding_Tutorials/Testing_mods|test your mod]]. You'll also want to change the texturePath to your unique art, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Completed Example ===&lt;br /&gt;
&lt;br /&gt;
''Note'': The example is up-to-date for [[Version|1.1]] and will likely be outdated in the future. The above steps should always be relevant.&lt;br /&gt;
&amp;lt;source lang =&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;Defs&amp;gt;&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseBullet&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague bullet&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Projectile/Bullet_Small&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;projectile&amp;gt;&lt;br /&gt;
      &amp;lt;flyOverhead&amp;gt;false&amp;lt;/flyOverhead&amp;gt;&lt;br /&gt;
      &amp;lt;damageDef&amp;gt;Bullet&amp;lt;/damageDef&amp;gt;&lt;br /&gt;
      &amp;lt;damageAmountBase&amp;gt;12&amp;lt;/damageAmountBase&amp;gt;&lt;br /&gt;
      &amp;lt;stoppingPower&amp;gt;1&amp;lt;/stoppingPower&amp;gt;&lt;br /&gt;
      &amp;lt;speed&amp;gt;55&amp;lt;/speed&amp;gt;&lt;br /&gt;
    &amp;lt;/projectile&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;ThingDef ParentName=&amp;quot;BaseHumanMakeableGun&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;defName&amp;gt;TST_Gun_PlagueGun&amp;lt;/defName&amp;gt;&lt;br /&gt;
    &amp;lt;label&amp;gt;plague gun&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;A curious weapon notable for its horrible health effects.&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;graphicData&amp;gt;&lt;br /&gt;
      &amp;lt;texPath&amp;gt;Things/Item/Equipment/WeaponRanged/Revolver&amp;lt;/texPath&amp;gt;&lt;br /&gt;
      &amp;lt;graphicClass&amp;gt;Graphic_Single&amp;lt;/graphicClass&amp;gt;&lt;br /&gt;
    &amp;lt;/graphicData&amp;gt;&lt;br /&gt;
    &amp;lt;soundInteract&amp;gt;Interact_Revolver&amp;lt;/soundInteract&amp;gt;&lt;br /&gt;
    &amp;lt;statBases&amp;gt;&lt;br /&gt;
      &amp;lt;WorkToMake&amp;gt;4000&amp;lt;/WorkToMake&amp;gt;&lt;br /&gt;
      &amp;lt;Mass&amp;gt;1.4&amp;lt;/Mass&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyTouch&amp;gt;0.80&amp;lt;/AccuracyTouch&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyShort&amp;gt;0.75&amp;lt;/AccuracyShort&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyMedium&amp;gt;0.45&amp;lt;/AccuracyMedium&amp;gt;&lt;br /&gt;
      &amp;lt;AccuracyLong&amp;gt;0.35&amp;lt;/AccuracyLong&amp;gt;&lt;br /&gt;
      &amp;lt;RangedWeapon_Cooldown&amp;gt;1.6&amp;lt;/RangedWeapon_Cooldown&amp;gt;&lt;br /&gt;
    &amp;lt;/statBases&amp;gt;&lt;br /&gt;
    &amp;lt;weaponTags&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;SimpleGun&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;Revolver&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/weaponTags&amp;gt;&lt;br /&gt;
    &amp;lt;costList&amp;gt;&lt;br /&gt;
      &amp;lt;Steel&amp;gt;30&amp;lt;/Steel&amp;gt;&lt;br /&gt;
      &amp;lt;ComponentIndustrial&amp;gt;2&amp;lt;/ComponentIndustrial&amp;gt;&lt;br /&gt;
    &amp;lt;/costList&amp;gt;&lt;br /&gt;
    &amp;lt;recipeMaker&amp;gt;&lt;br /&gt;
      &amp;lt;skillRequirements&amp;gt;&lt;br /&gt;
        &amp;lt;Crafting&amp;gt;3&amp;lt;/Crafting&amp;gt;&lt;br /&gt;
      &amp;lt;/skillRequirements&amp;gt;&lt;br /&gt;
    &amp;lt;/recipeMaker&amp;gt;&lt;br /&gt;
    &amp;lt;verbs&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;verbClass&amp;gt;Verb_Shoot&amp;lt;/verbClass&amp;gt;&lt;br /&gt;
        &amp;lt;hasStandardCommand&amp;gt;true&amp;lt;/hasStandardCommand&amp;gt;&lt;br /&gt;
        &amp;lt;defaultProjectile&amp;gt;TST_Bullet_PlagueGun&amp;lt;/defaultProjectile&amp;gt;&lt;br /&gt;
        &amp;lt;warmupTime&amp;gt;0.3&amp;lt;/warmupTime&amp;gt;&lt;br /&gt;
        &amp;lt;range&amp;gt;25.9&amp;lt;/range&amp;gt;&lt;br /&gt;
        &amp;lt;soundCast&amp;gt;Shot_Revolver&amp;lt;/soundCast&amp;gt;&lt;br /&gt;
        &amp;lt;soundCastTail&amp;gt;GunTail_Light&amp;lt;/soundCastTail&amp;gt;&lt;br /&gt;
        &amp;lt;muzzleFlashScale&amp;gt;9&amp;lt;/muzzleFlashScale&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/verbs&amp;gt;&lt;br /&gt;
    &amp;lt;tools&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;grip&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&lt;br /&gt;
        &amp;lt;label&amp;gt;barrel&amp;lt;/label&amp;gt;&lt;br /&gt;
        &amp;lt;capacities&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Blunt&amp;lt;/li&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;Poke&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/capacities&amp;gt;&lt;br /&gt;
        &amp;lt;power&amp;gt;9&amp;lt;/power&amp;gt;&lt;br /&gt;
        &amp;lt;cooldownTime&amp;gt;2&amp;lt;/cooldownTime&amp;gt;&lt;br /&gt;
      &amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/tools&amp;gt;&lt;br /&gt;
  &amp;lt;/ThingDef&amp;gt;&lt;br /&gt;
&amp;lt;/Defs&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C# Workspace Setup ==&lt;br /&gt;
{{Main|Modding Tutorials/Setting up a solution}}&lt;br /&gt;
&lt;br /&gt;
Next, we will set up a workspace to write C# code, which is a little bit more involved than just using a text editor.&lt;br /&gt;
&lt;br /&gt;
# Open your compiler of choice for C#.&lt;br /&gt;
#* This tutorial will assume you're using Visual Studio Community edition, a free Windows-based compiler for C# code.&lt;br /&gt;
# Make a new Visual C# Class Library .NET Framework project. Name it PlagueGun. Make its directory RimWorld&amp;gt;Mods&amp;gt;PlagueGun&amp;gt;Source&lt;br /&gt;
#* File → New → Project → Class Library (.NET Framework).&lt;br /&gt;
#* Don't get this confused with &amp;quot;Class Library (.NET Standard)&amp;quot; or &amp;quot;Class Library (.NET Core)&amp;quot;!&lt;br /&gt;
# Go into the project properties. &lt;br /&gt;
#* Project → PlagueGun Properties.&lt;br /&gt;
# In that window, change the Target Framework version to .NET Framework 4.7.2&lt;br /&gt;
#* Forgetting to do this will cause lots of errors.&lt;br /&gt;
#* Select Yes when it asks you if you're sure to change the framework.&lt;br /&gt;
# Go to the '''Build''' tab.&lt;br /&gt;
# Change the output path to be RimWorld\Mods\PlagueGun\Assemblies&lt;br /&gt;
#* All .dll files will go into this directory when we &amp;quot;build&amp;quot; our code library.&lt;br /&gt;
# In that same window, click the Advanced... button.&lt;br /&gt;
# Change Debugging Information to none.&lt;br /&gt;
#* This prevents a simple error that occurs when RimWorld doesn't know what to do with the debug .pdb files.&lt;br /&gt;
# In Solution Explorer. Go into Properties and edit AssemblyInfo.cs. Change the name of your assembly and assembly file version number as you like.&lt;br /&gt;
#* This doesn't have to all be the same as your namespace, but it doesn't hurt to be consistent.&lt;br /&gt;
# In the main option bar at the top of the visual studio (File, Edit, View...), click Project, and click Add Reference.&lt;br /&gt;
# Click Browse and go to RimWorld\RimWorldWin64_Data\Managed&lt;br /&gt;
# Add references to Assembly-CSharp.dll, UnityEngine.dll, and UnityEngine.CoreModule.dll.&lt;br /&gt;
#* In 1.1 the Unity DLLs were split up and are no longer all contained in the same module.&lt;br /&gt;
#* For our purposes we only need UnityEngine.CoreModule.dll, as it contains some code we will use later.&lt;br /&gt;
#* In general, it's also a good idea to add UnityEngine.dll, which allows Visual Studio to tell you which modules you're missing if you get related errors.&lt;br /&gt;
# In the Solution Explorer (typically on the right side of the application), look at the references drop down list.&lt;br /&gt;
# Select Assembly-CSharp. Check the Properties section (usually under Solution Explorer). Make sure the properties section has Copy Local set to FALSE.&lt;br /&gt;
# Do this (Copy Local to FALSE) for UnityEngine and UnityEngine.CoreModule as well.&lt;br /&gt;
#* By doing this, we prevent the project from causing one million hash conflicts by copying the entire game's code twice!&lt;br /&gt;
&lt;br /&gt;
Now the workspace setup is complete and we can add C# code to RimWorld.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Exact folder names might differ between installs. The naming scheme differs slightly between the DRM-free and Steam version of the mod.&lt;br /&gt;
&lt;br /&gt;
== C# Coding ==&lt;br /&gt;
&lt;br /&gt;
Now let's start writing the code we'll need to add custom behavior to our projectiles.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
# Open Class1.cs in the sidebar, usually on the right in Visual Studio.&lt;br /&gt;
# Right-click and rename the .cs file to your liking.&lt;br /&gt;
# Add these lines to the top this file (and every .cs file you make from now on for modding RimWorld).&amp;lt;source lang =&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using RimWorld;&lt;br /&gt;
using Verse;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* These tell the code you're working with RimWorld. Without these, our code will not be able to understand references to RimWorld code.&lt;br /&gt;
# Add a namespace line. By default, this is your project name. Take note - you will need this to connect to XML later.&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace TST_PlagueGun;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' ''Using a prefix on the namespace is not required, but it's good for consistency and in the rare case they may overlap - such as when multiple people follow the same tutorial to learn how to mod.''&lt;br /&gt;
&lt;br /&gt;
=== Connecting XML and C#, Part 1 ===&lt;br /&gt;
# First, let's add a way to read XML data into your assembly.&lt;br /&gt;
#* '''Note:''' Previous versions of this tutorial used a custom class inheriting ThingDef, which was the standard at the time, but this one will use a ModExtension, which is much less prone to various mod conflicts.&lt;br /&gt;
# Rename public class Class1 to ModExtension_Plaguebullet and make it inherit DefModExtension. As a reminder, inheritance looks like this:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class ModExtension_PlagueBullet : DefModExtension&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' Renaming things in an IDE like Visual Studio is best done by pressing F2 or right-clicking the item/name. Doing it like that will change all occurrences of that thing, so everything that references your namespace or Class1 will now use the new name.&lt;br /&gt;
# Add the following fields in ModExtension_PlagueBullet:&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public float AddHediffChance = 0.05f;&lt;br /&gt;
public HediffDef HediffToAdd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* Here, we're giving the field AddHediffChance a default value, which means it doesn't need to be set explicitly in XML.&lt;br /&gt;
#* '''Note:''' Personally, I give fields which are exposed to XML camelCase names, instead of the PascalCase used here, for consistency with vanilla XML. You can do either; this format was retained from earlier versions of this tutorial.&lt;br /&gt;
# Now let's add the XML which connects to this ModExtension. In your TST_Bullet_PlagueGun def, add the following lines: &amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;modExtensions&amp;gt;&lt;br /&gt;
    &amp;lt;li Class=&amp;quot;TST_PlagueGun.ModExtension_PlagueBullet&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;AddHediffChance&amp;gt;0.05&amp;lt;/AddHediffChance&amp;gt;&lt;br /&gt;
        &amp;lt;HediffToAdd&amp;gt;Plague&amp;lt;/HediffToAdd&amp;gt;&lt;br /&gt;
    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/modExtensions&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* '''Note:''' This is the key intuition of pretty much this entire tutorial. The fields you set in classes exposed to XML, like ModExtensions, are directly and automatically filled by the base game by their names. Notice the exact correspondence between AddHediffChance and HediffToAdd between the C# and XML.&lt;br /&gt;
#* Additionally, take care to note you can set the value of AddHediffChance to any valid floating point number and it will be reflected in-game. The value given in C# is only the default value if unset.&lt;br /&gt;
&lt;br /&gt;
=== Writing the Projectile === &lt;br /&gt;
# 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).&lt;br /&gt;
# First, create a new .cs file by right-clicking the PlagueGun part of the Solution Explorer and selecting Add &amp;gt; New Item.&lt;br /&gt;
#* '''Note:''' in C#, you can have multiple class definitions in a single file. However, it's much easier to navigate when you have a separate file for separate concepts.&lt;br /&gt;
#* I tend to only keep closely related classes (such as ThingComps and their associated CompProperties) together in the same file; in most cases, you should only have one or two classes per file.&lt;br /&gt;
# 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. &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class Projectile_PlagueBullet : Bullet&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# First, let's connect our new projectile to the relevant ModExtension: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public ModExtension_PlagueBullet Props =&amp;gt; base.def.GetModExtension&amp;lt;ModExtension_PlagueBullet&amp;gt;();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* This line is a Property, basically a method which doesn't take any arguments, and can generally speaking be treated as a variable. See [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties this article] for more details.&lt;br /&gt;
#* It also isn't ''strictly'' necessary, but do you really want to retype or copy-and-paste the right-hand side of that expression over and over?&lt;br /&gt;
# Now, let's start the actual core code of this mod. Let's begin by overriding the Impact method on the base Bullet class, like so: &amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
protected override void Impact(Thing hitThing)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
#* The &amp;lt;code&amp;gt;override&amp;lt;/code&amp;gt; keyword tells the compiler that we're replacing the functionality of the &amp;lt;code&amp;gt;Impact&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;Bullet&amp;lt;/code&amp;gt; class we're inheriting from.&lt;/div&gt;</summary>
		<author><name>Dninemfive</name></author>
	</entry>
</feed>