User:Kernelmethod/Sandbox: Difference between revisions

m
Add some XML fragments to the static encounters section
No edit summary
m (Add some XML fragments to the static encounters section)
 
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
Modding Tutorial: ''Snapjaw Mages!''
== Tutorial: Mage Towers (static and dynamic encounters) ==


Welcome! If you're looking to get started with modding 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;"| [[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;"| [[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 new mod which
Other:


* introduces two new creatures, the {{qud text|snapjaw &Rfire &Ymage}} and the {{qud text|snapjaw &Cice &Ymage}}, and
* https://bitbucket.org/bbucklew/cavesofqud-public-issue-tracker/issues/9458/modding-feature-request-allow-for-merging
* introduces two books that function as missile weapons, the {{qud text|tome of &Rfire}} and the {{qud text|tome 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 ==


== Getting started, and basic concepts ==
* Editing cell definition in Worlds.xml
* Add a new population table to a cell.
* Create a map template with the map editor.


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].
<syntaxhighlight lang="XML">
 
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 new <code>_Quickstart</code> 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''' (the e'''X'''tended '''M'''arkup '''L'''anguage) is a type of ''markup language'', which (loosely speaking) is a text-based document format that can be read and interpreted 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 what's called 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}}.
 
== Creating a mod ==
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| style = "border:1px solid #155352;padding:0.5em 1em;" | Let's get started!
|}
 
The first thing we'll do is create 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 new folder called <code>SnapjawMage</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 new file called <code>manifest.json</code> inside the <code>SnapjawMage/</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;"| [[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:
 
IMAGE DOWNLOAD LINK
 
Download this image and place it in the <code>SnapjawMage/</code> folder, so that now your folder looks like this:
 
<syntaxhighlight lang="text">
SnapjawMage
├── 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 new "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;"| [[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>).
|}
 
== Your first creature ==
 
=== Adding a new creature to <code>Creatures.xml</code> ===
 
In your mod directory, create a new folder called <code>ObjectBlueprints/</code>, and within that folder open up a new 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">
SnapjawMage
├── manifest.json
├── ObjectBlueprints
│  └── Creatures.xml
└── preview.png
</syntaxhighlight>
 
With that out of the way, let's start adding our new 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 new 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;"| [[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;"| [[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 new 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;"| [[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;"| [[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 new parts to our creature: <code>Render</code> and <code>Description</code>.
     https://bitbucket.org/bbucklew/cavesofqud-public-issue-tracker/issues/10902
 
<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 new XML we've added, save <code>Creatures.xml</code>. Reload your mods, start a new game and wish for a <code>Pyovya_SnapjawMage_Snapjaw Mage</code>. You should see a new snapjaw like the one below show up:
 
[[File:Snapjaw_Mages_--_Initial_mage.webp|700px]]
 
Congrats! You've successfully added a snapjaw mage to your game.
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em;"| [[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;"| [[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;"| [[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:
 
DOWNLOAD LINK FOR NEW TILE
 
In your mod directory, create a new folder called <code>Textures/</code>; in that folder, create a new subfolder called <code>Pyovya_SnapjawMage/</code>; and in there, create another subfolder called <code>Creatures/</code>. Save <code>snapjaw_mage.png</code> there, so that your mod folder now looks like this:
 
<syntaxhighlight lang="text">
SnapjawMage
├── 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 new 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 new furry friend.
 
=== Adding inventory ===
 
We'll keep adding stuff to our snapjaw mage to round them out a bit more. First of all, like any good mage, they need a {{favilink|walking stick}} and some [[book|books]]. Let's 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="Woven Tunic" 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>
 
=== Minor details ===
 
TODO
 
<syntaxhighlight lang="xml">
<property Name="Role" Value="Artillery" />
</syntaxhighlight>
 
TODO
 
<syntaxhighlight lang="xml">
<tag Name="DynamicObjectsTable:Snapjaws" />
<tag Name="AggregateWith" Value="Pyovya_SnapjawMage_Snapjaw Mage" />
</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="Woven Tunic" 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" />
 
    <property Name="Role" Value="Artillery" />
    <tag Name="DynamicObjectsTable:Snapjaws" />
    <tag Name="AggregateWith" Value="Pyovya_SnapjawMage_Snapjaw Mage" />
  </object>
</objects>
</syntaxhighlight>
 
== Using your creature as a base: Elemental Mages ==
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em;"| [[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'''''. The first thing we're going to do is mark the snapjaw mage 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
      get replaced with a random hills tile.
    -->
    <removepart Name="RandomTile" />
    <!--
      We modify grammatical usage of the terrain's name so that when we pass it by
      on the world map, it says that we pass by "a mage's tower" rather than "some
      mage's tower" or "a set of mage's tower".
    -->
    <xtagGrammar Proper="false" massNoun="false" />
    <tag Name="Gender" Value="*delete" />
   </object>
   </object>
</objects>
</objects>
</syntaxhighlight>
</syntaxhighlight>


{| style = "margin: 1em;font-family:Source Code Pro;"
<syntaxhighlight lang="XML">
| style = "padding:0em 1em;"| [[File:Mopango_pilgrim.png|40px]]
| style= "color:#155352" | <
| 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 new creatures will spawn with walking sticks, have the [[Cudgel]] skill, and so on.
|}
 
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]]
 
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<objects>
<worlds>
   <object Name="Pyovya_SnapjawMage_Snapjaw Mage" Inherits="Snapjaw">
   <world Name="JoppaWorld" Load="Merge">
     <part Name="Description" Short="Tussocks of fur dress skin stretched over taut muscle." />
     <cell Name="Pyovya_SnapjawMage_MageTower" Inherits="Hills" ApplyTo="Pyovya_SnapjawMage_TerrainMageHills" Mutable="false">
    <part Name="Render" DisplayName="snapjaw mage" Tile="Pyovya_SnapjawMage/snapjaw_mage.png" ColorString="&amp;O" DetailColor="Y" />
      <!-- New zone containing the mage's tower -->
 
      <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">
    <inventoryobject Blueprint="Walking Stick" Number="1" />
      </zone>
    <inventoryobject Blueprint="Woven Tunic" Number="1" />
     </cell>
    <inventoryobject Blueprint="Sandals" Number="1" />
   </world>
    <inventoryobject Blueprint="StandaloneMarkovBook" Number="1-2" Chance="10" />
