Monster Tutorial - dredmor-com/dungeons-of-dredmor GitHub Wiki
The monster file is a daunting piece of code very few modders have touched, mostly because nobody can draw.
As usual for the mod files, you might need some previous setup if you haven't done so yet. Otherwise, you can start by creating a file called 'monDB.xml'. When editing it, make sure it starts with <monDB>
and ends with </monDB>
. Individual monsters are contained between a <monster>...</monster>
tag pair.
We'll first look at a most classical enemy, the Diggle, and some of its most common variants:
<monster name="Diggle" level="0" tiny="1" splat="blood" taxa="Animal">
<idleSprite left="sprites/monster/diggle/diggle_run_l.spr" right="sprites/monster/diggle/diggle_run_r.spr" up="sprites/monster/diggle/diggle_run_u.spr" down="sprites/monster/diggle/diggle_run_d.spr"/>
<attackSprite left="sprites/monster/diggle/diggle_atk_l.spr" right="sprites/monster/diggle/diggle_atk_r.spr" up="sprites/monster/diggle/diggle_atk_u.spr" down="sprites/monster/diggle/diggle_atk_d.spr"/>
<hitSprite left="sprites/monster/diggle/diggle_hit_l.spr" right="sprites/monster/diggle/diggle_hit_r.spr" up="sprites/monster/diggle/diggle_hit_u.spr" down="sprites/monster/diggle/diggle_hit_d.spr"/>
<morphsprites
eatSprite="sprites/monster/diggle/diggle_eat.xml"
drinkSprite="sprites/monster/diggle/diggle_drink.xml"
levelupmSprite="sprites/monster/diggle/diggle_levelup_male.xml"
levelupfSprite="sprites/monster/diggle/diggle_levelup_female.xml"
vanishSprite="sprites/monster/diggle/diggle_vanish.xml"
longidleSprite="sprites/monster/diggle/diggle_long_idle.xml"/>
<dieSprite name="sprites/monster/diggle/diggle_die_r.spr"/>
<sfx attack="diggle_attack" hit="diggle_damage" die="diggle_die" spell="diggle_cast"/>
<ai aggressiveness="4" span="10" />
<!--<drop name="Native Gold" percent="75" />-->
<stats numFig="3" xpValue="10" />
<damage slashing="1" piercing="2"/>
<secondarybuff id="4" amount="-10"/> <!-- crit -->
<secondarybuff id="6" amount="4"/> <!-- dodge -->
<secondarybuff id="0" amount="-2"/> <!-- hp -->
<info latin="(Poingus Poingus)" text="A strange little bird-thing that tunnels through walls with its odd, rubbery nasal appliance."/>
<monster name="Sickly Diggle" level="0">
<palette tint="40"/>
<onhit spell="Diggle Flu" onechancein="5"/>
<resistances toxic="2"/>
<damage slashing="1" piercing="1" toxic="2"/>
<stats numFig="2" numRog="1" xpValue="7"/>
<secondarybuff id="0" amount="-4"/> <!-- hp -->
<secondarybuff id="4" amount="-5"/> <!-- crit -->
<secondarybuff id="6" amount="4"/> <!-- dodge -->
<info latin="(Poingus Poingus)" text="A strange little bird-thing that tunnels through walls with its odd, rubbery nasal appliance. This one looks like it has some kind of disease."/>
</monster>
<monster name="Enraged Diggle" level="1">
<palette tint="-40"/>
<damage slashing="3" piercing="2" />
<stats numFig="5" xpValue="16"/>
<secondarybuff id="10" amount="1"/> <!-- armour -->
<info latin="(Poingus Poingus)" text="A strange little bird-thing that tunnels through walls with its odd, rubbery nasal appliance. This one looks really mad."/>
<ai aggressiveness="5" span="24" spellPercentage="3"/>
<spell name="Monstrous Rage"/>
</monster>
<monster name="Arch Diggle" level="9">
<palette tint="-111"/>
<damage slashing="12" piercing="16" />
<stats numFig="15" numRog="15" xpValue="150"/>
<secondarybuff id="10" amount="8"/> <!-- armour -->
<info latin="(Poingus Poingus)" text="The secret leaders of Diggle society. (Such as it is.)"/>
</monster>
<monster name="Diggle Commando" level="4">
<palette tint="-180"/>
<damage slashing="1" piercing="6"/>
<stats numFig="5" numRog="6" xpValue="53"/>
<secondarybuff id="10" amount="5"/> <!-- armour -->
<info latin="(Poingus Poingus)" text="The fearsome Diggle Commando sneaks through the dungeons, being all it can be."/>
<ai aggressiveness="5" span="24" spellPercentage="5" invisible="1"/>
</monster>
<monster name="Hungry Diggle" level="7">
<palette tint="-200"/>
<damage slashing="2" piercing="10"/>
<stats numFig="9" numRog="6" xpValue="75"/>
<secondarybuff id="10" amount="6"/>
<!-- armour -->
<onhit spell="Consume Food" onechancein="5"/>
<info latin="(Poingus Poingus)" text="It's so hungry. So very, VERY hungry."/>
<ai aggressiveness="55" span="24"/>
</monster>
<monster name="Thirsty Diggle" level="11">
<palette tint="-140"/>
<damage slashing="10" piercing="22"/>
<stats numFig="16" numRog="16" xpValue="100"/>
<secondarybuff id="10" amount="7"/>
<!-- armour -->
<onhit spell="Consume Booze" onechancein="5"/>
<info latin="(Poingus Poingus)" text="It hatesh you sho much... *hic*"/>
<ai aggressiveness="75" span="24"/>
</monster>
<monster name="Trained Hunting Diggle" level="4" special="1">
<palette tint="-15"/>
<damage slashing="3" piercing="3" />
<stats numFig="7" xpValue="0"/>
<secondarybuff id="10" amount="6"/> <!-- armour -->
<secondarybuff id="6" amount="22"/> <!-- dodge -->
<secondarybuff id="7" amount="18"/> <!-- block -->
<secondarybuff id="8" amount="10"/> <!-- counter -->
<info latin="(Poingus Poingus)" text="A strange little bird-thing that tunnels through walls with its odd, rubbery nasal appliance. This one has been trained to hunt with absolute loyalty. Well, some loyalty. Mostly."/>
</monster>
</monster> <!-- diggle -->
This may look sizable, so how does it work? The code for the "main" Diggle is on the parent tag. Every other derived <monster>
tag pair inside the parent is a secondary variant. Now, onto the details...
Tag | Attribute | Description |
---|---|---|
monster | name="Diggle" | The monster's name. Other XML files may use this to call it. |
level="0" | What level this monster appears most often in. It may still appear in other levels, but not very often. | |
tiny="1" | When set to '1', if this monster is behind a wall, an arrow will appear over its head. | |
splat="blood" | What kind of gibs this monster splashes around when hurt or killed. | |
taxa="Animal" | The monster's taxa, which is used for certain spells. This can be anything, but the ones the game uses are:
|
|
idleSprite |
|
The tags' names are pretty descriptive: These are sprites for a monster when it's idle, when it attacks and when it gets hit, along with proper orientations. We mortals can't edit SPR files, but we can achieve the same results with an XML file and some PNGs. |
attackSprite | ||
hitSprite | ||
morphsprites |
|
If the player can turn into this enemy, they'll need a handful more of animations. They can be listed here. |
dieSprite | name="..." | The animation used when the monster dies. This one is direction-neutral. |
sfx |
|
Set sound effects for the monster. This uses names of sound effects defined in soundfx.cml. |
ai | aggressiveness="5" | How close you need to be to the monster for it to move towards and attack you. |
span="24" | How close you have to be for the monster to remember you instead of just walking off. If the monster is farther than the 'aggressiveness' range, it won't attack, but it might cast spells. | |
spellPercentage="5" | The chance for the monster to cast each of the listed spells. | |
invisible="1" | If set to '1', this monster is perpetually invisible. | |
stats |
|
How many levels on each class the monster has and, consequently, how high its stats are. 'numFig' is for Warrior, 'numRog' for Rogue and 'numWiz' for Wizard. |
xpValue="53" | How rewarding wanton slaughter of wildlife is on this particular case. | |
damage | slashing="1" and others... | How much damage of each type monster attacks deal. |
secondarybuff | id="4" | A tweak to the stats added by the Warrior/Rogue/Wizard levels. In this case, -10 points of S. Stat ID 4 (Critical Chance). |
amount="10" | ||
info | latin="(Poingus Poingus)" | Doesn't appear anywhere. It's unclear why it's kept. |
text="..." | The monster's description. | |
pallete | tint="40" | Changes the hue of the sprite. Used for pallete swapped monsters. |
onhit | spell="Diggle Flu" | Attacks of this monster might inflict "Diggle Flu" on the target... |
onechancein="5" | ... once every 5 attacks, though. | |
resistances | toxic="2" | This monster takes 2 less damage from Toxic sources, which means that the Rusty Sword is going to be useless. YOU HEARD ME, USELESS! You may add more damage resistances this way. |
spell | name="Monstrous Rage" | Remember the "spellPercentage" attribute from the <ai> tag? This is the spell the monster might actually use. Each spell listed rolls its change to cast sequentially, so a 40% spell percentage monster with two spells will cast 64% of the time, 40% of the time its first spell, 24% the second. |