User:Kernelmethod/Sandbox: Difference between revisions

m
Add some XML fragments to the static encounters section
m (Tweak interlocutor CSS to fix images in mobile view.)
m (Add some XML fragments to the static encounters section)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Introduction ==
== Tutorial: Mage Towers (static and dynamic encounters) ==


Welcome! If you're looking to learn how to write mods for Caves of Qud, this tutorial is a good place to start.
Potential ideas for an encounters tutorial:


In this tutorial, we're going to add a new creature to the game -- the great and mystical '''''snapjaw mage'''''. Along the way we're going to be helped by my friends {{qud text|&MRulimispruce, legendary sprouting orb}} and {{qud text|&MPyovya, legendary mopango}}.
* Static/dynamic locations
* Adding secrets during worldgen
* Zone builders


{| style = "margin: 1em;font-family:Source Code Pro;"
Some potential references:
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Howdy!
|}


{| style = "margin: 1em;font-family:Source Code Pro;"
* {{favilink|Flattened remains}}
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
* {{favilink|Ancient bones}} in the {{favilink|waterlogged tunnel}}
| style= "color:#155352" | <
* {{favilink|Stopsvalinn}}
| style = "border:1px solid #155352;padding:0.5em 1em;" | I'm excited!
* {{favilink|Oddly-hued Glowpad}}
|}
* {{favilink|Ruin of House Isner}}
* {{favilink|Bey Lah}}


By the end of this tutorial, you'll have created a mod for Caves of Qud which
Other:


* introduces two new creatures, the {{qud text|&Ysnapjaw &Rfire &Ymage}} and the {{qud text|&Ysnapjaw &Cice &Ymage}}, and
* https://bitbucket.org/bbucklew/cavesofqud-public-issue-tracker/issues/9458/modding-feature-request-allow-for-merging
* introduces two new missile weapons, the {{qud text|&Ytome of &Rfire}} and the {{qud text|&Ytome of &Cice}}.


Before you get started, you may also want to check out the [https://steamcommunity.com/sharedfiles/filedetails/?id=1302696701 Blue Ctesiphus modding tutorial] on Steam. It's a little dated, but it also covers many of the concepts covered here.
Static encounters section can be done with just XML; dynamic encounters section will require some C# experience.


This mod won't require any scripting, so you don't need to know anything about C#. However, I'd recommend that you play through a good chunk of Caves of Qud before you try your hand at modding. It's helpful to be able to refer to existing creatures and items when creating new ones.
== Adding static encounters ==


=== Source code ===
* Editing cell definition in Worlds.xml
* Add a new population table to a cell.
* Create a map template with the map editor.


You can find the source for the final version of the mod here: https://github.com/TrashMonks/Snapjaw-Mages
<syntaxhighlight lang="XML">
 
In particular (especially if you're familiar with version control), try stepping through the [https://github.com/TrashMonks/Snapjaw-Mages/commits/main repository's commit history]; it follows the steps involved in this tutorial, and you can use it to see how the mod changes after every step. Otherwise, if you find that for one reason or another your mod isn't working at some point in the tutorial, take a look at the files in the repository (which contain a complete, working implementation of the mod you'll be creating in this tutorial).
 
== Getting started, and basic concepts ==
 
If this is your first time modding, make sure to follow the checklist in [[Modding:Overview]]. It's particularly important that you install a text editor like [https://code.visualstudio.com/ VS Code]. I've prepared all of the tiles that you'll need to use for this tutorial, so you don't need to familiarize yourself with a pixel editor. However, if you plan on adding new tiles in the future you should be familiar with an editor like [https://www.piskelapp.com/ Piskel] or [https://www.aseprite.org/ Aseprite].
 
You should also enable the following options in your game:
* Modding &gt; Enable Mods
* Debug &gt; Show quickstart option during character generation.
** This will cause a {{qud text|&Y_Quickstart}} option to show up when you start a new game. This option makes it very easy to create a new character and immediately start testing out your mod.
 
Finally, you should take a look at the page of [[file locations]] and find the following directories on your computer:
* the "offline mods" folder; and
* the "game data files" folder.
 
=== XML ===
 
'''XML''' (e'''X'''tensible '''M'''arkup '''L'''anguage) is a type of ''markup language'', which (loosely speaking) is a text-based format that can be understood by a program. Caves of Qud makes extensive use of XML for things like defining creatures, quests, items, conversations, and more. We'll be working with XML a lot throughout this tutorial, so it's helpful to have a little familiarity with XML first.
 
You can check out the [https://en.wikipedia.org/wiki/XML Wikipedia page on XML] if you want to learn more. Here's some basic terminology you should be familiar with: in the XML snippet below,
 
<syntaxhighlight lang="xml">
<foo bar="baz" />
</syntaxhighlight>
 
<code>foo</code> is an '''XML tag'''. Meanwhile, <code>bar</code> is an '''attribute''', which (in this case) has been assigned the value <code>baz</code>.
 
You may also see '''comments''' here and there. A comment consists of one or more lines of text between <code>&lt;!--</code> and <code>--&gt;</code>, such as the following:
 
<syntaxhighlight lang="xml">
<!-- This is a comment! -->
 
<!--
  ... and this is also a comment!
-->
</syntaxhighlight>
 
Comments don't do anything by themselves; they're just helpful for documenting things that are going on in your XML.
 
=== Wishes ===
 
[[Wishes]] are commands that can be executed in-game to perform a variety of tasks. They're very useful when modding -- you can use a wish to spawn a creature of your choice, or create an item, and a variety of other tasks. You should follow the instructions on the [[Wishes]] page to bind the wish command to a key combination.
 
There are a lot of useful wishes. Here are a few that I use often:
 
* <code>idkfa</code>: puts your character in "God Mode". This makes your character immortal, and causes all attacks that penetrate to instantly kill.
* <code>swap</code>: allows you to swap your body with an adjacent creature.
* In addition, you can wish for the ID of a creature or item to spawn that creature/item. For instance, wishing for <code>Troll King 1</code> will spawn {{favilink|Jotun, Who Parts Limbs}}.
 
=== Navigating the game's data files ===
 
We won't delve too deeply into Caves of Qud's data files, but it's helpful to know how to navigate through them when creating a mod. Make sure that you've found where your computer keeps the game's data files by looking at the list of [[file locations]] before continuing; it should be a subfolder called <code>Base</code> of a folder called <code>StreamingAssets</code> somewhere on your machine.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Don't modify the game's files! If you make a mistake, you could end up having to reinstall the game.
|}
 
Once you've found this folder, you should see a bunch of files with names ending in things like .bmp, .rpm, .xml, .json, and so on.
 
[[File:Snapjaw_Mages_--_Game_files.webp|700px]]
 
For this tutorial, the .xml files are the ones we're going to be the most interested in. There are a lot of these files (35 as of game version 2.0.205.63); here's a high-level overview of just a few of them:
 
* <code>Bodies.xml</code>: in charge of defining various body parts and creature anatomies. This is useful when you want to define a new body type; for instance, the [https://github.com/librarianmage/Blahajar Blahajar mod] defines a unique anatomy specific to sharks.
* <code>Conversations.xml</code>: defines the conversational script that different creatures have.
* <code>Mutations.xml</code>: data file containing all of the mutations that are available in-game.
* <code>ObjectBlueprints/Creatures.xml</code>: definitions of all of the creatures that exist in Caves of Qud.
* <code>ObjectBlueprints/Items.xml</code>: definitions of all of the items available in Caves of Qud.
* <code>PopulationTables.xml</code>: contains ''population tables'', which are used to figure out when and where creatures should spawn.
* <code>Skills.xml</code>: contains all of the skill trees provided by Caves of Qud, and abilities within those trees.
* <code>Quests.xml</code>: lays out the steps and rewards for non-procedurally generated quests.
 
When adding new creatures and items (as in this tutorial!), we're mostly going to be interested in just <code>ObjectBlueprints/Creatures.xml</code> and <code>ObjectBlueprints/Items.xml</code>. Starting in the next section, we'll discuss what all of the bits and pieces mean in these files. Make sure you know where to find these files before you continue!
 
== Creating a mod ==
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Let's get started!
|}
 
We'll start by creating a mod that doesn't actually do anything. To do that, go to Caves of Qud's "offline mods" folder; you can find the location of this folder for your operating system by looking at the page of [[file locations]]. Inside this folder (it should be named <code>Mods</code>), create a folder called <code>Snapjaw-Mages</code>. The first file we're going to create for our mod will be a '''''manifest file'''''; this contains metadata such as our mod's title, a description of the mod, and its version. Create a file called <code>manifest.json</code> inside the <code>Snapjaw-Mages/</code> folder, and paste in the following contents:
 
<syntaxhighlight lang="json">
{
    "id": "Pyovya_SnapjawMage",
    "title": "Snapjaw Mages!",
    "description": "Adds the new Snapjaw Mage creature to Caves of Qud.",
    "version": "0.1.0",
    "author": "Pyovya",
    "tags": "Creature",
    "PreviewImage": "preview.png"
}
</syntaxhighlight>
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Feel free to replace <code>Pyovya</code> with your own name!
|}
 
