Quick species coding guide


Questions, Explanations, Howtos

Abyss Ambulator

Posts: 1217

Joined: Sunday, 14th April 2013, 04:01

Post Tuesday, 25th November 2014, 20:31

Quick species coding guide

As promised, I did a bit of code diving and wrote up this very rough guide.

Note that I haven't actually contributed any code to this game, but I thought this might be useful as an organization tool:


MAKING A NEW SPECIES:

This guide was written primarily by doing the following things:
1. Looking at what files affect how Minotaurs work, as a fairly regular baseline
2. Looking at what files affect how Felids work, as a data point for an insane species
3. Looking at what files affect how Demonspawn work, as a data point for a fairly complex species

I may have missed a few tiny things, but this should be VERY thorough.



BASICS OF ORGANIZATION:

A very sloppy way to describe how C++ is organized:
There are two types of files: header files (.h) and C++ files (.cc)
Typically, header files are a road map to a .cc file: A good, though sometimes inaccurate description is that header files describe WHAT a file will do, and a .cc file describes HOW it will do it

For example, acquire.h describes two functions: their names, their parameters, and what they return. But, it says nothing about how they work
All of that data is in acquire.cc

Sometimes, header files don't have a matching .cc file. This is often the case when they just contain data to be referenced later.

For example, aptitudes.h doesn't have an aptitudes.cc. It simply contains the data with all the species aptitudes.

Another important concept is that of an enum. Enums define a collection of names that never change that are used to reference something (For example, SP_MINOTAUR is used to say "This player is a minotaur")



GETTING STARTED:

Create the SP_FOO entry in enum.h
Set the aptitudes in aptitudes.h

Now look at species.cc. You'll return here for a few things, but for now, set the following:
species order: static species_type species_order[], line 11
species abbreviation: static const char * Species_Abbrev_List[NUM_SPECIES], line 52
species name: string species_name(species_type speci, bool genus, bool adj), line 126
species size: size_type species_size(species_type species, size_part_type psize), line 372
exp modifier: int species_exp_modifier(species_type species), line 544
HP modifier: int species_hp_modifier(species_type species), line 599
MP modifier: int species_mp_modifier(species_type species), line 651

Set starting stats and mutations in ng-setup.cc:
stats: static void _species_stat_init(species_type which_species), line 40
mutations: void give_basic_mutations(species_type speci), line 214

Mutation.cc and output.cc handle how mutations are displayed:
mutation.cc: string describe_mutations(bool center_title), line 319
output.cc: static string _status_mut_abilities(int sw), line 2576 //Warning: more technical

Set the recommended items and jobs in ng-restr.cc
UNRESTRICTED means recommended, RESTRICTED means not recommended, and BANNED means not allowed

The final bunch of major initial settings are in player.cc
Wearable items: bool you_can_wear(int eq, bool special_armour), line 684
Stat gains per level: void level_change(bool skip_attribute_increase), line 2911
Stealth modifier: static int _species_stealth_mod(), line 3522
Is unholy/undead: bool player::undead_or_demonic() const, line 6552


More technical:
Here's a bunch of little random details. Search for SP_FELID and SP_DEMONSPAWN to get a grasp on functionality

acquire.cc: allowed acquirement items, aka, screw felids. Also in dungeon.cc (line 4389)

attack.cc: special attack messages such as felid pouncing

describe.cc:
Print list of actions (for instance, felid's don't get a quiver option): static bool _actions_prompt(item_def &item, bool allow_inscribe, bool do_prompt), line 2336
Weird ghost description stuff: string get_ghost_description(const monster_info &mi, bool concise), line 4178

godabil.cc, godpassive.cc, godprayer.cc: handles god special cases. Gozag shops, Ru sacrifice weighting, Ash's passive, prayer messages

hints.cc: things like "Note that as a minotaur you will be unable to wear helmets"

invent.cc: handles inventory wielding restrictions, but NOT armour wearing, which is in item_use.cc

itenname.cc: handles item colorization aka whether an item is useless or not

main.cc: some special messages such as felids trying to remove nonexistent armour

melee_attack.cc: Includes aux attacks, constriction, and special cases such as minotaur retaliation. Also handles stab class for things like felid claws

mutation.cc: handles checks such as mutation restrictions (scales on a DS who already has scales for instance)

ng-wanderer.cc: starting items and skills

player.cc: Handles felid extra lives, new mutations, draconian transformations, and other level dependent changes
Weird little things such as player_has_feet(bool temp) (line 823), can_throw_large_rocks() (line 7827), can_smell() (line 7832),

