How to Write a Patch
====================

The following is a rough guide on how to write patches to the code. It is
meant to make writing patches easier to inexperienced programmers, but
following these steps does not guarantee that any patch will actually be
accepted - that depends entirely on content.

Required tools
--------------

The Stone Soup project uses git for version control. It is preferred, although
not mandatory, for the contributors to get acquainted with the git workflow and
submit their patches in the git format. For Windows, use either MSYS2 or WSL to
setup a development environment with all the required tools for Windows.

    See INSTALL.MD and develop/git/quickstart.txt for more information.

Main steps
----------
0.) If you're not interested in coding or have no intention of compiling the
    game, you can still submit patches for the documentation, descriptions
    or vaults. In that case, simply ignore the steps relating to compilation
    and coding. You don't even need the source code for that, instead you can
    simply use the binary distribution that also contains the relevant
    text files.

1.) Make a local clone of the source code:
    First, create a fork of the crawl repository on github:

    https://github.com/crawl/crawl

    (This will enable you to submit pull requests through github later.)
    Then, create a local clone of your forked repository:

    git clone https://github.com/yourname/crawl.git

2.) Compile the code. To do this you might have to install a compiler and/or
    additional libraries. See INSTALL.md for details. If you have any
    questions, you can ask for help in #crawl-dev on Libera IRC, or in the #dcss
    channel of the roguelikes discord: https://discord.gg/S5F2H32

3.) Now you can start tweaking the code. Depending on your coding background
    you may want to experiment with smaller changes first. If you intend to
    submit the patch to the dev team, please skim coding_conventions.md.
    Following these guidelines will save us some time later when integrating
    the patch.

    Remember that with git, you can work incrementally by making local commits.
    You can even pull new changes from the development repository while you
    work, by either making these incremental commits, or temporarily stashing
    your changes, and then applying the stash after pulling.

4.) Compile again to test your changes.

5.) Lint. Run util/checkwhite and util/unbrace to fix a few formatting problems.

6.) Create a pull request on github at
    https://github.com/crawl/crawl/pulls

    Here it is immensely helpful if you give a summary of what the patch is
    about. If you created it in response to a bug report or an "Implementable",
    mention the issue, and you might also want to post a reply in that issue
    pointing out your new patch. Please also mention anything you think may
    still need to be improved or modified.

    Thank you! :D


Tips
----
Tip 1:  The code is roughly divided into files according to functionality that
        is reflected in the file names, so mon-gear.cc, mon-stuff.cc
        and mon-util.cc all handle code relating to monsters, while spl-data.h,
        spl-cast.cc and spl-summoning.cc deal with spells. Note that related
        code can still be found in other files, too, but these are a good
        starting point.

Tip 2:  Start out with the simple, generic stuff where you only have to copy
        and minimally tweak existing code, and only once that works move on to
        the more complicated implementations.

Tip 3:  Use grep to find all occurrences of a similar instance of the same type
        as the one you're implementing, e.g.
            grep GOD_ELYVILON *.cc  when adding a new god, or
            grep SCR_FOG *.cc  when adding a new scroll.

        That way you'll be able to repurpose a lot of code for your new
        implementation, and it also helps cut down on coding errors.


Example
-------
In the following, file names and code distribution refer to Stone Soup 0.5,
and may very well have changed in the meantime. Still, the mechanics of finding
and copying code from similar concepts are unchanged.

I want to add a spell that creates some kind of clouds. The first similar spell
I can think of is Mephitic Cloud. I know that this spell is defined as
SPELL_MEPHITIC_CLOUD (and if I didn't know I could find out by grepping for
"Mephitic Cloud"), so I type (within the source folder)
    grep SPELL_MEPHITIC_CLOUD *.h   and
    grep SPELL_MEPHITIC_CLOUD *.cc

... which tells me that code regarding this spell turns up in the following
header files:
* enum.h (its declaration)
* mon-spll.h (monsters "casting" the spell)
* spl-data.h (the definition)

... as well as in ghost.cc (monster spell), it_use3.cc (some kind of misc.
item, maybe), mstuff2.cc (helpfully with a comment mentioning swamp drakes),
spl-book.cc (spellbooks that contain this spell), and spl-cast.cc (actually
casting the spell).

That gives me some ideas on where to start looking at code to duplicate
for my new spell. I'd start out with the basics, the declaration and
definition, copying all values from Mephitic Cloud and only changing the
SPELL_xxxx tag. Then I add the new spell to the list in spl-cast.cc, at which
point I'll also notice that Mephitic Cloud uses a function called
stinking_cloud() and that various other cloud spells (helpfully sorted by
effect type) use functions like cast_big_c() and others. Using grep I can
quickly find out that both functions are declared in spells1.h, meaning their
definitions can be found in spells1.cc.

stinking_cloud() contains a definition of a beam that defines damage and
such. The various properties are not self-explanatory but they're also not
totally obscure, so you should be able to find out a lot about them by just
fiddling with the values. In particular, beam.flavour is set to something
called BEAM_POTION_STINKING_CLOUD which looks interesting enough to check
out, so I grep the source (*.h and *.cc) for all occurrences and have a look
at all files this turns up. And so on.

Evaluating and prioritising the findings takes some experience with the source
code but even if you have no idea what the files are likely to contain, using
grep still greatly reduces the number of files you have to look at. To find
the code you're interested in, search the files for the same keyword you used
for grepping.

Good luck with your patch! If you have any questions, don't hesitate to ask.
Thank you for your support!