We should also get a preview image for the mod. I've made one that you can use here:
 
https://github.com/TrashMonks/Snapjaw-Mages/blob/main/Snapjaw-Mages/preview.png
 
Download this image and place it in the <code>SnapjawMage/</code> folder, so that now your folder looks like this:
 
<syntaxhighlight lang="text">
Snapjaw-Mages
├── manifest.json
└── preview.png
</syntaxhighlight>
 
Now start up Caves of Qud. In the splash screen, click on "Installed Mod Configuration". If everything went correctly, you should see a "Snapjaw Mages!" mod appear in your list of installed mods:
 
[[File:Snapjaw Heros -- Mods List.webp|800px]]
 
'''''You will be returning to this screen often!'''''
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Every time you make a change to your mod, you will need to go back to this screen and activate the "Save and Reload" option (which you can do by pressing <code>r</code>). You should see a bar saying "reloading mod configuration" appear at the bottom of your screen, like so:
|}
 
[[File:Snapjaw_Mages_--_reloading_mod_config.webp|700px]]
 
== Your first creature ==
 
=== Adding a new creature to <code>Creatures.xml</code> ===
 
In your mod directory, create a folder called <code>ObjectBlueprints/</code>, and within that folder open up a file in your text editor called <code>Creatures.xml</code>. Let's start by adding the following to <code>Creatures.xml</code>:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<objects>
<objects>
</objects>
  <!--
</syntaxhighlight>
    Due to an outstanding bug in the way the Hills zonebuilder works, your
 
     terrain object *must* have the word "Hills" somewhere in its name.
Save this file! Before continuing, make sure your mod directory looks something like this:
 
<syntaxhighlight lang="text">
Snapjaw-Mages
├── manifest.json
├── ObjectBlueprints
│  └── Creatures.xml
└── preview.png
</syntaxhighlight>
 
With that out of the way, let's start adding our snapjaw mage to <code>Creatures.xml</code>:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <object Name="Pyovya_SnapjawMage_Snapjaw Mage" Inherits="Snapjaw">
  </object>
</objects>
</syntaxhighlight>
 
Let's break this down:
* The <code>object</code> tag tells Qud that we want to add a new creature.
* The <code>Name</code> attribute is a unique identifier for our new creature (it's not the name of the creature as it appears in-game -- we'll get to that shortly). You'll use this identifier whenever you want to wish for a snapjaw mage.
* The <code>Inherits</code> attribute says that our new creature should "inherit" all of the properties of the <code>Snapjaw</code> creature.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Hey, why'd you add the <code>Pyovya_SnapjawMage</code> bit to the front of the name of the creature? Why not just call it a <code>Snapjaw Mage</code>?
|}
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | When writing a mod, it's common courtesy to prefix unique identifiers with your name, an underscore <code>_</code>, followed by the mod's name. This ensures that if somebody else writes their own Snapjaw Mage mod, your mod won't conflict with theirs.
|}
 
So far we haven't actually added anything to our creature; for all intents and purposes it's a plain ol' snapjaw. Let's change that by adding some parts.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | What's a part?
|}
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | A '''''part''''' is a special piece of code that can be added to a creature to modify its appearance, behavior, stats, and any number of other things. There are a ''lot'' of parts -- over a thousand! You won't need to worry about most of them; many of them are highly-customized bits of code written for just one or two creatures. For instance, there's a <code>CryptSitterBehavior</code> part that is used exclusively by {{favilink|crypt sitter|plural}}.
|}
 
We're going to add two parts to our creature: <code>Render</code> and <code>Description</code>.
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <object Name="Pyovya_SnapjawMage_Snapjaw Mage" Inherits="Snapjaw">
    <part Name="Description" Short="A tattered robe and decaying hat are all that protect =pronouns.possessive= thin layer of grizzled fur from the forces of nature. But behind that furtive glance, =pronouns.subjective= =verb:prepare:afterpronoun= an elemental spell, deployed at a moment's notice against threats to =pronouns.objective= and =pronouns.possessive= kin. =pronouns.Subjective= =verb:understand:afterpronoun= not the power that =pronouns.subjective= =verb:wield:afterpronoun=; and that only makes =pronouns.objective= all the more dangerous." />
     <part Name="Render" DisplayName="snapjaw mage" Tile="Assets_Content_Textures_Creatures_sw_snapjaw_warrior.bmp" ColorString="&amp;O" DetailColor="Y" />
  </object>
</objects>
</syntaxhighlight>
 
Before I dig into the XML we've just added, save <code>Creatures.xml</code>. Reload your mods, and then wish for a <code>Pyovya_SnapjawMage_Snapjaw Mage</code>.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | To reload your mods, return to the start screen for Caves of Qud, click on "installed mod configuration", and then press <code>r</code>. Then restart the game, either by continuing an old save or starting a new save.
|}


You should see a snapjaw like the one below show up:
    https://bitbucket.org/bbucklew/cavesofqud-public-issue-tracker/issues/10902
 
[[File:Snapjaw_Mages_--_Initial_mage.webp|600px]]
 
Congrats! You've successfully added a snapjaw mage to your game.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style = "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | I did?
|}
 
Well, it's still a little bare-bones, but you have indeed created a new creature called a <code>snapjaw mage</code> and spawned it in your game! Give yourself a pat on the back, Rulimispruce.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | *rustling noises*
|}
 
Now, back to the parts that you just added:
 