player-act.cc: Checks if a species can wield a weapon and displays special descriptions such as felid paw unarmed attack

quiver.cc: stupid felids

religion.cc: felid weapon gifts

spl-book.cc, spl-util.cc: useless spells, aka, felids can't brand, mummy's can't transform

transform.cc: some description tweaks for things like blade hands as felids and octopodes.
Three wins: Gargoyle Earth Elementalist of Ash, Ogre Fighter of Ru, Deep Dwarf Fighter of Makhleb (0.16 bugbuild :( )

For this message the author TeshiAlair has received thanks: 11
and into, Brannock, chequers, dolphin, guyht, Hirsch I, Mandragora, Neon, rockygargoyle, Sprucery and one more user
User avatar

Tartarus Sorceror

Posts: 1881

Joined: Saturday, 7th September 2013, 21:16

Location: Itajubá, MG, Brazil.

Post Wednesday, 26th November 2014, 06:54

Re: Quick species coding guide

this will help me alot. learning how to code is damn difficult, specially with my other responsabilities, and this should speed my practice nicely!
thanks a lot!
my posts are to be read in a mildly playful tone, with a deep, sexy voice.

Spider Stomper

Posts: 224

Joined: Monday, 19th November 2012, 04:56

Post Wednesday, 26th November 2014, 13:53

Re: Quick species coding guide

I think that the idea behind this is great, introducing people to the source as you said in the other thread. I would disagree with using species coding to do that, however. This is because a) as you can see even in this guide, species have a lot of moving parts that might make them unsuitable for beginners to start with (I am assuming beginners are your intended audience) and b) adding a new species to the game would require something new and interesting to make it in. While the experience could certainly be valuable, I would lean toward making a guide on something maybe a bit more attainable.

To go through the guide piecewise:

Making a species:

Truthfully, just searching the source the way you did is a great method to make a guide. I think that searching the source is important enough to emphasize how you searched so that a beginner would be able to repeat it. Mentioning the other git tools or referencing documentation that does could also be beneficial.

Basics of organization:

This was my favorite section because it is clear, has a good example and outlines how to think about the code, which in my opinion is more important than step-by-step edits.

Getting started:

As I just implied, I'm not a big fan of the step-by-step process. As you explained in your introduction, most of these code sites can be discovered by doing a few searches. The other aspect that I don't like about this is the sheer number of files that need to be edited in order to bring a new species to fruition. The chance for small mistakes in each file could add up and potentially frustrate a beginner. Compare this to something like a bug fix which could only require editing of one file, or even one line!

Overall, consider what level of coding familiarity for which this guide is intended. I suppose it is not too bad if it is intended to just get people into the source and poking around. Since it is written as a guide to add a species I don't think it is appropriate for beginners. You have all of the right files in place, I just can't imagine a beginner writing up a new species based on this guide.

If you are writing for people with no programming experience, referencing a syntax guide could be beneficial (again, this depends on your intended audience). Of note, crawl's coding style heavily leverages C's ternary operator for conditionals.
i.e.
  Code:
<condition> ? <do if true> : <do if false>

rather than
  Code:
if (<condition>) {<do if true>}
else {<do if false>}


I speak from experience, having contributed several small patches. My first contribution, 957e161, came from a game in which I was playing a vampire and noticed that I could not drain raven corpses, nor could I stab ravens to drain blood. I grepped around until I found the monster flags, and noticed that ravens were missing the M_WARM_BLOOD flag that other drainable monsters had. I added the flag, recompiled, and tested the fix before finally creating the patch and submitting it.

If I were to write a guide, it would be a similar process to what I just described. I readily recognize, however, that not everyone thinks the same way that I do. There are developers that seem to solely work on big projects like developing a species. Maybe some would find this guide beneficial! It is, as you said, very thorough. Hopefully something of what I said could be of use to you.

For this message the author RBrandon has received thanks:
zxc23

Abyss Ambulator

Posts: 1217

Joined: Sunday, 14th April 2013, 04:01

Post Wednesday, 26th November 2014, 15:53

Re: Quick species coding guide

I started with species coding because it and god creation are the two most common "put my idea in the game!" things in crawl, and a lot of the surface level species code is moderately straightforward (you could create your own human VERY quickly for example) even if it is sprawling.

This was also done at work and is a rough draft :p so all feedback is greatly appreciated!

