qw

The DCSS-playing bot qw

13
6
13
2
Lua
public
Forked

qw

This is the DCSS bot qw, the first bot to win
DCSS with no human assistance. Originally written by
elliptic, it’s now developed and maintained by
the DCSS devteam. A substantial amount of code here was contributed by elliott
or borrowed from N78291’s bot “xw”, and many others have contributed fixes and
suggestions.

qw can play most species and background combinations using either melee or
ranged weapons, and has some basic grasp of how many gods work. Note though
that most spells and abilities aren’t used, and qw does not have a high
winrate. It has won games with 3 and 15 runes, and we maintain qw so it can
continue to play and win the current version. See
docs/accomplishments.md for current and past
achievements.

Please post bug reports as issues on the official crawl qw repository:

https://github.com/crawl/qw/issues/new

If you’re interested in contributing to qw development, see the debugging
doc
for help with debugging.

Running qw

To run qw, you’ll need a local build of crawl, or your own crawl WebTiles or
dgamelaunch server with an appropriate build available. qw needs substantially
more memory than the 16MB clua limit. Additionally,
because qw is computationally demanding even with an action delay, it needs to
run without the lua throttle enabled. For local play, the recommended arguments
are -lua-max-memory 128, and if you’re running qw through a WebTiles or
dgamelaunch server via a DGL build of crawl, you’ll also need -no-throttle.

Setting up an rcfile

First clone this repository, and then make any desired changes to the
configuration in qw.rc. See the comments in this file and the
configuration section below for more details. Next, use the
make-qw.sh script from this repository to combine all lua source
files in one of two ways.

Method 1: lua include file (recommended)

This puts all source lua into a single qw.lua file that gets included into
the rcfile via an include statement.

Steps:

  • Run make-qw.sh to create qw.lua.
  • Uncomment the include line at the end of qw.rc so that it simply reads
    include = qw.lua
    
  • To run qw locally use a command like:
    ./crawl -lua-max-memory 128 -rc /path/to/qw/qw.rc -rcdir /path/to/qw
    
    The -rcdir option is necessary for crawl to find qw.lua.

This method makes rcfile modifications easier and debugging easier due to line
numbers from error messages.

Note that when running qw on a server, you can still use this method if you use
the qw.lua file as the rcfile contents of another account. You would then
modify your include = qw.lua statement to be include = ACCOUNT.rc where
ACCOUNT is the account name.

Method 2: lua directly in the rcfile

This puts all lua directly into the rcfile. This is an easy way to run qw from
a single account.

Steps:

  • Run make-qw.sh -r qw.rc to inline all lua directly into the contents of
    qw.rc and saving the results in a new file (qw-final.rc by default).
  • To run qw locally use a command like:
    ./crawl -lua-max-memory 128 -rc /path/to/qw/qw-final.rc
    

Note that make-qw.sh looks for a marker in qw.rc to know where to insert
the lua. This is # include = qw.lua by default.

Starting qw after crawl is loaded

Enter a name if necessary and start a game. If you didn’t change the
AUTO_START variable, the “Tab” key will start and stop qw.

The file qw.exp is a simple expect script that automates running qw
for many games in a row. The AUTO_START variable should be left at false when
when using this. (With minor modifications, this can also be used to run games
on a remote server over ssh.)

Running on a WebTiles or dgamelaunch server

qw requires more memory and cpu than what’s allowed for official online
servers, so you will need to run your own server. Please don’t try to run qw on
an official server. Misconfigured (or even well-configured) bots can eat up
server server resources.

When running your own WebTiles server, you need to add the options mentioned
above in Running qw. You can add these under the options
section of the game entry. To track games for your instance of qw, you can set
up Sequell or the DCSS
scoring scripts.

qw Configuration

qw has a number of variables set directly in its RC and described there in
comments. Some of the more important variables are described here. Note that
lines in qw.rc beginning with : define Lua variables and must be valid Lua
code, otherwise the lines are Crawl options as described in the options
guide
.

Starting and Action Delay

Set the AUTO_START variable to true to have qw start automatically when a
game begins. Otherwise, press “Tab” to start and stop execution.

If you’re spectating qw, you may want to set DELAYED to true to add a short
delay between each action. The delay time is stored in DELAY_TIME with a
default of 125 ms, which gives a good spectator experience.

Since clua works on the server side, WebTiles drawing can lag behind things
actually happening. To see more current events just refresh the page and press
“Tab”. Alternatively, run or watch the bot in console (via ssh).

Combos and Gods

To have qw play one type of char or select randomly from a set of combos, use
the combo rcfile option. See comments in the rcfile for examples. Then change
the GOD_LIST variable to set the gods qw is allowed to worship. Each entry
in GOD_LIST can be the full god name, as reported by you.god(), or the
abbreviation made with the first 1, 3, or 4 letters of the god’s name with any
whitespace removed. For the Shining One, you can use the abbreviations “1” or
“TSO”. For No God, you can use the abbreviations “0” or “None”. For
non-zealots, qw will worship the first god in the list it finds, entering
Temple if it needs to. To have CK abandon Xom immediately, set CK_ABANDON_XOM
to true, otherwise all zealots will remain with their starting god unless
told to convert explicitly by the goal list.

Gods who have at least partly implemented are BCHLMOQRTUXY1. Currently qw has
the most success with Okawaru, Trog, and Ru, roughly in that order. For
combos, GrFi, GrBe, MiFi, MiBe, GrHu, and MiHu are most successful.

Combo cycles