* The <code>Description</code> part changes (as you might guess) the description of the creature when you look at it.
** You'll notice that the description includes a lot of things like <code>=pronouns.subjective=</code> and <code>=verb:understand:afterpronoun=</code>. This ensures that the game uses the correct pronouns while generating the creature's description and conjugates verbs correctly. See [[Modding:Grammar]] for more details.
* The <code>Render</code> attribute changes the creature's appearance, as well as its name (as it appears in-game). This tag has the following attributes:
** <code>DisplayName</code>: how the creature's name is displayed in-game.
** <code>Tile</code>: a .png or .bmp ("bitmap") image that's used to display the creature. Check out [[Modding:Tiles]] for more information. In the snippet above, I just used the tile for {{favilink|snapjaw warrior|plural}} to get us started.
** <code>ColorString</code> and <code>DetailColor</code>: these are the primary and secondary colors used to color in the tile that you supply. You can look at [[Modding:Colors & Object Rendering]] for a full list of all of the available colors; in this case, we used <code>O</code> (orange) as the primary color and <code>Y</code> (white) as the detail color.
 
=== Using custom tiles ===
 
Instead of having our snapjaw mages look like off-color snapjaw warriors, let's add a snazzy new tile to the game to use for our mages! Just pop open a pixel editor, create a 16px x 24px black-and-white tile, save it as a --
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | I'm just a lil old sprouting orb, I don't know how to do any of those things.
|}
 
Ah, alright, fair enough. Well in that case, feel free to download the tile that I've already made for you here:
 
https://github.com/TrashMonks/Snapjaw-Mages/blob/main/Snapjaw-Mages/Textures/Pyovya_SnapjawMage/snapjaw_mage.png
 
In your mod directory, create a folder called <code>Textures/</code>; in that folder, create a subfolder called <code>Pyovya_SnapjawMage/</code>. Save <code>snapjaw_mage.png</code> there, so that your mod folder now looks like this:
 
<syntaxhighlight lang="text">
Snapjaw-Mage
├── manifest.json
├── ObjectBlueprints
│  └── Creatures.xml
├── preview.png
└── Textures
    └── Pyovya_SnapjawMage
        └── snapjaw_mage.png
</syntaxhighlight>
 
Let's change the <code>Render</code> part for our mages to use this tile:
 
<syntaxhighlight lang="xml">
<part Name="Render" DisplayName="snapjaw mage" Tile="Pyovya_Snapjaw/snapjaw_mage.png" ColorString="&amp;O" DetailColor="Y" />
</syntaxhighlight>
 
Now let's fill out some more details about our furry friend!
 
=== Adding inventory ===
 
First of all, like any good mage, they need a {{favilink|walking stick}} and some [[book|books]]. Let's also give them some clothes to equip while we're at it. Add the following XML to your creature:
 
<syntaxhighlight lang="xml">
<inventoryobject Blueprint="Walking Stick" Number="1" />
<inventoryobject Blueprint="Cloth Robe" Number="1" />
<inventoryobject Blueprint="Sandals" Number="1" />
<inventoryobject Blueprint="StandaloneMarkovBook" Number="1-2" Chance="10" />
</syntaxhighlight>
 
By setting <code>Number="1-2"</code> and <code>Chance="10"</code> in that last line, we've given our mages a 10% chance of holding 1-2 books when they spawn.
 
=== Adding skills ===
 
Let's give our mage the [[Cudgel]] skill as well, so that they're a little bit better at fighting with that walking stick:
 
<syntaxhighlight lang="xml">
<skill Name="Cudgel" />
</syntaxhighlight>
 
=== Changing stats ===
 
The base <code>Snapjaw</code> creature that we're inheriting from has really low stats, so we're going to bump up our mage's stats a little.
 
<syntaxhighlight lang="xml">
<stat Name="Hitpoints" Value="15" />
<stat Name="DV" Value="4" />
 
<!-- Raise ego to make the mage's mental mutations a little more powerful -->
<stat Name="Ego" Value="17" />
 
<!-- Raise willpower to reduce the cooldowns of abilities -->
<stat Name="Willpower" Value="17" />
</syntaxhighlight>
 
If you've followed along up to this point, you should be ending this section with a snapjaw mage that looks like this:
 
[[File:Snapjaw_Mages_--_Mage_new_tile.webp|700px]]
 
Your <code>Creatures.xml</code> at this point should look something like the following. Make sure that everything checks out before proceeding to the next section!
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <object Name="Pyovya_SnapjawMage_Snapjaw Mage" Inherits="Snapjaw">
    <part Name="Description" Short="A tattered robe and decaying hat are all that protect =pronouns.possessive= thin layer of grizzled fur from the forces of nature. But behind that furtive glance, =pronouns.subjective= =verb:prepare:afterpronoun= an elemental spell, deployed at a moment's notice against threats to =pronouns.objective= and =pronouns.possessive= kin. =pronouns.Subjective= =verb:understand:afterpronoun= not the power that =pronouns.subjective= =verb:wield:afterpronoun=; and that only makes =pronouns.objective= all the more dangerous." />
    <part Name="Render" DisplayName="snapjaw mage" Tile="Pyovya_SnapjawMage/snapjaw_mage.png" ColorString="&amp;O" DetailColor="Y" />
 
    <inventoryobject Blueprint="Walking Stick" Number="1" />
    <inventoryobject Blueprint="Cloth Robe" Number="1" />
    <inventoryobject Blueprint="Sandals" Number="1" />
    <inventoryobject Blueprint="StandaloneMarkovBook" Number="1-2" Chance="10" />
 
    <skill Name="Cudgel" />
 
    <stat Name="Hitpoints" Value="15" />
    <stat Name="DV" Value="4" />
    <stat Name="Ego" Value="17" />
    <stat Name="Willpower" Value="17" />
  </object>
</objects>
</syntaxhighlight>
 
== Using your creature as a base: Elemental Mages ==
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Hold up a second. How is this creature a mage? It doesn't have any kind of magic spells!
|}
 
I was just getting to that!
 
So far, we've sketched out most of the properties, skills, and stats that a snapjaw mage should have. Now we're going to create two types of mages: '''''fire mages''''' and '''''ice mages'''''.
 
First, we need to mark the snapjaw mage we've created as a "base object", i.e. an object that doesn't appear in-game but which instead serves as the basis for other objects. Add the following tag to the <code>Pyovya_SnapjawMage_Snapjaw Mage</code> creature:
 
<syntaxhighlight lang="xml">
<tag Name="BaseObject" Value="*noinherit" />
</syntaxhighlight>
 
Now, below your definition of the snapjaw mage in <code>Creatures.xml</code>, add two new creatures:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <!--
  Skipped: the XML that defines the "Pyovya_SnapjawMage_Snapjaw Mage" creature
   -->
   -->
 
   <object Name="Pyovya_SnapjawMage_TerrainMageHills" Inherits="TerrainHills">
   <object Name="Pyovya_SnapjawMage_Fire Mage" Inherits="Pyovya_SnapjawMage_Snapjaw Mage">
    <part Name="Render" DisplayName="mage's tower" RenderString="227" ColorString="&amp;K" DetailColor="m" Tile="Pyovya_SnapjawMage/mage_tower.png" />
  </object>
    <part Name="Description" Short="The secluded abode of an accomplished magician lays against the rolling hillscape. At night, one can hear their lonely howls emanating from the ruined tower." />
 
     <!--
  <object Name="Pyovya_SnapjawMage_Ice Mage" Inherits="Pyovya_SnapjawMage_Snapjaw Mage">
      Remove the RandomTile part inherited from TerrainHills so that our tile doesn't
  </object>
      get replaced with a random hills tile.
</objects>
    -->