I'm going to try to do a more general guide of Git and programming basics as well, but I felt an early source dive would be good for me as well, plus my C++ is rusty since I do mostly Groovy, Python, and JS these days. This really is more of a source map than a coding guide, since I think it would be most....irresponsible to tell people how to code things without having contributed anything myself. This is just so people can see "hey this is how it actually works."

Thank you for all of your feedback though! I'm going to be continuing to work on little things like this, and I will be trying to make some more beginner-friendly ones as well.

PS: It made me soooooo happy to see the ternary operator, even if it might be a little harder to read for new people.
Three wins: Gargoyle Earth Elementalist of Ash, Ogre Fighter of Ru, Deep Dwarf Fighter of Makhleb (0.16 bugbuild :( )
User avatar

Dungeon Master

Posts: 182

Joined: Saturday, 18th December 2010, 10:26

Location: Germany

Post Wednesday, 26th November 2014, 19:26

Re: Quick species coding guide

If you're interested in coding something for Crawl, have a look at the docs/develop directory, specifically patch_guide.txt and coding_conventions.txt.

The specific examples given will be severely out of date, but the principle still is sound.
Please report bugs to Crawl's bug tracker, and leave feedback on the development wiki. Thank you!

For this message the author jpeg has received thanks: 2
Hirsch I, neil

Ziggurat Zagger

Posts: 5382

Joined: Friday, 25th November 2011, 07:36

Post Saturday, 17th January 2015, 02:05

Re: Quick species coding guide

Be afraid, be very, very afraid: Elementals! Or, more accurately, humans who can't wear any armor, except they can, but they get rot immunity and mutation resistance three.

In other words, I tried following this guide to actually go ahead and code a race, and succeeded in roughly 3 hours or so of coding. Note I do have development experience, so if you're using this to learn to code, it may be harder, but there wasn't really much work here, it's mostly just adding one more value to enumerations. This didn't stop me from doing things like copy and pasting lines of code without reading them too closely and making the description for elementals "Formicid" or not giving a monster equivalent of my race. FYI: Your race must be linked to a monster equivalent, or crawl will crash immediately on race selection (This is intentional). But other than that, it was pretty simple.

In general all of the sections of code he called out are correct, I'd just add that mutation.cc's describe_mutations doesn't need to return a string for standard mutations, ie if you give someone claws 1, don't add a string there, it already has one.

Every section after "more technical" isn't required for a human-level complex race. It'll probably be very useful if I ever go about actually adding content to this race, but I don't know if/when I will.

Wearable items: bool you_can_wear(int eq, bool special_armour), line 684, only determines if it shows up as available on the % screen - you can still equip the item anyways. I'm going to look into where to actually prevent this from happening.

  Code:
 Dungeon Crawl Stone Soup version 0.16-a0-3659-gb504317 (tiles) character file.

Tasonir the Insei (Elemental Monk)                    Turns: 13, Time: 00:02:27

Health: 19/19      AC:  2    Str: 11    XL:     1   Next: 0%
Magic:  1/1        EV: 13    Int: 10    God:   
Gold:   0          SH:  0    Dex: 15    Spells: 0 memorised, 0 levels left

rFire  . . .     SeeInvis .     c - +0 whip
rCold  . . .     Clarity  .     a - +0 robe
rNeg   . . .     SustAb   .     (no shield)
rPois  ∞         Gourm    .     (helmet unavailable)
rElec  .         Spirit   .     (cloak unavailable)
rCorr  .         Warding  .     (gloves unavailable)
rMut   +         Stasis   .     (boots unavailable)
MR     .....                    (no amulet)
Stlth  ++........               (no ring)
                                (no ring)

@: not resistant to hostile enchantments, unstealthy
A: erupt in elemental fury, mutation resistance 3, unbreathing, rot immunity
a: no special abilities


You are on level 1 of the Dungeon.
You are not hungry.

You have visited 1 branch of the dungeon, and seen 1 of its levels.

Inventory:

Hand weapons
 c - a +0 whip (weapon)
Armour
 a - a +0 robe (worn)
Comestibles
 b - a bread ration


   Skills:
 + Level 3.0 Fighting
 + Level 3.0 Dodging
 + Level 1.7 Stealth
 + Level 4.0 Unarmed Combat


You cannot memorise any spells.
You don't know any spells.

Dungeon Overview and Level Annotations

Branches:
Dungeon (1/15)           

Altars:


Innate Abilities, Weirdness & Mutations

You are almost entirely resistant to further mutation and mutation removal.
You can survive without breathing.
You are immune to rotting.


Message History

Welcome back, Tasonir the Elemental Monk.
Press ? for a list of commands and other information.
You aren't wearing any rings or amulets.
Take off which item? (? for menu, Esc to quit)
You start removing your armour. You continue taking off your +0 robe.
You continue taking off your +0 robe. x3
You finish taking off your +0 robe.
Wear which item? (? for menu, Esc to quit)
You start putting on your armour. You continue putting on your +0 robe.
You continue putting on your +0 robe. x3
You finish putting on your +0 robe.
You see here a whip.
c - a whip
Wield which item (- for none, * to show all)? (? for menu, Esc to quit)
c - a +0 whip (weapon)
Saving game... please wait.
Welcome back, Tasonir the Elemental Monk.
Press ? for a list of commands and other information.
Char dumped to '/Users/stevenwarkentin/Library/Application Support/Dungeon Crawl Stone Soup/morgue/Tasonir.txt'.
Saving game... please wait.

  ≈ ≈
#.≈§§§§.
#.§§§≈§.#
#§§§?§§.#
#§≈§≈≈≈.#
#§.≈≈≈..#
#§.§....#
#.......#
#..@...(#
##..<..##
 #######


There are no monsters in sight!


Notes
Turn   | Place    | Note
--------------------------------------------------------------
     0 | D:1      | Tasonir, the Elemental Monk, began the quest for the Orb.
     0 | D:1      | Reached XP level 1. HP: 19/19 MP: 1/1

User avatar

Pandemonium Purger

Posts: 1386

Joined: Sunday, 5th April 2015, 22:37

Post Tuesday, 21st April 2015, 21:44

Re: Quick species coding guide

I used this guide to add Sludge Elves back to 16.1. I had already figured out most of the stuff needed, but the guide boosted my confidnce and let me work out the typo's. I may try coding an actually interesting race next. My coding experiancecome mostly from going though a online C++ tutorial.
http://crawl.akrasiac.org/scoring/playe ... speon.html. I started playing in 0.16.1
I achieved greatplayer in less than a year.
Remove food

Dungeon Dilettante

Posts: 1

Joined: Thursday, 4th June 2015, 09:52

Post Thursday, 4th June 2015, 09:55

Re: Quick species coding guide

Hey, sorry if this is a stupid question, but can someone tell me where to edit files for existing races, rather than make my own I really just want to tamper with the existing ones to make them more fun, as an example I want demonspawn to mutate 3 times as much but get a bad mutation every third level as well. If someone could direct me to what file(I know what to do just not where to find the file for species) needs to be edited to do so that would be nice. :D

Dungeon Master

Posts: 1051

Joined: Thursday, 12th June 2014, 05:19

Post Tuesday, 9th June 2015, 19:26

Re: Quick species coding guide

This guide is partially obsolete; a large amount of species data has been moved into https://github.com/crawl/crawl/blob/mas ... ies-data.h . Most of it still looks accurate, though.

ahart586712 wrote:Hey, sorry if this is a stupid question, but can someone tell me where to edit files for existing races, rather than make my own I really just want to tamper with the existing ones to make them more fun, as an example I want demonspawn to mutate 3 times as much but get a bad mutation every third level as well. If someone could direct me to what file(I know what to do just not where to find the file for species) needs to be edited to do so that would be nice. :D

You'd want to tamper with [url=http://s-z.org/neil/git/?p=crawl.git;f=crawl-ref/source/mutation.cc;hb=HEAD#l1972]this function[url]. Be warned that the code in question is somewhat complex and very bad. (Goto? Seriously?)

Tartarus Sorceror

Posts: 1694

Joined: Tuesday, 31st March 2015, 20:34

Post Tuesday, 9th June 2015, 20:43

Re: Quick species coding guide

Hey, there's nothing wrong with goto, it's just the coding sledgehammer that gets used improperly by inexperienced coders. It has its place...

Don't be mean to my little goto. Everyone picks on him.
User avatar

Dis Charger

Posts: 2057

Joined: Wednesday, 7th August 2013, 08:25

Post Tuesday, 9th June 2015, 20:48

Re: Quick species coding guide

dowan wrote:Hey, there's nothing wrong with goto, it's just the coding sledgehammer that gets used improperly by inexperienced coders. It has its place...

Don't be mean to my little goto. Everyone picks on him.
I first learned to code (at all) by teaching myself to program a calculator by trial and error. I used GoTo's so much on that. In retrospect, all my goto A; then defining what A is in another place is pretty much just a function, but you couldn't define a function and it was about the only option. I even got the calculator to intelligently play tic-tac-toe, for some reason. In programming the 'AI' I realized I could make it always win...that Was my first experience with a 'solved game'. Heh, also in retrospect if I was in a good environment at 14, instead of bored as an A student in a public school...Nevermind, no point in regretting the past.
I'm beginning to feel like a Cat God! Felid streaks: {FeVM^Sif Muna, FeWn^Dithmenos, FeAr^Pakellas}, {FeEE^Ashenzari, FeEn^Gozag, FeNe^Sif Muna, FeAE^Vehumet...(ongoing)}

Ziggurat Zagger

Posts: 6454

Joined: Tuesday, 30th October 2012, 19:06

Post Wednesday, 10th June 2015, 00:11

Re: Quick species coding guide

dowan wrote:Hey, there's nothing wrong with goto, it's just the coding sledgehammer that gets used improperly by inexperienced coders. It has its place...

Don't be mean to my little goto. Everyone picks on him.


The problem with goto isn't goto itself, it's that if you're getting to a point where you need to use one you've *already made* a grievous error somewhere in your design. Using a goto is a symptom, not explicitly the problem in and of itself.

And to be clear, goto is fine *if you never need to update, change fix or make bug fixes to your code ever in the future* which means for the most part, goto is fine if you're writing a trivial application.

You might not regret using a goto now, but in the future, the fact that you created a structure that required a goto (or had goto be the easiest solution) will fundamentally cause you (or possibly whomever is left maintaining your code at that point) more grief than writing it *properly* in the first place would.

Trust me, I've been doing this for over 35 years, if you find yourself thinking "I should just use a goto here" then there's something flawed with your design and you should go back and re-evaluate it, unless it's something that doesn't ever need to be maintained or fixed (probably it's good exercise even then).
Spoiler: show
This high quality signature has been hidden for your protection. To unlock it's secret, send 3 easy payments of $9.99 to me, by way of your nearest theta band or ley line. Complete your transmission by midnight tonight for a special free gift!
User avatar

Dis Charger

Posts: 2057

Joined: Wednesday, 7th August 2013, 08:25

Post Thursday, 25th June 2015, 09:05

Re: Quick species coding guide

Is MAJOR_VERSION == 34 nostalgia or something? I keep seeing it; it gives felids a traps&doors apt if version is 34, for example.

EDIT:

I'm seeing literally none of the stuff that's supposed to be in species.cc though there's a species-data.h that seems to have a struct that holds all that data? Has this majorly changed or something?

EDIT 2:

OK Species_ORDER [] is in Newgame.cc now.

EDIT 3:

OK I have an IDE now and I'm using it's such directory folder to find everything related to SP_HUMAN and going from there.
I'm beginning to feel like a Cat God! Felid streaks: {FeVM^Sif Muna, FeWn^Dithmenos, FeAr^Pakellas}, {FeEE^Ashenzari, FeEn^Gozag, FeNe^Sif Muna, FeAE^Vehumet...(ongoing)}

Ziggurat Zagger

Posts: 5382

Joined: Friday, 25th November 2011, 07:36

Post Thursday, 25th June 2015, 19:22

Re: Quick species coding guide

Yeah, major_version 34 is everywhere. I could be wrong, so take this with a grain of salt until someone with more experience than just my above post about elementals can confirm, but I believe it refers to the character save file version. So things like traps and doors used to be in the save file, but it no longer is, and is now a 'faked' skill based off your character level.

Good luck hacking in your races, some of them like giant/reverse demigods don't have any racial abilities and should, in theory, be fairly simple to make. I got elementals as far as "reskinned humans with some default mutations" but then never got around to doing all the custom level up effects that there's no precedent for. Maybe the next time I'm between work and have more time (I am a contractor)...
User avatar

Dungeon Master

Posts: 431

Joined: Tuesday, 13th September 2011, 17:34

Post Thursday, 25th June 2015, 23:09

Re: Quick species coding guide

Version tags are there for save compatibility: theoretically someone could have a save file from way back when Traps and Doors was a skill, and want to update it to trunk. In order for them to be able to do that, a space in the enum lists for T&D (and every other removed/moved thing) has to still exist, and everything needs to be in the same order in the lists (since stuff is just saved by its enum). When save compatibility is finally broken, major_version will get bumped to 35, at which point all that junk can be easily found and deleted by whoever is doing the breaking.

Return to Coding

Who is online

Users browsing this forum: No registered users and 4 guests

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.