To have qw cycle through a set of combos, set COMBO_CYCLE to true and edit
COMBO_CYCLE_LIST. This list uses the same syntax as the combo option, but
with an optional ^<god initials> suffix. The set of letters in <god initials> gives the set of gods qw is allowed to worship for that combo.
Additionally, after this god list, you can specify a goal name from
GOALS with a !<plan> suffix. For example, the default list:

COMBO_CYCLE_LIST = "GrFi.waraxe^OR, MiBe.handaxe, GrHu^O"

has qw cycle through GrFi of either Okawaru or Ru, and GrHu of Okawaru.

Goals

The GOALS variable defines a table of strings defining sets of goals
for qw to complete in sequence. Each key in this table is a descriptive string
that can be used in the DEFAULT_GOAL variable or in the
COMBO_CYCLE_LIST variable above to have qw execute that set of goals. The
entries in GOALS are case-insensitive, comma-separated strings of
goals that qw will follow in sequence.

The default goal is Normal, which is a meta goal that has qw proceed
through a 3-rune route that gives qw good success. This is mostly equivalent
to the following goal list:

"D:1-11, Lair, D:12-D:15, Orc, 1stLairBranch:1-3, 2ndLairBranch:1-3,
1stLairBranch:4, Vaults:1-4, 2ndLairBranch:4, Depths, Vaults:5, Shopping,
Zot:1-4, Orb"

Here 1stLairBranch and 2ndLairBranch refer to whatever Lair branches are
selected according to the RUNE_PREFERENCE rcfile variable. The other
differences between the above list and Normal are that qw enters Lair as soon
as it has sufficient piety for its god (see the ready_for_lair() function)
and that this route is subject to the rcfile variables LATE_ORC and
EARLY_SECOND_RUNE.

If Normal is followed by additional entries in the goal list, qw will
proceed to those after its Shopping goal is complete. Hence a viable 15
Rune route could be expressed as:

"Normal, God:TSO, Crypt, Tomb, Pan, Slime:5, Hells, Abyss, Zot"

This will have qw abandon its current god for the Shining One after shopping is
complete before heading through Crypt, Tomb, and the other extended branches.

The other types of goal entries are:

  • <branch>

    Where <branch> is the branch name reported by you.where(). qw will fully
    explore all levels in sequence in that branch as well as get any branch
    runes before proceeding to the next goal.

    Examples: D, Lair, Vaults

  • <branch>:<range>

    The can be a single level or a range of levels separated with a dash.
    The levels in this range are fully explored in sequence, although qw will
    potentially explore just outside of the level range to find all stairs for
    levels in the range. If the range includes a level with a rune, qw will find
    this rune before considering the goal complete.

    Examples: D:1-11, Swamp:1-3, Vaults:5

  • Rune:<branch>

    Go directly to the end level of <branch> and explore until the rune is
    obtained. This does not require full exploration of the level containing the
    rune.

    Examples: Rune:Swamp, Rune:Vaults, Rune:Geh

  • Shopping

    Try to buy the items on qw’s shopping list.

  • God:<god>

    Abandon any current god and convert to <god>. This is useful for attempting
    extended branches where a different god would be sufficiently better that it’s
    worth the risk of dying to god wrath. The name <god> can be the full god
    name as reported by you.god() or the abbreviation made by the first 1, 3, or
    4 letters of the god’s name with any whitespace removed. For the Shining One,
    TSO and 1 are valid abbreviations. For No God, No God, None, and 0
    are valid entries.

    Examples: God:Okawaru, God:Oka, or God:O; God:TSO, God:Chei

  • Win, Orb, and Escape

    The Orb goal has qw seek the Orb of Zot on Zot:5 and pick it up. The
    Escape goal has it go to D:1 and exit the dungeon, which ends the game. The
    Win goal does the Orb goal followed by the Escape goal. qw always
    switches to the Win goal when it completes all entries in its goal list. Note
    that the Orb goal has qw dive through all levels of Zot to look for the orb
    on Zot:5. Proceed this goal with e.g. Zot:1-4 or Zot if you want to explore
    more of the Zot
    branch.

  • Zig, or Zig:<num>

    Enter a ziggurat, clear it through level <num>, and exit. If <num> is not
    specified, qw clears the entire ziggurat.

  • Hells

    Do Hell and the 4 Hell branches in random order.

  • Save

    Save the game and exit. This is useful to have qw reach a certain goal and
    provide a save and c_persist file you can back up for further use in
    development. When qw resumes after a Save goal, it will move on to the next
    goal in its goal list.

  • Quit

    Quit the game immediately. This is useful as a final goal when testing qw.

Some notes about exploration

qw considers a level explored if it’s been autoexplored to completion at least
once, all its required stone upstairs and downstairs are reachable, and any
rune on the level has been obtained. Other types of unreachable areas,
transporters, and runed doors don’t prevent qw from considering a level
autoexplored. In portals, the Abyss, and Pan, qw always opens all runed doors
and explores all transporters. If qw must travel through unexplored levels that
aren’t part of its current goal, it will explore only as much as necessary
to find the necessary stairs and then take them. This behaviour includes
situations like being shafted.

For Hell branches, goals like Rune:Geh, Rune:Tar, etc. are good
choices, since they have qw dive to and get the rune while exploring as little
as possible of the final level. For a branch like Slime, a goal of
Slime:5 is better, since it makes qw dive through Slime but explore Slime:5
fully to obtain the loot after the Royal Jelly is dead.

v0.3.3[beta]