</syntaxhighlight>
     <removepart Name="RandomTile" />
 
    <!--
{| style = "margin: 1em;font-family:Source Code Pro;"
      We modify grammatical usage of the terrain's name so that when we pass it by
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
      on the world map, it says that we pass by "a mage's tower" rather than "some
| style= "color:#155352" | <
      mage's tower" or "a set of mage's tower".
| style = "border:1px solid #155352;padding:0.5em 1em;" | Notice how we've used the <code>Inherits</code> attribute here. We're telling the game that our original snapjaw mage creature, <code>Pyovya_SnapjawMage_Snapjaw Mage</code>, should serve as a base for our fire and ice mages. As a result, our creatures will spawn with walking sticks, have the [[Cudgel]] skill, and so on.
    -->
|}
     <xtagGrammar Proper="false" massNoun="false" />
 
     <tag Name="Gender" Value="*delete" />
Referencing the [[Modding:Colors & Object Rendering]] page, we're going to change our fire mages' detail color to red. We're also going to give them the {{favilink|Pyrokinesis}} mutation:
 
<syntaxhighlight lang="xml">
<object Name="Pyovya_SnapjawMage_Fire Mage" Inherits="Pyovya_SnapjawMage_Fire Mage">
  <part Name="Render" DisplayName="snapjaw {{R|fire}} mage" Tile="Pyovya_SnapjawMage/snapjaw_mage.png" ColorString="&amp;O" DetailColor="R" />
  <mutation Name="Pyrokinesis" Level="1" />
</object>
</syntaxhighlight>
 
The <code>&#x7b;{R|fire}&#x7d;</code> bit there says that the word "fire" should be colored red. Now we'll make some similar changes to ice mages (changing their color to cyan), and give them the {{favilink|Cryokinesis}} mutation.
 
<syntaxhighlight lang="xml">
<object Name="Pyovya_SnapjawMage_Ice Mage" Inherits="Pyovya_SnapjawMage_Ice Mage">
  <part Name="Render" DisplayName="snapjaw {{C|ice}} mage" Tile="Pyovya_SnapjawMage/snapjaw_mage.png" ColorString="&amp;O" DetailColor="C" />
  <mutation Name="Cryokinesis" Level="1" />
</object>
</syntaxhighlight>
 
Now try wishing for a <code>Pyovya_SnapjawMage_Fire Mage</code> and a <code>Pyovya_SnapjawMage_Ice Mage</code>. You should get two creatures that appear like the ones below (and they should immediately start attacking you with {{favilink|Pyrokinesis}} and {{favilink|Cryokinesis}}!):
 
[[File:Snapjaw_Mages_--_Fire_and_Ice.webp|700px]]
 
== Creating new items ==
 
We've now successfully added a {{qud text|&Ysnapjaw &Rfire &Ymage}} and a {{qud text|&Ysnapjaw &Cice &Ymage}}. We're also going to give them two new missile weapons: a {{qud text|&Ytome of &Rfire}} and a {{qud text|&Ytome of &Cice}}. These weapons will be magical spell books that function as less powerful versions of the {{favilink|flamethrower}} and {{favilink|freeze ray}}, respectively.
 
Start by creating a file <code>Items.xml</code> in the <code>ObjectBlueprints/</code> folder:
 
<syntaxhighlight lang="text">
Snapjaw-Mages
├── manifest.json
├── ObjectBlueprints
│  ├── Creatures.xml
│  └── Items.xml
├── preview.png
└── Textures
     └── Pyovya_SnapjawMage
        └── snapjaw_mage.png
</syntaxhighlight>
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Does it matter whether I name my file <code>Items.xml</code>? And do I have to place it in the <code>ObjectBlueprints/</code> directory?
|}
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Nope and nope! In fact, you can name all of your XML files whatever you want (as long as they end in .xml) and place them wherever you feel like (as long as they're in the <code>SnapjawMage/</code> mod directory). The scheme that we're using here to organize our XML files is the same scheme that the game uses for its own files (the ones that you can find in the [[File locations|"game data files" folder]]), just to make the relationship between what we're writing and Caves of Qud's code a little bit clearer.
|}
 
We want to create two new items -- a fire tome and and ice tome -- and we can probably guess in advance that these two items are going to have a lot of the same properties. Therefore, we're going to start the same way that we did when we were creating our mages: we'll create a base "magic tome" object, which we will later inherit from.
 
Add the following to <code>Items.xml</code>:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <object Name="Pyovya_SnapjawMage_Magic Tome" Inherits="BaseMissileWeapon">
     <tag Name="BaseObject" Value="*noinherit" />
  </object>
</objects>
</syntaxhighlight>
 
Now we need to add some parts to our object:
 
<syntaxhighlight lang="xml">
<!-- We borrow the same description that StandaloneMarkovBook uses -->
<part Name="Description" Short="Crisp pages of goatskin vellum are bound into a codex." />
<part Name="Physics" Weight="1" UsesTwoSlots="true" />
<part Name="Commerce" Value="80" />
</syntaxhighlight>
 
We've already seen the <code>Description</code> part before. The <code>Physics</code> part is a common part used by items to determine how much they weigh, whether they are equipped in one or two slots, and what category they appear under in the inventory screen. Finally, the <code>Commerce</code> part defines how valuable the item is.
 
Let's also add a tag to the item to indicate its [[tier]], as well as what [[mods]] it can accept (in our case, we don't want this item to be moddable):
 
<syntaxhighlight lang="xml">
<tag Name="Tier" Value="2" />
<tag Name="Mods" Value="" />
</syntaxhighlight>
 
That should be enough for our base object. Now, let's create a fire tome and an ice tome by inherting from <code>Pvovya_SnapjawMage_Magic Tome</code>. While we're at it, let's add some tiles to render each of them; we'll use the built-in <code>Items/sw_book_1.bmp</code> tile (which looks like a regular [[book]]).
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <!-- Skipped: definition of "Pyovya_SnapjawMage_Magic Tome" -->
 
  <object Name="Pyovya_SnapjawMage_Fire Tome" Inherits="Pyovya_SnapjawMage_Magic Tome">
     <part Name="Render" DisplayName="tome of {{R|fire}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;R" DetailColor="Y" />
  </object>
 
  <object Name="Pyovya_SnapjawMage_Ice Tome" Inherits="Pyovya_SnapjawMage_Magic Tome">
     <part Name="Render" DisplayName="tome of {{C|ice}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;C" DetailColor="Y" />
   </object>
   </object>
</objects>
</objects>
</syntaxhighlight>
</syntaxhighlight>


=== Using existing items as a template ===
<syntaxhighlight lang="XML">
 
Now, we know that we want these items to function like a {{favilink|flamethrower}} and {{favilink|freeze ray}}, but we probably need to iron out some more details first. Such as:
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Do magic books use ammo?
|}
 
That's a good question. If we wanted, we could set up our new missile weapons to use some kind of magical ammo, or pull from an energy cell. I'm actually going to go with a third option -- let's set up our tomes of fire and ice so that they don't use any kind of ammo or energy, but instead just have a plain 10-turn cooldown.
 
We must also figure out what kind of projectile each of these items shoots. Let's take a look at how the game defines the flamethrower and freeze ray objects. Looking at the [[file locations]], navigate in your file browser to where the game's data files are stored. Once you're in that folder, go to <code>ObjectBlueprints/</code> and open up the <code>Items.xml</code> file. Then search for <code>Flamethrower</code> and <code>Freeze Ray</code>; you should find the following XML for each of them.
 
