Modding:Genotypes and Subtypes

From Caves of Qud Wiki
Jump to navigation Jump to search
This page is about modding. See the modding overview for an abstract on modding.
This page is about modding. See the modding overview for an abstract on modding.

Genotypes and subtypes can be created with only some basic XML files. No scripting is required.

Creating a new genotype

Genotypes are high-level categories that a subtype can belong to, such as "Mutant" and "True Kin". Genotypes are defined in Genotypes.xml, which is structured as follows:

XML tag Description
<genotype> Defines top-level properties of a genotype, including
  • Name: the name of the genotype;
  • MutationPoints: the number of mutation points (for purchasing mutations in the mutation selection screen) that the genotype should start with;
  • StatPoints: the number of stat points that the genotype should have available for allocation;
  • BaseHPGain, BaseSPGain, BaseMPGain: the number of hitpoints, skill points, and mutation points that the genotype should gain per level;
  • AllowedMutationCategories: the mutation categories (as defined by the category tags in Mutations.xml that the genotype should be able to pick up;
  • RandomWeight: the likelihood of picking this genotype when random creating a character;
  • DisplayName: how the name of the genotype should be displayed in the character creation UI;
  • Subtypes: the name of the subtype class in Subtypes.xml that should be used for this genotype's subtypes;
  • Tile, DetailColor: the tile for the genotype and its color, as displayed in the character creation UI;
  • BodyObject: the game object blueprint that should be used for this genotype's body;
  • Species: the species of a character with this genotype (used by morphogenetic and a handful of other things);
  • IsMutant: whether or not characters with this genotype are considered mutants (used by e.g. tonics when determining effects);
  • CharacterBuilderModules: unused (#12181).
<stat> The starting value for a particular statistic for the genotype.
<skills> The skills that should be granted to the player by default upon starting the game.
<reputations> Starting reputations with different factions for starting the game as the given genotype. Note that <reputations> is preferred over specifying a Reputation="..." attribute in the <genotype> tag (which used to be the main way to set starting reputations).
<extrainfo> Additional info that should appear underneath the genotype when the player is choosing a genotype.

Creating a new subtype

Subtypes define more specific starting characteristics and are defined per-genotype. For Mutants the subtypes are callings, whereas for True Kin the subtypes are castes.

The game defines the default subtypes in Subtypes.xml. This file is structured as follows:

XML tag Description
<class> Defines a class of subtypes belonging to a single genotype. For example, the class with ID="Callings" corresponds to the various Mutated Human callings.
<category> An optional tag that allows you to subdivide the subtypes into further categories. The effects of this tag are purely aesthetic. This tag is used by the True Kin castes to define the different arcologies that they originate from.
<subtype> Defines high-level properties of a single subtype, such as its name, starting gear, tile, and so on. Note that the Gear attribute specifies a population table that the subtype's inventory should be sampled from.
<stat> Adds bonuses to a stat for a given subtype.
<skills> Defines skills that the subtype starts with.
<savemodifiers> Adds bonuses to saving throws against different negative effects.
<reputations> Adds bonuses to starting reputation.
<extrainfo> Allows you to put additional information underneath the description of a subtype in the subtype selection screen.

Custom naming conventions

This article is a stub. You can help Caves of Qud Wiki by expanding it.
This article is a stub. You can help Caves of Qud Wiki by expanding it.

You can define custom names for subtypes by writing a Naming.xml with namestyles assigned to those subtypes (naming is assigned on a subtype level rather than by genotype).

Example: a snapjaw genotype

This article has information that is missing or not up to par.
Reason: This example should also include some details on how to use the snapjaw naming conventions for the player.

This section will step you through an example of creating a snapjaw genotype, with custom subtypes. (If you're interested in such a mod, check out Playable Snapjaws, which served as a loose inspiration for this example, although none of the code shown here is pulled from the mod). If this is your first time writing a mod, consider checking out the Snapjaw Mages tutorial, which will provide some context on how to structure your mod files.

Genotypes.xml

First, we will define a Genotypes.xml file. For demonstration purposes, our Snapjaw genotype will be mostly identical to the Mutated Human genotype, with the following differences:

  • We change the tile used to represent the genotype in the genotype selection screen; see the Modding:Tiles article for more information on how this tile is specified.
  • The character's species will be snapjaw rather than human.
  • It will have a lower RandomWeight (which will make us less likely to pick it when generating a random character).
  • Players with the snapjaw genotype will start with 0 reputation with the snapjaws faction (rather than the default -475).
  • We define a custom body object as well, which we will define shortly.
<?xml version="1.0" encoding="utf-8" ?>
<genotypes>
  <genotype Name="Snapjaw" MutationPoints="12" StatPoints="44" AllowedMutationCategories="*"
    RandomWeight="10" DisplayName="Snapjaw" Subtypes="Snapjaws" Class="" Tile="Assets_Content_Textures_Creatures_sw_snapjaw.bmp"
    DetailColor="R" BodyObject="SnapjawBody" BaseHPGain="1-4" BaseSPGain="50" BaseMPGain="1" Species="snapjaw"
    IsMutant="true" CharacterBuilderModules="">

    <!-- Stats -->
    <stat Name="Strength" Minimum="10" Maximum="24" ChargenDescription="Your {{W|Strength}} score determines how effectively you penetrate your opponents' armor with melee attacks, how much damage your melee attacks do, your ability to resist forced movement, and your carry capacity."/>
    <stat Name="Agility" Minimum="10" Maximum="24" ChargenDescription="Your {{W|Agility}} score determines your accuracy with both melee and ranged weapons and your ability to dodge attacks."/>
    <stat Name="Toughness" Minimum="10" Maximum="24" ChargenDescription="Your {{W|Toughness}} score determines your number of hit points, your natural healing rate, and your ability to resist poison and disease."/>
    <stat Name="Intelligence" Minimum="10" Maximum="24" ChargenDescription="Your {{W|Intelligence}} score determines your number of skill points and your ability to examine artifacts."/>
    <stat Name="Willpower" Minimum="10" Maximum="24" ChargenDescription="Your {{W|Willpower}} score modifies the cooldowns of your activated abilities, determines your ability to resist mental attacks, and modifies your natural healing rate."/>
    <stat Name="Ego" Minimum="10" Maximum="24" ChargenDescription="Your {{W|Ego}} score determines the potency of your mental mutations, your ability to haggle with merchants, and your ability to dominate the wills of other living creatures."/>

    <!-- Skills -->
    <skills>
      <skill Name="Tactics_Run" />
      <skill Name="Survival_Camp" />
    </skills>

    <!-- Reputation -->
    <reputations>
      <reputation With="Snapjaws" Value="475" />
    </reputations>

    <extrainfo>Mutations</extrainfo>
    <extrainfo>Starts with Heightened Smell</extrainfo>
    <extrainfo>Moderate starting attributes</extrainfo>
    <extrainfo>-600 reputation with {{C|the Putus Templar}}</extrainfo>
    <extrainfo>0 reputation with {{C|snapjaws}}</extrainfo>
  </genotype>
</genotypes>

ObjectBlueprints.xml

Since we specified a custom body object for the player, we must add an object blueprint for SnapjawBody. Below is a SnapjawBody implementation that uses the standard snapjaw sounds for various actions, and gives the player the Heightened Smell mutation by default:

<?xml version="1.0" encoding="utf-8" ?>
<objects>
  <!-- Custom body object for the snapjaw genotype -->
  <object Name="SnapjawBody" Inherits="Humanoid">
    <!-- Define the sounds the player should make -->
    <tag Name="AmbientIdleSound" Value="Sounds/Creatures/VO/sfx_creature_animal_snapjaw_vo_idle"/>
    <tag Name="PunchSound" Value="Sounds/Creatures/VO/sfx_creature_animal_snapjaw_vo_attack"/>
    <tag Name="DeathSounds" Value="Sounds/Creatures/VO/sfx_creature_animal_snapjaw_vo_die" />
    <tag Name="TakeDamageSound" Value="Sounds/Creatures/VO/sfx_creature_animal_snapjaw_vo_hurt"/>
    <tag Name="LairAmbientBed" Value="Sounds/Ambiences/amb_creature_snapjaw" />
    <!-- Snapjaws have Heightened Smell by default. -->
    <mutation Name="HeightenedSmell" Level="1" />
  </object>
</objects>

Note that if we kept the default Humanoid body used by Mutated Humans (instead of SnapjawBody) we could have skipped this part altogether.

Subtypes.xml

Now let's define three different subtypes for our snapjaw genotype, corresponding to the snapjaw scavenger, snapjaw brute, and snapjaw shotgunner.

Regarding tile orientation

To make it as easy as possible for you to test these genotypes and subtypes and use them as a template for your own code, I have used the default snapjaw scavenger, snapjaw brute, and snapjaw shotgunner tiles from the base game. However, an important stylistic element in Caves of Qud is that the player tile always points right, while every other creature's tile points left (with some limited exceptions).

For a real mod, you would want to take these tiles and flip them horizontally for the subtypes, so that they point to the right.

<?xml version="1.0" encoding="utf-8" ?>
<subtypes>
  <!--
    I did not attempt to balance these subtypes at all; you should probably choose skills a
    little more carefully when creating your subtypes.
  -->

  <class ID="Snapjaws" ChargenTitle="choose calling" SingularTitle="calling">

    <!--
      We will need to define the following custom population tables for our subtypes'
      starting gear:
      * StartingGear_SnapjawScavenger
      * StartingGear_SnapjawBrute
      * StartingGear_SnapjawShotgunner
    -->

    <subtype Name="Scavenger" Gear="StartingGear_SnapjawScavenger" Tile="Assets_Content_Textures_Creatures_sw_snapjaw.bmp" DetailColor="R">
      <stat Name="Toughness" Bonus="2" />
      <skills>
        <skill Name="Survival" />
        <skill Name="Survival_DesertCanyonSurvival" />
        <skill Name="Tinkering_Scavenger" />
        <skill Name="Endurance_Longstrider" />
      </skills>
    </subtype>

    <subtype Name="Brute" Gear="StartingGear_SnapjawBrute" Tile="Assets_Content_Textures_Creatures_sw_snapjaw_bruiser.bmp" DetailColor="R">
      <stat Name="Strength" Bonus="2" />
      <skills>
        <skill Name="Axe_Expertise" />
        <skill Name="Axe_ChargingStrike" />
        <skill Name="Tactics_Charge" />
        <skill Name="Endurance_Weathered" />
      </skills>
    </subtype>

    <subtype Name="Shotgunner" Gear="StartingGear_SnapjawShotgunner" Tile="Assets_Content_Textures_Creatures_sw_snapjaw_gunner.bmp" DetailColor="r">
      <stat Name="Agility" Bonus="2" />
      <skills>
        <skill Name="Acrobatics_Dodge" />
        <skill Name="CookingAndGathering" />
        <skill Name="CookingAndGathering_Butchery" />
        <skill Name="Rifles" />
      </skills>
      <extrainfo>Starts with some ingredients and a cookbook</extrainfo>
    </subtype>

  </class>
</subtypes>

PopulationTables.xml

Finally, we need to define the population tables with the starting gear for each subtype. In your PopulationTables.xml file, you should define each of the StartingGear_SnapjawScavenger, StartingGear_SnapjawBrute, and StartingGear_SnapjawShotgunner tables, e.g.

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

  <!-- Starting gear common to all snapjaw subtypes -->
  <population Name="StartingGear_SnapjawCommon">
    <group Name="Items" Style="pickeach">
      <!--
        All subtypes have gear from StartingGear_Common, which provides some
        empty waterskins and torches.
      -->
      <table Name="StartingGear_Common" />
      <table Name="HumanoidEquipment 1" />
      <object Blueprint="HalfFullWaterskin" Number="2-3" />
      <object Blueprint="Witchwood Bark" Number="3-4" />
      <!--
        We have to explicitly give each snapjaw subtype the Snapjaw_Bite
        natural equipment, otherwise they won't have it.
      -->
      <object Blueprint="Snapjaw_Bite" Number="1" />
    </group>
  </population>

  <!-- Starting gear for individual snapjaw subtypes -->
  <population Name="StartingGear_SnapjawScavenger">
    <group Name="Items" Style="pickeach">
      <!--
        The snapjaw scavenger gets some random junk
      -->
      <table Name="StartingGear_SnapjawCommon" />
      <table Name="Junk 1" Number="3-4" />
      <table Name="Food 1" Number="3-4" />
    </group>
  </population>
  <population Name="StartingGear_SnapjawBrute">
    <group Name="Items" Style="pickeach">
      <!--
        We don't give anything in particular to the brute outside
        of the default equipment
      -->
      <table Name="StartingGear_SnapjawCommon" />
    </group>
  </population>
  <population Name="StartingGear_SnapjawShotgunner">
    <group Name="Items" Style="pickeach">
      <!--
        We give the shotgunner a shotgun and some ingredients to
        make food
      -->
      <table Name="StartingGear_SnapjawCommon" />
      <table Name="Ingredients1" Number="4-5" />
      <table Name="Food 1" Number="2-3" />
      <table Name="Cookbooks" Number="1" />
      <object Blueprint="Pump Shotgun" Number="1" />
      <object Blueprint="Shotgun Shell" Number="150-200" />
      <object Blueprint="Woven Tunic" Number="1" />
      <object Blueprint="Dagger" Number="1" />
    </group>
  </population>
</populations>

With all of these pieces in place, you should now see the snapjaw genotype appear when starting a new game.

Snapjaw genotype example.webp

Snapjaw subtype example.webp