</worlds>
 
    <skill Name="Cudgel" />
 
    <stat Name="Hitpoints" Value="15" />
    <stat Name="DV" Value="4" />
    <stat Name="Ego" Value="17" />
    <stat Name="Willpower" Value="17" />
 
    <property Name="Role" Value="Artillery" />
    <tag Name="DynamicObjectsTable:Snapjaws" />
    <tag Name="AggregateWith" Value="Pyovya_SnapjawMage_Snapjaw Mage" />
    <tag Name="BaseObject" Value="*noinherit" />
  </object>
 
  <object Name="Pyovya_SnapjawMage_Fire Mage" Inherits="Pyovya_SnapjawMage_Snapjaw 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>
 
  <object Name="Pyovya_SnapjawMage_Ice Mage" Inherits="Pyovya_SnapjawMage_Snapjaw 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>
</objects>
</syntaxhighlight>
</syntaxhighlight>


== Creating new items ==
<syntaxhighlight lang="XML">
 
<?xml version="1.0" encoding="utf-8"?>
TODO: magical tome of fire + magical tome of ice
<Map Width="80" Height="25">
 
   <cell X="19" Y="23">
Proof-of-concept:
     <object Name="Pyovya_SnapjawMage_TerrainMageHills"></object>
 
   </cell>
<syntaxhighlight lang="xml">
</Map>
<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <!-- Weapons -->
  <object Name="Pvovya_SnapjawMage_Magic Tome" Inherits="BaseMissileWeapon">
    <part Name="Description" Short="A magical tome." />
    <part Name="Physics" Weight="1" UsesTwoSlots="true" Category="Missile Weapon" />
    <part Name="Commerce" Value="200" />
 
    <tag Name="Tier" Value="2" />
    <tag Name="BaseObject" Value="*noinherit" />
  </object>
 
  <object Name="Pvovya_SnapjawMage_Fire Tome" Inherits="Pvovya_SnapjawMage_Magic Tome">
    <part Name="Render" DisplayName="tome of {{R|fire}}" Tile="Items/sw_book_1.bmp" ColorString="&amp;R" DetailColor="Y" />
    <part Name="MissileWeapon" Skill="Rifle" AmmoChar="f" ShotsPerAction="1" AmmoPerAction="1" ShotsPerAnimation="1" WeaponAccuracy="0" />
    <part Name="CooldownAmmoLoader" Cooldown="10" Readout="true" ProjectileObject="Pvovya_SnapjawMage_FireTomeProjectile" />
 
    <tag Name="MissileFireSound" Value="flamethrower" />
    <stag Name="Heat" />
   </object>
 
  <object Name="Pvovya_SnapjawMage_Ice Tome" Inherits="Pvovya_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" Skill="Rifle" AmmoChar="FR" ShotsPerAction="1" AmmoPerAction="1" ShotsPerAnimation="1" WeaponAccuracy="0" />
     <part Name="CooldownAmmoLoader" Cooldown="10" Readout="true" ProjectileObject="Pvovya_SnapjawMage_IceTomeProjectile" />
 
    <tag Name="MissileFireSound" Value="hiss_low" />
    <stag Name="Cold" />
  </object>
 
  <!-- Projectiles -->
  <object Name="Pvovya_SnapjawMage_FireTomeProjectile" Inherits="TemporaryProjectile">
    <part Name="Render" DisplayName="{{R|stream of flame}}" ColorString="&amp;R" />
    <part Name="Projectile" BasePenetration="8" 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>
 
   <object Name="Pvovya_SnapjawMage_IceTomeProjectile" Inherits="TemporaryProjectile">
    <part Name="Render" DisplayName="{{C|streak of ice}}" ColorString="&amp;B" />
    <part Name="Projectile" BasePenetration="4" BaseDamage="1d4" Attributes="Cold NonPenetrating" ColorString="&amp;B" PassByVerb="crackle" />
    <part Name="TemperatureOnHit" Amount="-4d20" Max="false" OnWielderHit="true" />
    <part Name="TemperatureOnEntering" Amount="-8d20" Max="false" OnWielderHit="true" />
  </object>
</objects>
</syntaxhighlight>
</syntaxhighlight>


== Going forward ==
== Your first dynamic encounter ==
 
Congrats! You reached the end of the tutorial!
 
{| style = "margin: 1em;font-family:Source Code Pro;"
| style = "padding:0em 1em;"| [[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;"| [[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 ===
=== World generation ===


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|snapjaw &Welectric &Ymage}}, along with a {{qud text|tome of &Welectricity}} that shoots electric projectiles. You're free to go about this however you wish, but here are some general pointers:
* Locate zone to place tower
* Place creature


* You'll probably want to give your new mage the {{favilink|Electrical Generation}} mutation.
=== Zone builders ===
* When you're creating your {{qud text|tome 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>.


[[Category:Guides]]
* Place walls and items
* Add map template.