<syntaxhighlight lang="xml">
<object Name="Freeze Ray" Inherits="BaseRifle">
  <part Name="Render" DisplayName="{{freezing|freeze}} ray" Tile="items/sw_raygun.bmp" ColorString="&amp;C" DetailColor="y" />
  <part Name="Physics" UsesTwoSlots="true" Weight="28" />
  <part Name="MissileWeapon" Skill="Rifle" AmmoChar="FR" ShotsPerAction="1" AmmoPerAction="1" ShotsPerAnimation="1" WeaponAccuracy="0" />
  <part Name="Commerce" Value="750" />
  <part Name="EnergyAmmoLoader" ChargeUse="500" ProjectileObject="ProjectileFreezeRay" />
  <part Name="EnergyCellSocket" SlotType="EnergyCell" />
  <part Name="Description" Short="Gaseous coolant billows through a chiffon tube, putting dew on the wide and planar barrel chrome. It spills out onto the air from a ice-chipped muzzle." />
  <part Name="Examiner" Complexity="5" />
  <part Name="TinkerItem" Bits="12345" CanDisassemble="true" CanBuild="true" />
  <part Name="Metal" />
  <part Name="ItemElements" Elements="ice:10" />
  <tag Name="MissileFireSound" Value="lazerMedium4" />
  <tag Name="Mods" Value="MissileWeaponMods,FirearmMods,CommonMods,RifleMods,ElectronicsMods,BeamWeaponMods" />
  <tag Name="Tier" Value="5" />
  <tag Name="DynamicObjectsTable:Guns" />
  <stag Name="Cold" />
</object>
 
<!-- some more item definitions later... -->
 
<object Name="Flamethrower" Inherits="BaseHeavyWeapon">
  <part Name="Render" Tile="items/sw_flamethrower.bmp" DisplayName="flamethrower" ColorString="&amp;R" TileColor="&amp;c" DetailColor="R"/>
  <part Name="Physics" UsesTwoSlots="true" />
  <part Name="MissileWeapon" Skill="HeavyWeapons" bShowShotsPerAction="false" NoWildfire="true" MaxRange="12" AnimationDelay="20" AmmoChar="f" ShotsPerAction="9" AmmoPerAction="1" ShotsPerAnimation="9" WeaponAccuracy="10" />
  <part Name="Commerce" Value="100" />
  <part Name="LiquidAmmoLoader" Liquid="oil" ProjectileObject="ProjectileFlamethrower" />
  <part Name="LiquidVolume" MaxVolume="32" Volume="32" StartVolume="1d32" InitialLiquid="oil-1000" />
  <part Name="LeakWhenBroken" />
  <part Name="Description" Short="A limpid fuel pump exposes ribbons of oil slick, and behind it a voltage gauge ticks. The slanted heat shield is scorched black." />
  <part Name="Examiner" Alternate="UnknownBackpack" Complexity="4" />
  <part Name="TinkerItem" Bits="0004" CanDisassemble="true" CanBuild="true" />
  <part Name="Metal" />
  <tag Name="TurretName" Value="flamethrower turret" />
  <tag Name="Tier" Value="4" />
  <tag Name="UsesSlots" Value="Back,Missile Weapon,Missile Weapon" />
  <tag Name="DynamicObjectsTable:Guns" />
  <tag Name="ReloadSound" Value="SplashStep1" />
  <tag Name="MissileFireSound" Value="flamethrower" />
  <stag Name="Heat" />
</object>
</syntaxhighlight>
 
If you know a bit about each of these items, you can intuit what some of these parts do. For instance, <code>EnergyCellSocket</code> is clearly related to the ability to insert and use energy cells in freeze rays; <code>LiquidAmmoLoader</code> is somehow connected to the fact that flamethrowers run on oil.
 
In any case, the most important bits right now is this line from the definition of <code>Freeze Ray</code>:
 
<syntaxhighlight lang="xml">
<part Name="EnergyAmmoLoader" ChargeUse="500" ProjectileObject="ProjectileFreezeRay" />
</syntaxhighlight>
 
... and this line from the definition of <code>Flamethrower</code>:
 
<syntaxhighlight lang="xml">
<part Name="LiquidAmmoLoader" Liquid="oil" ProjectileObject="ProjectileFlamethrower" />
</syntaxhighlight>
 
From this, we can see that freeze rays shoot a <code>ProjectileFreezeRay</code> object, and flamethrowers shoot a <code>ProjectileFlamethrower</code> object.
 
To have our new items shoot these projectiles on a cooldown, we're going to add the <code>CooldownAmmoLoader</code> part. Here's how we'll add it to our {{qud text|&Ytome of &Rfire}}:
 
<syntaxhighlight lang="xml">
<object Name="Pyovya_SnapjawMage_Fire Tome" Inherits="Pyovya_SnapjawMage_Magic Tome">
  <part Name="Render" DisplayName="tome of {{R|fire}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;R" DetailColor="Y" />
  <part Name="CooldownAmmoLoader" Cooldown="10" Readout="true" ProjectileObject="ProjectileFlamethrower" />
</object>
</syntaxhighlight>
 
... and here's how we'll add it to our {{qud text|&Ytome of &Cice}}:
 
<syntaxhighlight lang="xml">
<object Name="Pyovya_SnapjawMage_Ice Tome" Inherits="Pyovya_SnapjawMage_Magic Tome">
  <part Name="Render" DisplayName="tome of {{C|ice}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;C" DetailColor="Y" />
  <part Name="CooldownAmmoLoader" Cooldown="10" Readout="true" ProjectileObject="ProjectileFreezeRay" />
</object>
</syntaxhighlight>
 
We also need to add a <code>MissileWeapon</code> part to each of our items, and specify the sound that the item makes when it's fired. Go ahead and update <code>Items.xml</code> until you get the following:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<objects>
<worlds>
   <!-- Skipped: definition of "Pyovya_SnapjawMage_Magic Tome" -->
   <world Name="JoppaWorld" Load="Merge">
 
     <cell Name="Pyovya_SnapjawMage_MageTower" Inherits="Hills" ApplyTo="Pyovya_SnapjawMage_TerrainMageHills" Mutable="false">
  <object Name="Pyovya_SnapjawMage_Fire Tome" Inherits="Pyovya_SnapjawMage_Magic Tome">
      <!-- New zone containing the mage's tower -->
    <part Name="Render" DisplayName="tome of {{R|fire}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;R" DetailColor="Y" />
      <zone Level="10" x="1" y="1" IndefiniteArticle="a" Name="mage's tower" HasWeather="true" WindSpeed="0-60" WindDirections="N,NW,NW,W,W,SW,S,SE" WindDuration="50-3000">
     <part Name="MissileWeapon" AmmoChar="f" ShotsPerAction="1" AmmoPerAction="1" ShotsPerAnimation="1" WeaponAccuracy="0" />
      </zone>
    <part Name="CooldownAmmoLoader" Cooldown="10" Readout="true" ProjectileObject="ProjectileFlamethrower" />
    </cell>
 
   </world>
    <tag Name="MissileFireSound" Value="flamethrower" />
</worlds>
  </object>
 
  <object Name="Pyovya_SnapjawMage_Ice Tome" Inherits="Pyovya_SnapjawMage_Magic Tome">
    <part Name="Render" DisplayName="tome of {{C|ice}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;C" DetailColor="Y" />
    <part Name="MissileWeapon" AmmoChar="FR" ShotsPerAction="1" AmmoPerAction="1" ShotsPerAnimation="1" WeaponAccuracy="0" />
    <part Name="CooldownAmmoLoader" Cooldown="10" Readout="true" ProjectileObject="ProjectileFreezeRay" />
 
    <tag Name="MissileFireSound" Value="hiss_low" />
  </object>
</objects>
</syntaxhighlight>
 
You've successfully added both items to your game! You can now wish for a <code>Pyovya_SnapjawMage_Fire Tome</code> or a <code>Pyovya_SnapjawMage_Ice Tome</code>.
 
[[File:Snapjaw_Mages_--_fire_ice_tomes.webp|600px]]
 
Try equipping the item and firing it as a missile weapon. You should see a streak of fire appear when you shoot the {{qud text|&Ytome of &Rfire}}, and a streak of ice when you shoot the {{qud text|&Ytome of &Cice}}.
 
[[File:Snapjaw Mages -- fire tome activated.webp|600px]]
 
[[File:Snapjaw Mages -- ice tome activated.webp|600px]]
 
=== Adding custom projectiles ===
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | I burnt down all of Joppa with my tome of fire! Take that, Ualraig.
|}
 
Ah, hm, yeah. The projectile that a missile weapon shoots defines the damage and effects of that weapon. We just decided to use the same projectile that {{favilink|flamethrower}} and {{favilink|freeze ray}} use, which in retrospect wasn't the greatest idea. Those are both mid- to late-game items, and we want our new snapjaws to be early-game enemies.
 
Let's fix that by creating some new projectile types that operate in the same way as <code>ProjectileFlamethrower</code> and <code>FreezeRayProjectile</code>, but are a little bit weaker. First, let's look up how these projectiles are defined in the game's data files; you can find them in (the game's version of) <code>ObjectBlueprints/Items.xml</code>.
 
We'll copy those definitions over to our own <code>Items.xml</code> in the folder for our mod. We'll rename these projectiles <code>Pyovya_SnapjawMage_FireTomeProjectile</code> and <code>Pyovya_SnapjawMage_IceTomeProjectile</code>:
 
<syntaxhighlight lang="xml">
<!-- Copied from ProjectileFlamethrower -->
<object Name="Pyovya_SnapjawMage_FireTomeProjectile" Inherits="TemporaryProjectile">
  <part Name="Render" DisplayName="{{R|stream of flame}}" ColorString="&amp;R" />
  <part Name="Projectile" BasePenetration="15" BaseDamage="1d2" Attributes="Heat Fire" ColorString="&amp;R" PassByVerb="whoosh" />
  <part Name="TemperatureOnHit" Amount="4d20" Max="false" OnWielderHit="true" />
  <part Name="TemperatureOnEntering" Amount="8d20" Max="false" OnWielderHit="true" />
</object>
 
<!-- Copied from ProjectileFreezeRay -->
<object Name="Pyovya_SnapjawMage_IceTomeProjectile" Inherits="TemporaryProjectile">
  <part Name="Render" DisplayName="{{C|energy beam}}" ColorString="&amp;B" />
  <part Name="Projectile" BaseDamage="1d4" Attributes="Cold NonPenetrating" ColorString="&amp;B" PassByVerb="crackle" />
  <part Name="TemperatureOnHit" Amount="-190" Max="false" OnWielderHit="true" />
  <part Name="TemperatureOnEntering" Amount="-190" Max="false" OnWielderHit="true" />
</object>
</syntaxhighlight>
 
Let's make some changes to the penetration, base damage, and temperature changes of each of these items. Here's what I set mine to, but go ahead and try tweaking these numbers to different values!
 
<syntaxhighlight lang="xml">
<object Name="Pyovya_SnapjawMage_ProjectileFireTome" Inherits="TemporaryProjectile">
  <part Name="Render" DisplayName="{{R|stream of flame}}" ColorString="&amp;R" />
  <part Name="Projectile" BasePenetration="4" BaseDamage="1d4" Attributes="Heat Fire" ColorString="&amp;R" PassByVerb="whoosh" />
  <part Name="TemperatureOnHit" Amount="4d20" Max="false" OnWielderHit="true" />
  <part Name="TemperatureOnEntering" Amount="8d20" Max="false" OnWielderHit="true" />
</object>
 
<object Name="Pyovya_SnapjawMage_ProjectileIceTome" Inherits="TemporaryProjectile">
  <part Name="Render" DisplayName="{{C|streak of ice}}" ColorString="&amp;B" />
  <part Name="Projectile" BasePenetration="4" BaseDamage="1d4" Attributes="Cold" ColorString="&amp;B" PassByVerb="crackle" />
  <part Name="TemperatureOnHit" Amount="-4d20" Max="false" OnWielderHit="true" />
   <part Name="TemperatureOnEntering" Amount="-8d20" Max="false" OnWielderHit="true" />
</object>
</syntaxhighlight>
 
Now you should change the <code>CooldownAmmoLoader</code> part of your {{qud text|&Ytome of &Rfire}} and {{qud text|&Ytome of &Cice}} objects to use this new projectile.
 
=== Wrapping up ===
 
We can't forget to give our mages their new weapons! Go back to <code>Creatures.xml</code>, and add the following XML tag to <code>Pyovya_SnapjawMage_Fire Mage</code>:
 
<syntaxhighlight lang="xml">
<inventoryobject Blueprint="Pyovya_SnapjawMage_Fire Tome" Number="1" />
</syntaxhighlight>
</syntaxhighlight>


You should also add the {{qud text|&Ytome of &Cice}} to <code>Pyovya_SnapjawMage_Fire Mage</code>'s inventory:
<syntaxhighlight lang="XML">
 
<?xml version="1.0" encoding="utf-8"?>
<syntaxhighlight lang="xml">
<Map Width="80" Height="25">
<inventoryobject Blueprint="Pyovya_SnapjawMage_Ice Tome" Number="1" />
  <cell X="19" Y="23">
    <object Name="Pyovya_SnapjawMage_TerrainMageHills"></object>
  </cell>
</Map>
</syntaxhighlight>
</syntaxhighlight>


Now when you spawn one of your mages, you should find that they already have their magical tomes equipped (and they should start using them against you!).
== Your first dynamic encounter ==
 
[[File:Snapjaw_Mages_--_mage_tome_equipped.webp|600px]]
 
== Controlling spawning: population tables ==
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Well, it looks like I can wish for a <code>Pyovya_SnapjawMage_Fire Tome</code> or a <code>Pyovya_SnapjawMage_Ice Mage</code>. But I can't find them anywhere in the game!
|}
 
That's because there's one thing we're still missing: we haven't told Caves of Qud when and where our new mages should spawn!
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | In fact, it ''is'' already possible for our snapjaw mages to appear in game; it's just that the probability of this happening is very low at the moment. We'll talk about this more when we discuss [[#dynamic population tables|dynamic tables]].
|}
 
Caves of Qud uses '''''population tables''''' to decide when to spawn different items and creatures. Here's an example of one such population table (which you can find in the game data in <code>PopulationTables.xml</code>):
 
<syntaxhighlight lang="xml">
<population Name="SaltMarshZoneGlobals">
  <table Name="StandardSurfaceGlobals" />
  <object Chance="90" Number="160-200" Blueprint="Watervine" />
  <object Chance="90" Number="90-130" Blueprint="Brinestalk" />
  <object Chance="50" Number="6-16" Blueprint="Dogthorn Tree" />
  <object Chance="25" Number="1-4" Blueprint="Witchwood Tree" />
  <object Chance="5" Number="1-4" Blueprint="Starapple Tree" />
 
  <object Chance="50" Blueprint="Croc" />
  <object Chance="75" Number="2d6" Blueprint ="Glowpad" Hint="Aquatic" />
  <object Chance="75" Number="2d4" Blueprint ="Glowfish" Hint="Aquatic" />
  <object Chance="50" Number="2d6" Blueprint ="GiantDragonfly" />
  <group Chance="4" Name="ManySnapjaws" Style="pickeach">
    <table Name="SnapjawParty1" Number="4" />
  </group>
</population>
</syntaxhighlight>
 
This table is used in the [[salt marsh]] to help decide what animals and plants should be spawned. Let's take a look at a few of these lines:
 
* <code>&lt;table Name="StandardSurfaceGlobals" /&gt;</code>: this says that the <code>SaltMarshZoneGlobals</code> table should include all of the contents of another table called <code>StandardSurfaceGlobals</code>. You can find the definition of that table in <code>PopulationTables.xml</code>; it does things like add a chance of a {{favilink|Mechanimist pilgrim}} spawning in each zone.
* <code>&lt;object Chance="50" Blueprint="Croc" /&gt;</code>: this adds a 50% chance of a {{favilink|Croc}} spawning in a given zone.
* <code>&lt;group Chance="4" Name="ManySnapjaws" Style="pickeach"&gt;...&lt;/group&gt;</code>: this defines a "group" in the table. The usage here says (roughly speaking) that there's a 4% chance that we sample some creatures from the <code>SnapjawParty1</code> table.
 
=== Adding snapjaw mages to population tables ===
 
There are a few different snapjaw-related population tables in the data files -- <code>SnapjawParty0</code>, <code>SnapjawParty1</code>, <code>SnapjawParty1-with-Warlord</code>, and <code>SnapjawParty2</code>. Each of these tables is used for different encounters with snapjaws.
 
In your <code>Snapjaw-Mages</code> mod folder, create a new file called <code>PopulationTables.xml</code>:
 
<syntaxhighlight lang="text">
Snapjaw-Mages
├── manifest.json
├── ObjectBlueprints
│   ├── Creatures.xml
│   └── Items.xml
├── PopulationTables.xml
├── preview.png
└── Textures
    └── Pyovya_SnapjawMage
        └── snapjaw_mage.png
</syntaxhighlight>
 
Within this file, start by adding the following:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<populations>
</populations>
</syntaxhighlight>
 
Next, we need to modify the contents of the four tables that we listed previously:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<populations>
  <population Name="SnapjawParty0" Load="Merge">
  </population>
  <population Name="SnapjawParty1" Load="Merge">
  </population>
  <population Name="SnapjawParty1-with-Warlord" Load="Merge">
  </population>
  <population Name="SnapjawParty0" Load="Merge">
  </population>
</populations>
</syntaxhighlight>
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | What does <code>Load="Merge"</code> do?
|}
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | We need to specify <code>Load="Merge"</code> to tell Caves of Qud that we want to merge new XML into an existing table. This prevents us from creating a new population table like (for example) <code>SnapjawParty0</code> that overwrites the old one.
 
It's possible to use <code>Load="Merge"</code> to modify the contents of most of the game's XML files.
|}
 
Each of these tables has a group named <code>Creatures</code>, for instance:
 
<syntaxhighlight lang="xml">
<population Name="SnapjawParty0">
  <group Name="Creatures" Style="pickeach">
    <object Chance="100" Number="1-3" Blueprint="Snapjaw Scavenger 0" />
    <object Chance="75" Number="1-3" Blueprint="Snapjaw Scavenger 0" />
    <object Chance="25" Number="1-3" Blueprint="Snapjaw Hunter 0" />
    <object Chance="2" Number="1" Blueprint="Snapjaw Shotgunner 0" />
    <object Chance="15" Number="1" Blueprint="Snapjaw Brute 0" />
    <object Chance="10,3" Number="1" Blueprint="Snapjaw Warrior 0" />
    <object Chance="10" Number="1" Blueprint="Snapjaw Warlord 0" />
    <object Chance="3" Number="1" Blueprint="Snapjaw Hero 0" />
    <table Name="HumanoidEnvironmentFeatures" Chance="25" />
    <table Name="SnapjawParty0" Chance="10" />
  </group>
</population>
</syntaxhighlight>
 
Because the group has <code>Style="pickeach"</code>, the population table will go over each item (each XML tag) in the group and sample creatures based on the rules defined by that item:
* Based on the first line (<code>&lt;object Chance="100" Number="1-3" Blueprint="Snapjaw Scavenger 0" /&gt;</code>), there's a 100% chance that 1-3 {{favilink|snapjaw scavenger|plural}} spawn).
* The second line (<code>&lt;object Chance="75" Number="1-3" Blueprint="Snapjaw Scavenger 0" /&gt;</code>) adds a 75% chance for an additional 1-3 snapjaw scavengers to spawn.
* The fifth line (<code>&lt;object Chance="15" Number="1" Blueprint="Snapjaw Brute 0" /&gt;</code>) adds a 15% chance for a {{favilink|snapjaw brute}} to spawn.
* The last line (<code>&lt;table Name="SnapjawParty0" Chance="10" /&gt;</code>) adds a 10% chance for another snapjaw party (also sampled from the <code>SnapjawParty0</code> table) to spawn alongside this party.
 
To guarantee that each snapjaw party spawns with a fire mage and an ice mage, we'll merge some new XML into each of these groups:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<populations>
  <population Name="SnapjawParty0" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
    </group>
  </population>
 
  <population Name="SnapjawParty1" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
    </group>
  </population>
 
  <population Name="SnapjawParty1-with-Warlord" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
    </group>
  </population>
 
  <population Name="SnapjawParty0" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
    </group>
  </population>
</populations>
</syntaxhighlight>
 
Now when you encounter a band of roving snapjaws, they should include one fire mage and one ice mage:
 
[[File:Snapjaw Mages -- snapjaw party.webp|600px]]
 
You can use the <code>population:findtable</code> [[wish]] to check the likelihood that a snapjaw mage will spawn in each of the population tables. For instance, here's a snippet from the popup that appears when you wish for <code>population:findtable:Pyovya_SnapjawMage_Fire Mage</code>:
 
[[File:Snapjaw Mages -- poptable probs.webp|600px]]
 
As a result of the XML we merged into <code>PopulationTables.xml</code>, our mage has a 100% chance of appearing in each of the <code>SnapjawMage</code> tables. But we can also see that it has a nonzero chance of appearing in many other population tables; for instance, it has a 97% chance generating inside the {{favilink|waterlogged tunnel}}. That's because the <code>SnapjawParty</code> tables are used in turn by many other population tables for areas where snapjaws may be generated.
 
=== Creating new tables ===
 
Having two mages appear alongside every party of snapjaws feels like a lot -- ideally, we'd have either one fire mage or one ice mage show up. We could try using <code>Chance</code> to reduce the probability of each type of mage showing up, for example:
 
<syntaxhighlight lang="xml">
<object Number="1" Chance="50" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
<object Number="1" Chance="50" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
</syntaxhighlight>
 
But all that does is give us a 50% chance of spawning a fire mage, ''and'' a 50% chance of spawning an ice mage. That means that there's a 25% chance that ''both'' mages show up, and a 25% chance that ''neither'' mage shows up.
 
Instead, we'll define a new population table. This table will be set up so that whenever we sample from it, we either pick a fire mage or an ice mage:
 
<syntaxhighlight lang="xml">
<population Name="Pyovya_SnapjawMage_Mages">
  <group Name="Mages" Style="pickone">
    <object Number="1" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
    <object Number="1" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
  </group>
</population>
</syntaxhighlight>
 
By giving the <code>Mages</code> group <code>Style="pickone"</code>, we're telling the game "whenever we pick an item from the <code>Pyovya_SnapjawMage_Mages</code> table, we want to pick just one of the items listed in our <code>Mages</code> group".
Now we can change the XML that we merged into the <code>SnapjawParty</code> tables to sample from our new table instead. Our final <code>Populations.xml</code> table will look like this:
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<populations>
  <population Name="Pyovya_SnapjawMage_Mages">
    <group Name="Mages" Style="pickone">
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Fire Mage" />
      <object Number="1" Blueprint="Pyovya_SnapjawMage_Ice Mage" />
    </group>
  </population>
 
  <population Name="SnapjawParty0" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <table Name="Pyovya_SnapjawMage_Mages" />
    </group>
  </population>
 
  <population Name="SnapjawParty1" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <table Name="Pyovya_SnapjawMage_Mages" />
    </group>
  </population>
 
  <population Name="SnapjawParty1-with-Warlord" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <table Name="Pyovya_SnapjawMage_Mages" />
    </group>
  </population>
 
  <population Name="SnapjawParty0" Load="Merge">
    <group Name="Creatures" Load="Merge">
      <table Name="Pyovya_SnapjawMage_Mages" />
    </group>
  </population>
</populations>
</syntaxhighlight>
 
After this change, snapjaw parties that we run across will only have one mage, rather than two.
 
=== Dynamic population tables ===
 
So far, the tables we've been working with have been '''''static''''' -- they're pre-defined based on the contents of <code>PopulationTables.xml</code>. It's also possible to generate a '''''dynamic''''' population table, which is generated based on the tags that creatures have as well as their relationship to one another. For instance, let's take a look at the definition of {{favilink|shrewd baboon}} in the game's <code>ObjectBlueprints/Creatures.xml</code>:
 
<syntaxhighlight lang="xml">
<object Name="Shrewd Baboon" Inherits="Baboon">
  <part Name="Render" DisplayName="shrewd baboon" ColorString="&amp;B" />
  <stat Name="AV" Value="3" />
  <stat Name="Intelligence" Boost="1" />
  <stat Name="Hitpoints" Value="20" />
  <property Name="Role" Value="Leader" />
  <tag Name="DynamicObjectsTable:Baboons" />
</object>
</syntaxhighlight>
 
The <code>&lt;tag Name="DynamicObjectsTable:Baboons" /&gt;</code> XML at the end adds the shrewd baboon to the "Baboons" dynamic table.
 
Caves of Qud primarily uses dynamic tables when it needs to be be able to get one of a particular type of item or creature -- for instance, a random type of [[energy cell]] or a random type of [[goatfolk]]. This is useful, for example, for identifying what creatures are able to own a lair.
 
There are several ways to create a dynamic table:
 
* Through <code>DynamicObjectsTable</code>, such as the <code>DynamicObjectsTable:Baboons</code> table in the previous example. These tables contain all objects explicitly tagged as belonging to that table.
* Through the use of <code>DynamicInheritsTable</code>. These tables include all objects that inherit from another object. This inheritance doesn't need to be direct -- for example, even though {{favilink|shrewd baboon}} doesn't inherit from <code>Creature</code> (it inherits from <code>Baboon</code>), it would still fall under the dynamic inherits table for <code>Creature</code> since <code>Baboon</code> inherits from <code>BaseApe</code>, which in turn inherits from <code>Humanoid</code>, and which finally inherits from <code>Creature</code>.
* Through a <code>DynamicSemanticTable</code>. A dynamic semantic table contains all objects that fall into several intersecting categories, such as "medical" and "furniture".
 
Finally, it's also possible to exclude an object from a dynamic table by using <code>ExcludeFromDynamicEncounters</code>. Check out the [[Modding:Encounters and Population]] page for more information on how dynamic tables work.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Because snapjaw mages are descended from the Snapjaw object, which in turn ultimately descends from the Creature object, it turns out that snapjaw mages were already included in some population tables before we started writing <code>PopulationTables.xml</code>! In particular, snapjaw mages could appear in the <code>DynamicInheritsTable:Creatures</code> table, although the probability of them being generated was pretty low.
|}
 
Returning to our mod: there's a <code>Snapjaws</code> dynamic table that we can add our mages to. Doing so is fairly straightforward: open up <code>Creatures.xml</code> and add the following tag at the end of the definition of <code>Pyovya_SnapjawMage_Fire Mage</code> and <code>Pyovya_SnapjawMage_Ice Mage</code>:
 
<syntaxhighlight lang="xml">
<tag Name="DynamicObjectsTable:Snapjaws" />
</syntaxhighlight>
 
One result of adding this tag is that legendary snapjaw mage lairs can now appear! Here's one that I found while traversing the overworld:
 
[[File:Snapjaw Mages -- travelnote fire mage.webp|600px]]
[[File:Snapjaw_Mages_--_legendary_fire_mage.webp|600px]]
 
== Conclusion ==
 
Congrats! You reached the end of the tutorial!
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Woohoo!
|}
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | I'm ready to go face these mages in magical combat.
|}
 
=== Extra challenge ===
 
Before you go, here's a little challenge that you can use to test what you've learned so far. We now have mages of fire and ice; now, try creating a new {{qud text|&Ysnapjaw &Welectric &Ymage}}, along with a {{qud text|&Ytome of &Welectricity}} that shoots electric projectiles. You're free to go about this however you wish, but here are some general pointers:
 
* You'll probably want to give your new mage the {{favilink|Electrical Generation}} mutation.
* When you're creating your {{qud text|&Ytome of &Welectricity}}, start by having it shoot <code>ProjectileElectroPistol</code>; this is the projectile that is shot by an {{favilink|arc winder}}. Once you're ready, create your own version of this projectile by referring to how <code>ProjectileElectroPistol</code> is implemented in the game's version of <code>ObjectBlueprints/Items.xml</code>.
 
=== Next steps ===
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em; min-width: 40px;"| [[File:Sprouting orb.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | What should I do if I want to start designing my own creatures?
|}
 
First off, make sure you read the other [[Modding]] pages! They're a treasure trove of valuable information about the various systems that exist in Caves of Qud and how to work with them.


You should definitely spend some time looking at how the game implements different creatures and items. This is the easiest way to learn about existing parts. If you have a good understanding of how a creature behaves in-game, you can look at how they're defined in <code>Creatures.xml</code> and intuit how the parts that have been applied to that creature affect its behavior.
=== World generation ===


Personally, I also find it helpful to look at other people's mods. There's a section in the [[Modding:Overview]] page that includes links to the source code for mods that people have written; it's a valuable reference for figuring out how other people have written mods for Caves of Qud.
* Locate zone to place tower
* Place creature


Finally, feel free to ask for help in the Caves of Qud and Kitfox Discords! We have a steadily-growing community of modders who are all excited to help you out. :)
=== Zone builders ===


{{Modding Navbox}}
* Place walls and items
[[Category:Modding Resources]]
* Add map template.
[[Category:Guides]]