diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f8b42521..dc9611eb9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -185,7 +185,7 @@ endif()
# set up versioning.
set(DF_VERSION "0.47.04")
-set(DFHACK_RELEASE "r3")
+set(DFHACK_RELEASE "r4")
set(DFHACK_PRERELEASE FALSE)
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")
diff --git a/LICENSE.rst b/LICENSE.rst
index 18aed8de6..f1e07d111 100644
--- a/LICENSE.rst
+++ b/LICENSE.rst
@@ -23,6 +23,8 @@ clsocket_ BSD 3-clause \(c\) 2007-2009, CarrierLabs, LLC.
dirent_ MIT \(c\) 2006, Toni Ronkko
JSON.lua_ CC-BY-SA_ \(c\) 2010-2014, Jeffrey Friedl
jsoncpp_ MIT \(c\) 2007-2010, Baptiste Lepilleur
+libexpat_ MIT \(c\) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper \(c\) 2001-2019 Expat maintainers
+libzip_ BSD 3-clause \(c\) 1999-2020 Dieter Baron and Thomas Klausner
linenoise_ BSD 2-clause \(c\) 2010, Salvatore Sanfilippo & Pieter Noordhuis
lua_ MIT \(c\) 1994-2008, Lua.org, PUC-Rio.
luafilesystem_ MIT \(c\) 2003-2014, Kepler Project
@@ -31,6 +33,7 @@ protobuf_ BSD 3-clause \(c\) 2008, Google Inc.
tinythread_ Zlib \(c\) 2010, Marcus Geelnard
tinyxml_ Zlib \(c\) 2000-2006, Lee Thomason
UTF-8-decoder_ MIT \(c\) 2008-2010, Bjoern Hoehrmann
+xlsxio_ MIT \(c\) 2016-2020, Brecht Sanders
=============== ============= =================================================
.. _DFHack: https://github.com/DFHack/dfhack
@@ -38,14 +41,17 @@ UTF-8-decoder_ MIT \(c\) 2008-2010, Bjoern Hoehrmann
.. _dirent: https://github.com/tronkko/dirent
.. _JSON.lua: http://regex.info/blog/lua/json
.. _jsoncpp: https://github.com/open-source-parsers/jsoncpp
+.. _libexpat: https://github.com/libexpat/libexpat
+.. _libzip: https://github.com/nih-at/libzip
.. _linenoise: http://github.com/antirez/linenoise
.. _lua: http://www.lua.org
.. _luafilesystem: https://github.com/keplerproject/luafilesystem
+.. _lua-profiler: http://lua-users.org/wiki/PepperfishProfiler
.. _protobuf: https://github.com/google/protobuf
.. _tinythread: http://tinythreadpp.bitsnbites.eu/
.. _tinyxml: http://www.sourceforge.net/projects/tinyxml
.. _UTF-8-decoder: http://bjoern.hoehrmann.de/utf-8/decoder/dfa
-.. _lua-profiler: http://lua-users.org/wiki/PepperfishProfiler
+.. _xlsxio: https://github.com/brechtsanders/xlsxio
.. _CC-BY-SA: http://creativecommons.org/licenses/by/3.0/deed.en_US
diff --git a/data/blueprints/README.md b/data/blueprints/README.md
index fb4e2d9ef..2facb3f4e 100644
--- a/data/blueprints/README.md
+++ b/data/blueprints/README.md
@@ -1,4 +1,5 @@
-This folder contains blueprints used by the `quickfort` script. For more information, see:
+This folder contains blueprints that can be applied by the `quickfort` script. For more information, see:
* [Quickfort command reference](https://docs.dfhack.org/en/stable/docs/_auto/base.html#quickfort)
-* [Quickfort user guide](https://docs.dfhack.org/en/stable/docs/guides/quickfort-user-guide.html)
+* [Quickfort blueprint guide](https://docs.dfhack.org/en/stable/docs/guides/quickfort-user-guide.html)
+* [Quickfort library guide](https://docs.dfhack.org/en/stable/docs/guides/quickfort-library-guide.html)
diff --git a/data/quickfort/aliases-common.txt b/data/quickfort/aliases-common.txt
index e4d2ef1cd..509d1c4ed 100644
--- a/data/quickfort/aliases-common.txt
+++ b/data/quickfort/aliases-common.txt
@@ -1,32 +1,63 @@
-# Common baseline for aliases for quickfort query mode blueprints.
+# Standard library of aliases for quickfort query mode blueprints.
#
# Please DO NOT EDIT this file directly. It will get overwritten when DFHack
# is updated. Instead, custom aliases should be added to
-# dfhack-config/quickfort/aliases.txt. See that file for syntax documentation.
+# dfhack-config/quickfort/aliases.txt
+# Custom alias definitions will take precedence over aliases in this file.
#
-# The aliases in this file were tested in DF 0.47.04 on 2020 Jul 18.
-#
-# The aliases are generally split into three categories:
-# 1) The aliases that name a type disable everything else for that stockpile
-# category and enable only that type. For example, "preparedfood" enables
-# prepared food and disables all other types of food.
-# 2) The aliases that start with "forbid" only forbid (or toggle) the named type
-# and leave the rest of the stockpile untouched.
-# 3) The aliases that start with "permit" only permit (or toggle) the named type
-# and leave the rest of the stockpile untouched.
-#
-# Aliases that don't fit into those two categories have comments explaining
-# their usage.
+# Please see
+# https://docs.dfhack.org/en/latest/docs/guides/quickfort-alias-guide.html
+# or
+# hack/docs/docs/guides/quickfort-alias-guide.html
+# in your DF installation directory for alias syntax documentation and
+# documentation for the aliases in this file.
+
+##################################
+# naming aliases
+##################################
+
+name: {Right}
+givename: !n{name}&
+namezone: ^i{givename}^q
+
+
+##################################
+# quantum stockpile aliases
+##################################
+
+# Allows the standard stockpile config aliases to also be used to configure
+# hauling routes.
+enter_sp_config: {enter_sp_config_default}
+enter_sp_config_default: s
+enter_sp_config_hauling: &
+
+quantum_enable: {enableanimals}{enablefood}{enablefurniture}{enablestone}{enableammo}{enablecoins}{enablebars}{enablegems}{enablefinishedgoods}{enableleather}{enablecloth}{enablewood}{enableweapons}{enablearmor}{enablesheet}
+quantum: {linksonly}{nocontainers}{quantum_enable}{givename}
+
+stop_name: {Right}
+route_enable: {quantum_enable}{enablecorpses}{enablerefuse}
+quantumstop: ^hrn{name}&sn{stop_name}&&xxx{route_enable enter_sp_config={enter_sp_config_hauling}}s{move}p^{move_back}^q
+quantumstopfromeast: {quantumstop move={Right} move_back={Left}}
+quantumstopfromsouth: {quantumstop move={Down} move_back={Up}}
+quantumstopfromwest: {quantumstop move={Left} move_back={Right}}
+quantumstopfromnorth: {quantumstop move={Up} move_back={Down}}
+
+
+##################################
+# farm plots
+##################################
+
+growlastcropall: a/&b/&c/&d/&
+growfirstcropall: a&b&c&d&
########################################
-# general purpose stockpile adjustments
+# stockpile utility aliases
########################################
linksonly: a
nocontainers: CE
-# for configuring stockpiles to give to other nearby stockpiles/workshops
give: g{move}&
give2up: {give move={Up 2}}
give2down: {give move={Down 2}}
@@ -37,69 +68,15 @@ give10down: {give move={Down 10}}
give10left: {give move={Left 10}}
give10right: {give move={Right 10}}
-# Keep in mind that building, stockpile, and zone names have a maximum length
-# of 20 characters. usage example: {givename name="myname"}
-givename: {Ctrl}n{name}&
-
-# use to toggle a sequence of stockpile options. for example: {togglesequence 5}
togglesequence: &{Down}
togglesequence2: &{Down 2}
-enablesequence: e{Down}
-
-# Enables everything but corpses and refuse. Refuse is excluded since otherwise
-# clothes and armor in this quantum stockpile will rot away. If you want bones
-# in your quantum stockpile, apply this alias to a refuse stockpile (but don't
-# put useful clothes or armor in there!)
-# Optionally set a name for the stockpile by specifying the 'name' parameter,
-# for example: {quantum name="my name"}
-quantum: {linksonly}{nocontainers}{enableanimals}{enablefood}{enablefurniture}{enablestone}{enableammo}{enablecoins}{enablebars}{enablegems}{enablefinishedgoods}{enableleather}{enablecloth}{enablewood}{enableweapons}{enablearmor}{enablesheet}{givename}
-
-
-##################################
-# hauling aliases
-##################################
-
-# Run one of the quantumstopfrom* aliases over a track stop that is set to dump
-# into a quantum stockpile. The alias will set up the stop to accept all types
-# (the actual types stored in the quantum stockpile should be controlled by the
-# feeder stockpile) and link the indicated adjacent feeder stockpile. For
-# example, the quantumstopfromsouth alias should be used over a track stop set
-# to dump to the North and take items from a feeder stockpile one tile to the
-# South. All you need to do afterwards is assign a vehicle to the stop. The
-# track stop does not need to be constructed yet, but the feeder stockpile needs
-# to exist so we can link to it.
-#
-# Be sure to define the optional 'name' parameter if you want to give your
-# quantum hauling routes custom names. Keep in mind that names have a maximum
-# length of 22 characters. For example:
-# {quantumstopfromsouth name="Trash Dump"}
-#
-# For several examples of these aliases, see
-# https://docs.google.com/spreadsheets/d/1gvTJxxRxZ5V4vXkqwhL-qlr_lXCNt8176TK14m4kSOU
-namelastrouteprefix: ^h--n
-namelastroutesuffix: &^q
-namelastroute: {namelastrouteprefix}{name}{namelastroutesuffix}
-quantumstopprefix: ^hrs&xxx&{enablesequence 17}^
-quantumstopsuffix: ^q{namelastroute}
-quantumstopfromeast: {quantumstopprefix}s{Right}p^{Left}{quantumstopsuffix}
-quantumstopfromsouth: {quantumstopprefix}s{Down}p^{Up}{quantumstopsuffix}
-quantumstopfromwest: {quantumstopprefix}s{Left}p^{Right}{quantumstopsuffix}
-quantumstopfromnorth: {quantumstopprefix}s{Up}p^{Down}{quantumstopsuffix}
-
-
-##################################
-# zone aliases
-##################################
-
-# usage example: {namezone name="my zone name"}
-namezone: ^i{givename}^q
##################################
# animal stockpile adjustments
##################################
-animalsprefix: s
+animalsprefix: {enter_sp_config}
enableanimals: {animalsprefix}e^
disableanimals: {animalsprefix}d^
@@ -117,7 +94,7 @@ permittraps: {forbidtraps}
# food stockpile adjustments
##################################
-foodprefix: s{Down}
+foodprefix: {enter_sp_config}{Down}
enablefood: {foodprefix}e^
disablefood: {foodprefix}d^
@@ -148,9 +125,10 @@ permitdye: {forbiddye}
permittallow: {forbidtallow}
permitmiscliquid: {foodprefix}{Right}{Down 18}p^
+# the next two aliases are for compatibility with previous implementations of
+# Quickfort and are not documented.
# enables everything but seeds
noseeds: {disablefood}{enablefood}{forbidseeds}
-
# enables all food except for the types listed above
food: {noseeds}{forbidpreparedfood}{forbidunpreparedfish}{forbidplants}{forbidbooze}{forbiddye}{forbidtallow}{forbidmiscliquid}
@@ -159,7 +137,7 @@ food: {noseeds}{forbidpreparedfood}{forbidunpreparedfish}{forbidplants}{forbidbo
# furniture stockpile adjustments
##################################
-furnitureprefix: s{Down 2}
+furnitureprefix: {enter_sp_config}{Down 2}
enablefurniture: {furnitureprefix}e^
disablefurniture: {furnitureprefix}d^
@@ -173,11 +151,11 @@ sand: {furnitureprefix}de{Right}f{Right}{Up}&^
# corpses and refuse stockpile adjustments
###########################################
-corpsesprefix: s{Down 3}
+corpsesprefix: {enter_sp_config}{Down 3}
enablecorpses: {corpsesprefix}e^
disablecorpses: {corpsesprefix}d{Up}d^
-refuseprefix: s{Down 4}
+refuseprefix: {enter_sp_config}{Down 4}
enablerefuse: {refuseprefix}e^
disablerefuse: {refuseprefix}d^
@@ -220,7 +198,7 @@ permitcraftrefuse: {permitskulls}{permitbones}{permitshells}{permitteeth}{permit
# stone stockpile adjustments
##################################
-stoneprefix: s{Down 5}
+stoneprefix: {enter_sp_config}{Down 5}
enablestone: {stoneprefix}e^
disablestone: {stoneprefix}d^
@@ -259,7 +237,7 @@ permitclay: {stoneprefix}{Right}{Down 3}p^
# ammo stockpile adjustments
##################################
-ammoprefix: s{Down 6}
+ammoprefix: {enter_sp_config}{Down 6}
enableammo: {ammoprefix}e^
disableammo: {ammoprefix}d^
@@ -274,7 +252,7 @@ forbidbonebolts: {ammoprefix}{Right}{Down 2}{Right}{Down}&^
# bar stockpile adjustments
##################################
-barsprefix: s{Down 8}
+barsprefix: {enter_sp_config}{Down 8}
enablebars: {barsprefix}e^
disablebars: {barsprefix}d^
@@ -309,7 +287,7 @@ forbidblocks: {barsprefix}{Down 2}f{Down}f{Down}f^
# gem stockpile adjustments
##################################
-gemsprefix: s{Down 9}
+gemsprefix: {enter_sp_config}{Down 9}
enablegems: {gemsprefix}e^
disablegems: {gemsprefix}d^
@@ -330,7 +308,7 @@ forbidcutstone: {gemsprefix}{Right}{Down 4}f^
# finished goods stockpile adjustments
#######################################
-finishedgoodsprefix: s{Down 10}
+finishedgoodsprefix: {enter_sp_config}{Down 10}
enablefinishedgoods: {finishedgoodsprefix}e^
disablefinishedgoods: {finishedgoodsprefix}d^
@@ -341,7 +319,7 @@ jugs: {finishedgoodsprefix}{Right}f{Right}{Up 2}&{Left}{Down 2}f{Down}f{Down}f^
# cloth
##################################
-clothprefix: s{Down 12}
+clothprefix: {enter_sp_config}{Down 12}
enablecloth: {clothprefix}e^
disablecloth: {clothprefix}d^
@@ -355,7 +333,7 @@ adamantinecloth: {clothprefix}b{Right}{Up}p^
# weapon stockpile adjustments
##################################
-weaponsprefix: s{Down 14}
+weaponsprefix: {enter_sp_config}{Down 14}
enableweapons: {weaponsprefix}e^
disableweapons: {weaponsprefix}d^
@@ -396,7 +374,7 @@ permitartifactweapons: {forbidartifactweapons}
# armor stockpile adjustments
##################################
-armorprefix: s{Down 15}
+armorprefix: {enter_sp_config}{Down 15}
enablearmor: {armorprefix}e^
disablearmor: {armorprefix}d^
@@ -432,32 +410,18 @@ permitartifactarmor: {forbidartifactarmor}
# others
##################################
-coinsprefix: s{Down 7}
+coinsprefix: {enter_sp_config}{Down 7}
enablecoins: {coinsprefix}e^
disablecoins: {coinsprefix}d^
-leatherprefix: s{Down 11}
+leatherprefix: {enter_sp_config}{Down 11}
enableleather: {leatherprefix}e^
disableleather: {leatherprefix}d^
-woodprefix: s{Down 13}
+woodprefix: {enter_sp_config}{Down 13}
enablewood: {woodprefix}e^
disablewood: {woodprefix}d^
-sheetprefix: s{Down 16}
+sheetprefix: {enter_sp_config}{Down 16}
enablesheet: {sheetprefix}e^
disablesheet: {sheetprefix}d^
-
-
-##################################
-# farm plots
-##################################
-
-# Sets a farm plot to grow the LAST type of seed in the list of available seeds
-# for all 4 seasons. The last seed is used because it's usually Plump helmet
-# spawn, suitable for post-embark. If you only have 1 seed type, that'll be
-# grown.
-growlastcropall: a/&b/&c/&d/&
-
-# Like growlastcropall but grows the first one in the list instead.
-growfirstcropall: a&b&c&d&
diff --git a/dfhack-config/quickfort/aliases.txt b/dfhack-config/quickfort/aliases.txt
index 1d1ebff9f..a3e52052d 100644
--- a/dfhack-config/quickfort/aliases.txt
+++ b/dfhack-config/quickfort/aliases.txt
@@ -1,106 +1,17 @@
-# Aliases for quickfort #query mode blueprints
+# Custom aliases for quickfort query mode blueprints
#
-# This file defines custom keycode shortcuts for #query mode blueprints.
-# Definitions in this file take precedence over any definitions in the baseline
-# aliases configuration file at hack/data/quickfort/aliases-common.txt. See that
-# file for the many useful aliases that are already defined.
+# This file defines custom key sequence shortcuts for query mode blueprints.
+# Definitions in this file take precedence over any definitions in the
+# baseline aliases configuration file in
+# hack/data/quickfort/aliases-common.txt
#
-# If possible, build on the baseline aliases when defining your own aliases. If
-# the DF UI screens change, updated baseline aliases may allow your aliases to
-# automatically adapt to the new UI. For example, if you create an alias to
-# modify particular furniture stockpile settings, start your alias with
-# "{furnitureprefix}" instead of manually writing "s{Down 2}". Then, if the
-# location of the furniture setting changes, your alias will automatically
-# inherit the updated position when DFHack is updated.
+# Please see
+# https://docs.dfhack.org/en/latest/docs/guides/quickfort-alias-guide.html
+# or
+# hack/docs/docs/guides/quickfort-alias-guide.html
+# in your DF installation directory for alias syntax documentation and an
+# overview of the DFHack alias standard library.
#
-# Aliases simplify repetitive tasks, such as configuring workshop profiles or
-# adjusting a food stockpile to accept only seeds. Making new aliases is just a
-# matter of mimicking the keys used to navigate through the menus and select
-# options. Use the aliases in your blueprint spreadsheets by writing an alias by
-# itself in a cell, like "nocontainers", or reference an alias in a larger
-# sequence by enclosing it in curly brackets, like "{nocontainers}{linksonly}"
#
-# For example, say you have the following build and place blueprints:
-#
-# #build masonry workshop
-# ~, ~,~,`,`,`
-# ~,wm,~,`,`,`
-# ~, ~,~,`,`,`
-#
-# #place stockpile for mason
-# ~,~,~,s,s,s
-# ~,~,~,s,s,s
-# ~,~,~,s,s,s
-#
-# and you want to configure the stockpile to hold only non-economic ("other")
-# stone and to give to the adjacent mason workshop. You could write the
-# keystrokes directly:
-#
-# #query start(4;1;upper left corner of stockpile) configure mason
-# ~,~,~,s{Down 5}deb{Right}{Down 2}p^,`,`
-# ~,~,~,g{Left 2}&, `,`
-# ~,~,~,`, `,`
-#
-# or you could use alias names:
-#
-# #query start(4;1;upper left corner of stockpile) configure mason
-# ~,~,~,otherstone,`,`
-# ~,~,~,give2left, `,`
-# ~,~,~,`, `,`
-#
-# you can combine the two aliases above into a single cell as well, if desired:
-#
-# #query start(4;1;upper left corner of stockpile) configure mason
-# ~,~,~,{otherstone}{give2left},`,`
-# ~,~,~,`, `,`
-# ~,~,~,`, `,`
-#
-# The syntax for defining aliases is:
-# aliasname: keystrokes
-#
-# Where aliasname is at least two letters or digits long (including dashes and
-# underscores) and keystrokes are whatever you would type into the DF UI. A
-# keystroke can also be a named keycode from the DF interface definition file
-# (data/init/interface.txt), enclosed in curly brackets like an alias, like:
-# "{Right}" or "{Enter}". In # order to avoid naming conflicts between aliases
-# and keycodes, the convention is to start aliases with a lowercase letter.
-#
-# Anything enclosed within curly brackets can also have a number after it,
-# indicating how many times that alias or keycode should be repeated. For
-# example: "{togglesequence 9}" or "{Down 5}".
-#
-# Finally, you can specify sub-aliases that will only be defined while the
-# current alias is being resolved by adding them after the alias name (but
-# before the repetition number, if it is specified), for example:
-# {quantumstopfromeast name="Trash Dump"}
-# The value of the sub-alias 'name' is used by quantumstopfromeast (or one of
-# the aliases it calls) to give a useful name to your quantum dump hauling
-# route. You can also use this format to temporarily override the value of an
-# existing regularly-defined alias.
-#
-# Sub-aliases must be in one of the following formats:
-# subaliasname=valwithnospaces
-# subaliasname="val with spaces"
-# subaliasname={someotheralias repetitions}
-#
-# Ctrl, Alt, and Shift modifiers can be specified for the next keycode by adding
-# them into the key sequence. For example, Alt-h is written as "{Alt}h".
-#
-# Some frequently-used keystrokes are assigned shorthand characters. Think of
-# them as single-character aliases that don't need to be surrounded in curly
-# brackets:
-# & expands to {Enter}
-# @ expands to {Shift}{Enter}
-# ~ expands to {Alt}
-# ! expands to {Ctrl}
-# ^ expands to {ESC}
-#
-# There is also a non-standard alias built into the code for the common
-# shorthand for "make room":
-# r+ expands to r+&
-#
-# If you need literal verisons of the shorthand characters, surround them in
-# curly brackets, for example: "{!}"
-#
-#
-# Add your custom aliases here:
+# Add your custom aliases here. Example:
+# food_stash: {foodprefix}b{Right}{Down 11}p^{permitplants}
diff --git a/docs/Authors.rst b/docs/Authors.rst
index e3478e486..83ce58ef0 100644
--- a/docs/Authors.rst
+++ b/docs/Authors.rst
@@ -159,6 +159,7 @@ stolencatkarma
Stoyan Gaydarov sgayda2
suokko suokko shrieker
sv-esk sv-esk
+Tachytaenius wolfboyft
Tacomagic
thefriendlyhacker thefriendlyhacker
TheHologram TheHologram
diff --git a/docs/Documentation.rst b/docs/Documentation.rst
index 03531998e..5e1f8c599 100644
--- a/docs/Documentation.rst
+++ b/docs/Documentation.rst
@@ -119,15 +119,13 @@ Add link targets if you need them, but otherwise plain headings are preferred.
Scripts have link targets created automatically.
-Building the documentation
-==========================
+Required dependencies
+=====================
.. highlight:: shell
-Required dependencies
----------------------
In order to build the documentation, you must have Python with Sphinx
-version |sphinx_min_version| or later. Both Python 2.x and 3.x are supported.
+version |sphinx_min_version| or later. Python 3 is recommended.
When installing Sphinx from OS package managers, be aware that there is
another program called Sphinx, completely unrelated to documentation management.
@@ -146,7 +144,7 @@ For more detailed platform-specific instructions, see the sections below:
Linux
-~~~~~
+-----
Most Linux distributions will include Python by default. If not, start by
installing Python (preferably Python 3). On Debian-based distros::
@@ -172,7 +170,7 @@ system-wide by running pip with ``sudo``. In any case, you will need the folder
containing ``sphinx-build`` to be in your ``$PATH``.
macOS
-~~~~~
+-----
macOS has Python 2.7 installed by default, but it does not have the pip package manager.
You can install Homebrew's Python 3, which includes pip, and then install the
@@ -193,7 +191,7 @@ If not, just installing sphinx-doc for macOS's system Python 2.7 is fine.
Windows
-~~~~~~~
+-------
Python for Windows can be downloaded `from python.org `_.
The latest version of Python 3 is recommended, as it includes pip already.
@@ -210,6 +208,11 @@ Once you have pip available, you can install Sphinx with the following command::
Note that this may require opening a new (admin) command prompt if you just
installed pip from the same command prompt.
+Building the documentation
+==========================
+
+Once the required dependencies are installed, there are multiple ways to run
+Sphinx to build the docs:
Using CMake
-----------
@@ -230,7 +233,7 @@ ways to do this:
* You can edit the ``BUILD_DOCS`` setting in CMakeCache.txt directly
-* You can use the CMake GUI to change ``BUILD_DOCS``
+* You can use the CMake GUI or ``ccmake`` to change the ``BUILD_DOCS`` setting
* On Windows, if you prefer to use the batch scripts, you can run
``generate-msvc-gui.bat`` and set ``BUILD_DOCS`` through the GUI. If you are
@@ -238,19 +241,28 @@ ways to do this:
it to add the flag. You can also run ``cmake`` on the command line, similar to
other platforms.
+The generated documentation will be stored in ``docs/html`` in the root DFHack
+folder, and will be installed to ``hack/docs`` when you next install DFHack in a
+DF folder.
+
Running Sphinx manually
-----------------------
-You can also build the documentation without going through CMake, which may be
-faster. There is a ``docs/build.sh`` script provided for Linux and macOS that
-will run essentially the same command that CMake runs - see the script for
-additional options.
+You can also build the documentation without running CMake - this is faster if
+you only want to rebuild the documentation regardless of any code changes. There
+is a ``docs/build.sh`` script provided for Linux and macOS that will run
+essentially the same command that CMake runs when building the docs - see the
+script for additional options.
To build the documentation with default options, run the following command from
the root DFHack folder::
sphinx-build . docs/html
+The resulting documentation will be stored in ``docs/html`` (you can specify
+a different path when running ``sphinx-build`` manually, but be warned that
+Sphinx may overwrite existing files in this folder).
+
Sphinx has many options to enable clean builds, parallel builds, logging, and
more - run ``sphinx-build --help`` for details.
@@ -263,7 +275,7 @@ want to build a PDF version locally, you will need ``pdflatex``, which is part
of a TeX distribution. The following command will then build a PDF, located in
``docs/pdf/latex/DFHack.pdf``, with default options::
- sphinx-build -M latexpdf . ./docs/pdf
+ sphinx-build -M latexpdf . docs/pdf
There is a ``docs/build-pdf.sh`` script provided for Linux and macOS that runs
this command for convenience - see the script for additional options.
@@ -272,10 +284,11 @@ this command for convenience - see the script for additional options.
Building the changelogs
=======================
-If you have Python installed, but do not want to build all of the documentation,
-you can build the changelogs with the ``docs/gen_changelog.py`` script. This
-script provides additional options, including one to build individual changelogs
-for all DFHack versions - run ``python docs/gen_changelog.py --help`` for details.
+If you have Python installed, you can build just the changelogs without building
+the rest of the documentation by running the ``docs/gen_changelog.py`` script.
+This script provides additional options, including one to build individual
+changelogs for all DFHack versions - run ``python docs/gen_changelog.py --help``
+for details.
Changelog entries are obtained from ``changelog.txt`` files in multiple repos.
This allows changes to be listed in the same repo where they were made. These
@@ -302,3 +315,30 @@ Changelog syntax
.. include:: /docs/changelog.txt
:start-after: ===help
:end-before: ===end
+
+.. _docs-ci:
+
+GitHub Actions
+==============
+
+Documentation is built automatically with GitHub Actions (a GitHub-provided
+continuous integration service) for all pull requests and commits in the
+"dfhack" and "scripts" repositories. These builds run with strict settings, i.e.
+warnings are treated as errors. If a build fails, you will see a red "x" next to
+the relevant commit or pull request. You can view detailed output from Sphinx in
+a few ways:
+
+* Click on the red "x" (or green checkmark), then click "Details" next to
+ the "Build / docs" entry
+* For pull requests only: navigate to the "Checks" tab, then click on "Build" in
+ the sidebar to expand it, then "docs" under it
+
+Sphinx output will be visible under the step named "Build docs". If a different
+step failed, or you aren't sure how to interpret the output, leave a comment
+on the pull request (or commit).
+
+You can also download the "docs" artifact from the summary page (typically
+accessible by clicking "Build") if the build succeeded. This is a way to
+visually inspect what the documentation looks like when built without installing
+Sphinx locally, although we recommend installing Sphinx if you are planning to
+do any significant work on the documentation.
diff --git a/docs/Lua API.rst b/docs/Lua API.rst
index ffce7fd4e..1fe403034 100644
--- a/docs/Lua API.rst
+++ b/docs/Lua API.rst
@@ -1679,7 +1679,11 @@ Low-level building creation functions:
Returns *false* if the building cannot be placed, or *true, width,
height, rect_area, true_area*. Returned width and height are the
final values used by the building; true_area is less than rect_area
- if any tiles were removed from designation.
+ if any tiles were removed from designation. You can specify a non-rectangular
+ designation for building types that support extents by setting the
+ ``room.extents`` bitmap before calling this function. The extents will be
+ reset, however, if the size returned by this function doesn't match the
+ input size parameter.
* ``dfhack.buildings.constructAbstract(building)``
@@ -1768,7 +1772,9 @@ Among them are:
- ``fields = { ... }``
- Initializes fields of the building object after creation with ``df.assign``.
+ Initializes fields of the building object after creation with
+ ``df.assign``. If ``room.extents`` is assigned this way and this function
+ returns with error, the memory allocated for the extents is freed.
- ``width = ..., height = ..., direction = ...``
diff --git a/docs/Plugins.rst b/docs/Plugins.rst
index 73c0e1073..f8fcd569d 100644
--- a/docs/Plugins.rst
+++ b/docs/Plugins.rst
@@ -187,8 +187,9 @@ Usage and related commands:
:reveal demon: Reveals everything and allows unpausing - good luck!
:unreveal: Reverts the effects of ``reveal``
:revtoggle: Switches between ``reveal`` and ``unreveal``
-:revflood: Hide everything, then reveal tiles with a path to the cursor
- (useful to make walled-off rooms vanish)
+:revflood: Hide everything, then reveal tiles with a path to the cursor.
+ Note that tiles behind constructed walls are also revealed as a
+ workaround for :bug:`1871`.
:revforget: Discard info about what was visible before revealing the map.
Only useful where (e.g.) you abandoned with the fort revealed
and no longer want the data.
diff --git a/docs/changelog.txt b/docs/changelog.txt
index e3f299def..d3b4d72f1 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -33,29 +33,44 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
# Future
+# 0.47.04-r4
+
## Fixes
- Fixed an issue on some Linux systems where DFHack installed through a package manager would attempt to write files to a non-writable folder (notably when running `exportlegends` or `gui/autogems`)
-- `buildingplan`: artifacts are now successfully matched when max quality is set to ``artifacts``
-- `buildingplan`: no longer erroneously matches items to buildings while the game is paused
+- `buildingplan`: fixed an issue preventing artifacts from being matched when the maximum item quality is set to ``artifacts``
+- `buildingplan`: stopped erroneously matching items to buildings while the game is paused
+- `buildingplan`: fixed a crash when pressing 0 while having a noble room selected
+- `dwarfvet`: fixed a crash that could occur when discharging patients
- `dwarfmonitor`: fixed a crash when opening the ``prefs`` screen if units have vague preferences
- `embark-assistant`: fixed an issue causing incursion resource matching (e.g. sand/clay) to skip some tiles if those resources were provided only through incursions
-- `embark-assistant`: corrected river size determination by performing it at the MLT level rather than the world tile one
+- `embark-assistant`: corrected river size determination by performing it at the MLT level rather than the world tile level
+- `search`: fixed an issue where search options might not display if screens were destroyed and recreated programmatically (e.g. with `quickfort`)
+- `workflow`: fixed an error when creating constraints on "mill plants" jobs and some other plant-related jobs
- `zone`: fixed an issue causing the ``enumnick`` subcommand to run when attempting to run ``assign``, ``unassign``, or ``slaughter``
## Misc Improvements
-- `buildingplan`: all buildings, furniture, and constructions are now supported (except for instruments)
-- `buildingplan`: now respects building job_item filters when matching items, so you can set your own programmatic filters for buildings before submitting them to buildingplan
-- `buildingplan`: default filter setting for max quality changed from ``artifact`` to ``masterwork``
-- `buildingplan`: min quality adjustment hotkeys changed from 'qw' to 'QW' to avoid conflict with existing hotkeys for setting roller speed. max quality adjustment hotkeys changed from 'QW' to 'AS' to make room for the min quality hotkey changes.
-- `buildingplan`: new global settings page accessible via ``G`` hotkey when on any building build screen; ``Quickfort Mode`` toggle for legacy Python Quickfort has been moved to this page
-- `buildingplan`: new global settings for whether generic building materials should match blocks, boulders, logs, and/or bars. defaults are everything but bars.
-- `quickfort`: The Dreamfort sample blueprints now have complete walkthroughs for each fort level and importable orders that automate basic fort stock management
-- `quickfort`: More blueprints have been added to the blueprints library: several bedroom layouts, the Saracen Crypts, and the complete fortress example from Python Quickfort: TheQuickFortress
+- `buildingplan`: added support for all buildings, furniture, and constructions (except for instruments)
+- `buildingplan`: added support for respecting building job_item filters when matching items, so you can set your own programmatic filters for buildings before submitting them to buildingplan
+- `buildingplan`: changed default filter setting for max quality from ``artifact`` to ``masterwork``
+- `buildingplan`: changed min quality adjustment hotkeys from 'qw' to 'QW' to avoid conflict with existing hotkeys for setting roller speed - also changed max quality adjustment hotkeys from 'QW' to 'AS' to make room for the min quality hotkey changes
+- `buildingplan`: added a new global settings page accessible via the ``G`` hotkey when on any building build screen; ``Quickfort Mode`` toggle for legacy Python Quickfort has been moved to this page
+- `buildingplan`: added new global settings for whether generic building materials should match blocks, boulders, logs, and/or bars - defaults are everything but bars
- `embark-assistant`: split the lair types displayed on the local map into mound, burrow, and lair
+- `probe`: added more output for designations and tile occupancy
+- `quickfort`: The Dreamfort sample blueprints now have complete walkthroughs for each fort level and importable orders that automate basic fort stock management
+- `quickfort`: added more blueprints to the blueprints library: several bedroom layouts, the Saracen Crypts, and the complete fortress example from Python Quickfort: TheQuickFortress
+
+## Documentation
+- `quickfort-alias-guide`: alias syntax and alias standard library documentation for `quickfort` blueprints
+- `quickfort-library-guide`: overview of the quickfort blueprint library
## API
- `buildingplan`: added Lua interface API
-- add item type param to dfhack.job.isSuitableMaterial() so the non_economic flag can be properly handled (it was being matched for all item types instead of just boulders)
+- ``dfhack.job.isSuitableMaterial()``: added an item type parameter so the ``non_economic`` flag can be properly handled (it was being matched for all item types instead of just boulders)
+- ``Buildings::setSize()``: changed to reuse existing extents when possible
+
+## Lua
+- ``utils.addressof()``: fixed for raw userdata
# 0.47.04-r3
diff --git a/docs/guides/quickfort-alias-guide.rst b/docs/guides/quickfort-alias-guide.rst
new file mode 100644
index 000000000..b1f525eba
--- /dev/null
+++ b/docs/guides/quickfort-alias-guide.rst
@@ -0,0 +1,801 @@
+.. _quickfort-alias-guide:
+
+Quickfort Alias Guide
+=====================
+
+Aliases allow you to use simple words to represent complicated key sequences
+when configuring buildings and stockpiles in quickfort ``#query`` blueprints.
+
+For example, say you have the following ``#build`` and ``#place`` blueprints::
+
+ #build masonry workshop
+ ~, ~,~,`,`,`
+ ~,wm,~,`,`,`
+ ~, ~,~,`,`,`
+
+ #place stockpile for mason
+ ~,~,~,s,s,s
+ ~,~,~,s,s,s
+ ~,~,~,s,s,s
+
+and you want to configure the stockpile to hold only non-economic ("other")
+stone and to give to the adjacent mason workshop. You could write the
+key sequences directly::
+
+ #query configure stockpile with expanded key sequences
+ ~,~,~,s{Down 5}deb{Right}{Down 2}p^,`,`
+ ~,~,~,g{Left 2}&, `,`
+ ~,~,~,`, `,`
+
+or you could use aliases::
+
+ #query configure stockpile with aliases
+ ~,~,~,otherstone,`,`
+ ~,~,~,give2left, `,`
+ ~,~,~,`, `,`
+
+If the stockpile had only a single tile, you could also replay both aliases in
+a single cell::
+
+ #query configure mason with multiple aliases in one cell
+ ~,~,~,{otherstone}{give2left},`,`
+ ~,~,~,`, `,`
+ ~,~,~,`, `,`
+
+With aliases, blueprints are much easier to read and understand. They also
+save you from having to copy the same long key sequences everywhere.
+
+Alias definition files
+----------------------
+
+DFHack comes with a library of aliases for you to use that are always
+available when you run a ``#query`` blueprint. Many blueprints can be built
+with just those aliases. This "standard alias library" is stored in
+:source:`data/quickfort/aliases-common.txt` (installed under the ``hack`` folder
+in your DFHack installation). The aliases in that file are described at the
+`bottom of this document `.
+
+Please do not edit the aliases in the standard library directly. The file will
+get overwritten when DFHack is updated and you'll lose your changes. Instead,
+add your custom aliases to :source:`dfhack-config/quickfort/aliases.txt`.
+Definitions in this file take precedence over any definitions in the standard
+library.
+
+Alias syntax and usage
+----------------------
+
+The syntax for defining aliases is::
+
+ aliasname: expansion
+
+Where ``aliasname`` is at least two letters or digits long (dashes and
+underscores are also allowed) and ``expansion`` is whatever you would type
+into the DF UI.
+
+You use an alias by typing its name into a ``#query`` blueprint cell where you
+want it to be applied. You can use an alias by itself or as part of a larger
+sequence, potentially with other aliases. If the alias is the only text in the
+cell, the alias name is matched and its expansion is used. If the alias has
+other keys before or after it, the alias name must be surrounded in curly
+brackets (:kbd:`{` and :kbd:`}`). An alias can be surrounded in curly brackets
+even if it is the only text in the cell, it just isn't necesary. For example,
+the following blueprint uses the ``aliasname`` alias by itself in the first
+two rows and uses it as part of a longer sequence in the third row::
+
+ #query apply alias 'aliasname' in three different ways
+ aliasname
+ {aliasname}
+ literaltext{aliasname}literaltext
+
+For a more concrete example of an alias definition, a simple alias that
+configures a stockpile to have no bins (:kbd:`C`) and no barrels (:kbd:`E`)
+assigned to it would look like this::
+
+ nocontainers: CE
+
+The alias definition can also contain references to other aliases by including
+the alias names in curly brackets. For example, ``nocontainers`` could be
+equivalently defined like this::
+
+ nobins: C
+ nobarrels: E
+ nocontainers: {nobins}{nobarrels}
+
+Aliases used in alias definitions *must* be surrounded by curly brackets, even
+if they are the only text in the definition::
+
+ alias1: text1
+ alias2: alias1
+ alias3: {alias1}
+
+Here, ``alias1`` and ``alias3`` expand to ``text1``, but ``alias2`` expands to
+the literal text ``alias1``.
+
+Keycodes
+~~~~~~~~
+
+Non-printable characters, like the arrow keys, are represented by their
+keycode name and are also surrounded by curly brackets, like ``{Right}`` or
+``{Enter}``. Keycodes are used exactly like aliases -- they just have special
+expansions that you wouldn't be able to write yourself. In order to avoid
+naming conflicts between aliases and keycodes, the convention is to start
+aliases with a lowercase letter.
+
+Any keycode name from the DF interface definition file
+(data/init/interface.txt) is valid, but only a few keycodes are actually
+useful for blueprints::
+
+ Up
+ Down
+ Left
+ Right
+ Enter
+ ESC
+ Backspace
+ Space
+ Tab
+
+Repetitions
+~~~~~~~~~~~
+
+Anything enclosed within curly brackets can also have a number, indicating how
+many times that alias or keycode should be repeated. For example:
+``{togglesequence 9}`` or ``{Down 5}`` will repeat the ``togglesequence``
+alias nine times and the ``Down`` keycode five times, respectively.
+
+Modifier keys
+~~~~~~~~~~~~~
+
+Ctrl, Alt, and Shift modifiers can be specified for the next key by adding
+them into the key sequence. For example, Alt-h is written as ``{Alt}h``.
+
+Shorthand characters
+~~~~~~~~~~~~~~~~~~~~
+
+Some frequently-used keycodes are assigned shorthand characters. Think of them
+as single-character aliases that don't need to be surrounded in curly
+brackets::
+
+ & expands to {Enter}
+ @ expands to {Shift}{Enter}
+ ~ expands to {Alt}
+ ! expands to {Ctrl}
+ ^ expands to {ESC}
+
+If you need literal versions of the shorthand characters, surround them in
+curly brackets, for example: use ``{!}`` for a literal exclamation point.
+
+Built-in aliases
+~~~~~~~~~~~~~~~~
+
+Most aliases that come with DFHack are in ``aliases-common.txt``, but there is
+one alias built into the code for the common shorthand for "make room"::
+
+ r+ expands to r+{Enter}
+
+This needs special code support since ``+`` can't normally be used in alias
+names. You can use it just like any other alias, either by itself in a cell
+(``r+``) or surrounded in curly brackets (``{r+}``).
+
+Sub-aliases
+~~~~~~~~~~~
+
+You can specify sub-aliases that will only be defined while the current alias
+is being resolved. This is useful for "injecting" custom behavior into the
+middle of a larger alias. As a simple example, the ``givename`` alias is defined
+like this::
+
+ givename: !n{name}&
+
+Note the use of the ``name`` alias inside of the ``givename`` expansion. In your
+``#query`` blueprint, you could write something like this, say, while over your
+main drawbridge::
+
+ {givename name="Front Gate"}
+
+The value that you give the sub-alias ``name`` will be used when the
+``givename`` alias is expanded. Without sub-aliases, we'd have to define ``givename`` like this::
+
+ givenameprefix: !n
+ givenamesuffix: &
+
+and use it like this::
+
+ {givenameprefix}Front Gate{givenamesuffix}
+
+which is more difficult to write and more difficult to understand.
+
+A handy technique is to define an alias with some sort of default
+behavior and then use sub-aliases to override that behavior as necessary. For
+example, here is a simplified version of the standard ``quantum`` alias that
+sets up quantum stockpiles::
+
+ quantum_enable: {enableanimals}{enablefood}{enablefurniture}...
+ quantum: {linksonly}{nocontainers}{quantum_enable}
+
+You can use the default behavior of ``quantum_enable`` by just using the
+``quantum`` alias by itself. But you can override ``quantum_enable`` to just
+enable furniture for some specific stockpile like this::
+
+ {quantum quantum_enable={enablefurniture}}
+
+If an alias uses a sub-alias in its expansion, but the sub-alias is not defined when the alias is used, quickfort will halt the ``#query`` blueprint with an error. If you want your aliases to work regardless of whether sub-aliases are defined, then you must define them with default values like ``quantum_enable`` above.
+
+Sub-aliases must be in one of the following formats::
+
+ subaliasname=keyswithnospaces
+ subaliasname="keys with spaces or {aliases}"
+ subaliasname={singlealias}
+
+If you specify both a sub-alias and a number of repetitions, the number for
+repetitions goes last, right before the :kbd:`}`::
+
+ {alias subaliasname=value repetitions}
+
+Beyond query mode
+-----------------
+``#query`` blueprints normally do things in DF :kbd:`q`\uery mode, but nobody
+said that we have to *stay* in query mode. ``#query`` blueprints send
+arbitrary key sequences to Dwarf Fortress. Anything you can do by typing keys
+into DF, you can do in a ``#query`` blueprint. It is absolutely fine to
+temporarily exit out of query mode, go into, say, hauling or zone or hotkey
+mode, and do whatever needs to be done.
+
+You just have to make certain to exit out of that alternate mode and get back
+into :kbd:`q`\uery mode at the end of the key sequence. That way quickfort can
+continue on configuring the next tile -- a tile configuration that assumes the
+game is still in query mode.
+
+For example, here is the standard library alias for giving a name to a zone::
+
+ namezone: ^i{givename}^q
+
+The first :kbd:`\^` exits out of query mode. Then :kbd:`i` enters zones mode.
+We then reuse the standard alias for giving something a name. Finally, we exit
+out of zones mode with another :kbd:`\^` and return to :kbd:`q`\uery mode.
+
+.. _quickfort-alias-library:
+
+The DFHack standard alias library
+---------------------------------
+
+DFHack comes with many useful aliases for you to use in your blueprints. Many
+blueprints can be built with just these aliases alone, with no custom aliases
+required.
+
+This section goes through all aliases provided by the DFHack standard alias
+library, discussing their intended usage and detailing sub-aliases that you
+can define to customize their behavior.
+
+If you do define your own custom aliases in
+``dfhack-config/quickfort/aliases.txt``, try to build on the library aliases.
+For example, if you create an alias to modify particular furniture stockpile
+settings, start your alias with ``{furnitureprefix}`` instead of
+``s{Down 2}``. Using library prefixes will allow sub-aliases to work with your
+aliases just like they do with library aliases. In this case, using
+``{furnitureprefix}`` will allow your stockpile customization alias to work
+with both stockpiles and hauling routes.
+
+Naming aliases
+~~~~~~~~~~~~~~
+
+These aliases give descriptive names to workshops, levers, stockpiles, zones,
+etc. Dwarf Fortress building, stockpile, and zone names have a maximum length
+of 20 characters.
+
+======== ===========
+Alias Sub-aliases
+======== ===========
+givename name
+namezone name
+======== ===========
+
+``givename`` works anywhere you can hit Ctrl-n to customize a name, like when
+the cursor is over buildings and stockpiles. Example::
+
+ #place
+ f(10x2)
+
+ #query
+ {booze}{givename name=booze}
+
+``namezone`` is intended to be used when over an activity zone. It includes
+commands to get into zones mode, set the zone name, and get back to query
+mode. Example::
+
+ #zone
+ n(2x2)
+
+ #query
+ {namezone name="guard dog pen"}
+
+Quantum stockpile aliases
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These aliases make it easy to create :wiki:`minecart stop-based quantum stockpiles `.
+
++----------------------+------------------+
+| Alias | Sub-aliases |
++======================+==================+
+| quantum | | name |
+| | | quantum_enable |
++----------------------+------------------+
+| quantumstopfromnorth | | name |
++----------------------+ | stop_name |
+| quantumstopfromsouth | | route_enable |
++----------------------+ |
+| quantumstopfromeast | |
++----------------------+ |
+| quantumstopfromwest | |
++----------------------+------------------+
+| quantumstop | | name |
+| | | stop_name |
+| | | route_enable |
+| | | move |
+| | | move_back |
++----------------------+------------------+
+
+The idea is to use a minecart on a track stop to dump an infinite number of
+items into a receiving "quantum" stockpile, which significantly simplifies
+stockpile management. These aliases configure the quantum stockpile and
+hauling route that make it all work. Here is a complete example for quantum
+stockpiling weapons, armor, and ammunition. It has a 3x1 feeder stockpile on
+the bottom (South), the trackstop in the center, and the quantum stockpile on
+the top (North). Note that the feeder stockpile is the only stockpile that
+needs to be configured to control which types of items end up in the quantum
+stockpile. By default, the hauling route and quantum stockpile itself simply
+accept whatever is put into them.
+
+::
+
+ #place
+ ,c
+ ,
+ pdz(3x1)
+
+ #build
+ ,
+ ,trackstopN
+
+ #query message(remember to assign a minecart to the new route)
+ ,quantum
+ ,quantumstopfromsouth
+ nocontainers
+
+The ``quantum`` alias configures a 1x1 stockpile to be a quantum stockpile. It
+bans all containers and prevents the stockpile from being manually filled. By
+default, it also enables storage of all item categories (except corpses and
+refuse), so it doesn't really matter what letter you use to place the
+stockpile. :wiki:`Refuse` is excluded by default since otherwise clothes and
+armor in the quantum stockpile would rot away. If you want corpses or bones in
+your quantum stockpile, use :kbd:`y` and/or :kbd:`r` to place the stockpile
+and the ``quantum`` alias will just enable the remaining types. If you *do*
+enable refuse in your quantum stockpile, be sure you avoid putting useful
+clothes or armor in there!
+
+The ``quantumstopfromsouth`` alias is run over the track stop and configures
+the hauling route, again, allowing all item categories into the minecart by
+default so any item that can go into the feeder stockpile can then be placed
+in the minecart. It also links the hauling route with the feeder stockpile to
+the South.The track stop does not need to be fully constructed before the
+``#query`` blueprint is run, but the feeder stockpile needs to exist so we can
+link to it. This means that the three blueprints above can be run one right
+after another, without any dwarven labor in between them, and the quantum
+stockpile will work properly.
+
+Finally, the ``nocontainers`` alias simply configures the feeder stockpile to
+not have any containers (which would just get in the way here). If we wanted
+to be more specific about what item types we want in the quantum stockpile, we
+could configure the feeder stockpile further, for example with standard
+`stockpile adjustment aliases `.
+
+After the blueprints are run, the last step is to manually assign a minecart
+to the newly-defined hauling route.
+
+You can define sub-aliases to customize how these aliases work, for example to
+have fine-grained control over what item types are enabled for the route and
+quantum stockpile. We'll go over those options below, but first, here is an
+example for how to just give names to everything::
+
+ #query message(remember to assign a minecart to the new route)
+ ,{quantum name="armory quantum"}
+ ,{quantumstopfromsouth name="Armory quantum" stop_name="Armory quantum stop"}{givename name="armory dumper"}
+ {givename name="armory feeder"}
+
+All ``name`` sub-aliases are completely optional, of course. Keep in mind that
+hauling route names have a maximum length of 22 characters, hauling route stop
+names have a maximum length of 21 characters, and all other names have a
+maximum length of 20 characters.
+
+If you want to be absolutely certain that nothing ends up in your quantum
+stockpile other than what you've configured in the feeder stockpile, you can
+set the ``quantum_enable`` sub-alias for the ``quantum`` alias. This can
+prevent, for example, somebody's knocked-out tooth from being considered part
+of your furniture quantum stockpile when it happened to land on it during a
+fistfight::
+
+ #query
+ {quantum name="furniture quantum" quantum_enable={enablefurniture}}
+
+You can have similar control over the hauling route if you need to be more
+selective about what item types are allowed into the minecart. If you have
+multiple specialized quantum stockpiles that use a common feeder pile, for
+example, you can set the ``route_enable`` sub-alias::
+
+ #query
+ {quantumstopfromsouth name="Steel bar quantum" route_enable="{enablebars}{steelbars}"}
+
+Any of the `stockpile configuration aliases ` can
+be used for either the ``quantum_enable`` or ``route_enable`` sub-aliases.
+Experienced Dwarf Fortress players may be wondering how the same aliases can
+work in both contexts since the keys for entering the configuration screen
+differ. Fear not! There is some sub-alias magic at work here. If you define
+your own stockpile configuraiton aliases, you can use the magic yourself by
+building your aliases on the ``*prefix`` aliases described later in this
+guide.
+
+Finally, the ``quantumstop`` alias is a more general version of the
+``quantumstopfrom*`` aliases. The ``quantumstopfrom*`` aliases assume that the
+feeder stockpile is orthogonally adjacent to your track stop (which is how
+most people set them up). If your feeder stockpile is somewhere further away,
+you can use the ``quantumstop`` alias directly. In addition to the
+``quantumstopfrom*`` sub-aliases, you can also define the ``move`` and
+``move_back`` sub-aliases, which let you specify the cursor keys required to
+move from the track stop to the feeder stockpile and back again, respectively::
+
+ #query
+ {quantumstop move="{Right 2}{Up}" move_back="{Down}{Left 2}"}
+
+Farm plots
+~~~~~~~~~~
+
+Sets a farm plot to grow the first or last type of seed in the list of
+available seeds for all four seasons. The last seed is usually Plump helmet
+spawn, suitable for post-embark. But if you only have one seed type, that'll
+be grown instead.
+
++------------------+
+| Alias |
++==================+
+| growlastcropall |
++------------------+
+| growfirstcropall |
++------------------+
+
+Instead of these aliases, though, it might be more useful to use the DFHack
+`autofarm` plugin.
+
+Stockpile configuration utility aliases
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+=============== ===========
+Alias Sub-aliases
+=============== ===========
+linksonly
+nocontainers
+give2up
+give2down
+give2left
+give2right
+give10up
+give10down
+give10left
+give10right
+give move
+togglesequence
+togglesequence2
+=============== ===========
+
+``linksonly`` and ``nocontainers`` set the named basic properties on
+stockpiles. ``nocontainers`` sets bins and barrels to 0, but does not affect
+wheelbarrows since the hotkeys for changing the number of wheelbarrows depend
+on whether you have the DFHack `stockpiles` plugin active. It is better to set
+the number of wheelbarrows via the `quickfort` ``stockpiles_max_wheelbarrows``
+setting. It is set to ``0`` by default.
+
+The ``give*`` aliases set a stockpile to give to a workshop or another
+stockpile located at the indicated number of tiles in the indicated direction
+from the current tile. For example, here we use the ``give2down`` alias to
+connect an ``otherstone`` stockpile with a mason workshop::
+
+ #place
+ s,s,s,s,s
+ s, , , ,s
+ s, , , ,s
+ s, , , ,s
+ s,s,s,s,s
+
+ #build
+ `,`,`,`,`
+ `, , , ,`
+ `, ,wm,,`
+ `, , , ,`
+ `,`,`,`,`
+
+ #query
+ , ,give2down
+ otherstone
+
+and here is a generic stone stockpile that gives to a stockpile that only
+takes flux::
+
+ #place
+ s(10x1)
+ s(10x10)
+
+ #query
+ flux
+ ,
+ give2up
+
+If you want to give to some other tile that is not already covered by the
+``give2*`` or ``give10*`` aliases, you can use the generic ``give`` alias and
+specify the movement keys yourself in the ``move`` sub-alias. Here is how to
+give to a stockpile or workshop one z-level above, 9 tiles to the left, and 14
+tiles down::
+
+ #query
+ {give move="<{Left 9}{Down 14}"}
+
+``togglesequence`` and ``togglesequence2`` send ``{Down}{Enter}`` or
+``{Down 2}{Enter}`` to toggle adjacent (or alternating) items in a list. This
+is useful when toggling a bunch of related item types in the stockpile config.
+For example, the ``dye`` and ``tallow`` aliases in the standard alias library
+need to select specific items from long lists::
+
+ dye: {foodprefix}b{Right}{Down 11}{Right}{Down 28}{togglesequence 4}^
+ tallow: {foodprefix}b{Right}{Down 13}{Right}{Down}{togglesequence2 811}^
+
+.. _quickfort-stockpile-aliases:
+
+Stockpile adjustment aliases
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For each stockpile item category, there are three standard aliases:
+
+* ``*prefix`` aliases enter the stockpile configuration screen and position
+ the cursor at a particular item category in the left-most column, ready for
+ further keys that configure the elements within that category. All other
+ stockpile adjustment aliases are built on these prefixes. You can use them
+ yourself to create stockpile adjustment aliases that aren't already covered
+ by the standard library aliases. Using the library prefix instead of
+ creating your own also allows your stockpile configuration aliases to be
+ used for both stockpiles and hauling routes. For example, here is the
+ library definition for ``booze``::
+
+ booze: {foodprefix}b{Right}{Down 5}p{Down}p^
+
+* ``enable*`` aliases enter the stockpile configuration screen, enable all
+ subtypes of the named category, and exit the stockpile configuration screen
+* ``disable*`` aliases enter the stockpile configuration screen, disable all
+ subtypes of the named category, and exit the stockpile configuration screen
+
+==================== ==================== =====================
+Prefix Enable Disable
+==================== ==================== =====================
+animalsprefix enableanimals disableanimals
+foodprefix enablefood disablefood
+furnitureprefix enablefurniture disablefurniture
+corpsesprefix enablecorpses disablecorpses
+refuseprefix enablerefuse disablerefuse
+stoneprefix enablestone disablestone
+ammoprefix enableammo disableammo
+coinsprefix enablecoins disablecoins
+barsprefix enablebars disablebars
+gemsprefix enablegems disablegems
+finishedgoodsprefix enablefinishedgoods disablefinishedgoods
+leatherprefix enableleather disableleather
+clothprefix enablecloth disablecloth
+woodprefix enablewood disablewood
+weaponsprefix enableweapons disableweapons
+armorprefix enablearmor disablearmor
+sheetprefix enablesheet disablesheet
+==================== ==================== =====================
+
+Then, for each item category, there are aliases that manipulate interesting
+subsets of that category:
+
+* Exclusive aliases forbid everthing within a category and then enable only
+ the named item type (or named class of items)
+* ``forbid*`` aliases forbid the named type and leave the rest of the
+ stockpile untouched.
+* ``permit*`` aliases permit the named type and leave the rest of the
+ stockpile untouched.
+
+Note that for specific item types (items in the third stockpile configuration
+column), you can only toggle the item type on and off. Aliases can't know
+whether sending the ``{Enter}`` key will enable or disable the type. The
+``forbid*`` aliases that affect these item types assume the item type was
+enabled and toggle it off. Likewise, the ``permit*`` aliases assume the item
+type was disabled and toggle it on. If the item type is not in the expected
+enabled/disabled state when the alias is run, the aliases will not behave
+properly.
+
+Animal stockpile adjustments
+````````````````````````````
+
+=========== =========== ============
+Exclusive Forbid Permit
+=========== =========== ============
+cages forbidcages permitcages
+traps forbidtraps permittraps
+=========== =========== ============
+
+Food stockpile adjustments
+``````````````````````````
+
+=============== ==================== ====================
+Exclusive Forbid Permit
+=============== ==================== ====================
+preparedfood forbidpreparedfood permitpreparedfood
+unpreparedfish forbidunpreparedfish permitunpreparedfish
+plants forbidplants permitplants
+booze forbidbooze permitbooze
+seeds forbidseeds permitseeds
+dye forbiddye permitdye
+tallow forbidtallow permittallow
+miscliquid forbidmiscliquid permitmiscliquid
+=============== ==================== ====================
+
+Furniture stockpile adjustments
+```````````````````````````````
+
++-----------+
+| Exclusive |
++===========+
+| pots |
++-----------+
+| bags |
++-----------+
+| buckets |
++-----------+
+| sand |
++-----------+
+
+Notes:
+
+* Because of the limitations of Dwarf Fortress, ``bags`` cannot distinguish
+ between empty and filled bags
+
+Refuse stockpile adjustments
+````````````````````````````
+
+=========== ================== ==================
+Exclusive Forbid Permit
+=========== ================== ==================
+bodyparts forbidbodyparts permitbodyparts
+rawhides forbidrawhides permitrawhides
+tannedhides forbidtannedhides permittannedhides
+skulls forbidskulls permitskulls
+bones forbidbones permitbones
+shells forbidshells permitshells
+teeth forbidteeth permitteeth
+horns forbidhorns permithorns
+hair forbidhair permithair
+craftrefuse forbidcraftrefuse permitcraftrefuse
+=========== ================== ==================
+
+Notes:
+
+* ``bodyparts`` includes remains/corpses and rotten rawhdes.
+* ``craftrefuse`` includes everything a craftsdwarf can use: skulls, bones,
+ shells, teeth, horns, and hair.
+
+Stone stockpile adjustments
+```````````````````````````
+
+============= ==================== ====================
+Exclusive Forbid Permit
+============= ==================== ====================
+metal forbidmetal permitmetal
+iron forbidiron permitiron
+economic forbideconomic permiteconomic
+flux forbidflux permitflux
+plaster forbidplaster permitplaster
+coalproducing forbidcoalproducing permitcoalproducing
+otherstone forbidotherstone permitotherstone
+bauxite forbidbauxite permitbauxite
+clay forbidclay permitclay
+============= ==================== ====================
+
+Ammo stockpile adjustments
+``````````````````````````
+
+=============== ====================
+Exclusive Forbid
+=============== ====================
+bolts
+\ forbidmetalbolts
+\ forbidwoodenbolts
+\ forbidbonebolts
+=============== ====================
+
+Bar stockpile adjustments
+`````````````````````````
+
+=========== ==================
+Exclusive Forbid
+=========== ==================
+bars forbidbars
+metalbars forbidmetalbars
+ironbars forbidironbars
+steelbars forbidsteelbars
+pigironbars forbidpigironbars
+otherbars forbidotherbars
+coal forbidcoal
+potash forbidpotash
+ash forbidash
+pearlash forbidpearlash
+soap forbidsoap
+blocks forbidblocks
+=========== ==================
+
+Gem stockpile adjustments
+`````````````````````````
+
+=========== ================
+Exclusive Forbid
+=========== ================
+roughgems forbidroughgems
+roughglass forbidroughglass
+cutgems forbidcutgems
+cutglass forbidcutglass
+cutstone forbidcutstone
+=========== ================
+
+Finished goods stockpile adjustments
+````````````````````````````````````
+
++-----------+
+| Exclusive |
++===========+
+| jugs |
++-----------+
+
+Cloth stockpile adjustments
+```````````````````````````
+
++------------------+
+| Exclusive |
++==================+
+| thread |
++------------------+
+| adamantinethread |
++------------------+
+| cloth |
++------------------+
+| adamantinecloth |
++------------------+
+
+Weapon stockpile adjustments
+````````````````````````````
+
+================= ======================== ====================
+Exclusive Forbid Permit
+================= ======================== ====================
+\ forbidweapons permitweapons
+\ forbidtrapcomponents permittrapcomponents
+metalweapons forbidmetalweapons permitmetalweapons
+\ forbidstoneweapons permitstoneweapons
+\ forbidotherweapons permitotherweapons
+ironweapons forbidironweapons permitironweapons
+copperweapons forbidcopperweapons permitcopperweapons
+steelweapons forbidsteelweapons permitsteelweapons
+masterworkweapons forbidmasterworkweapons permitmasterworkweapons
+artifactweapons forbidartifactweapons permitartifactweapons
+================= ======================== ====================
+
+Armor stockpile adjustments
+```````````````````````````
+
+=============== ====================== ====================
+Exclusive Forbid Permit
+=============== ====================== ====================
+metalarmor forbidmetalarmor permitmetalarmor
+otherarmor forbidotherarmor permitotherarmor
+ironarmor forbidironarmor permitironarmor
+copperarmor forbidcopperarmor permitcopperarmor
+steelarmor forbidsteelarmor permitsteelarmor
+masterworkarmor forbidmasterworkarmor permitmasterworkarmor
+artifactarmor forbidartifactarmor permitartifactarmor
+=============== ====================== ====================
diff --git a/docs/guides/quickfort-library-guide.rst b/docs/guides/quickfort-library-guide.rst
new file mode 100644
index 000000000..0eb04f73f
--- /dev/null
+++ b/docs/guides/quickfort-library-guide.rst
@@ -0,0 +1,106 @@
+.. _quickfort-library-guide:
+
+Quickfort Library Guide
+=======================
+
+This guide contains a high-level overview of the blueprints available in the
+:source:`quickfort blueprint library `. You can list
+library blueprints by running ``quickfort list --library`` or by hitting
+:kbd:`Alt`:kbd:`l` in the ``quickfort gui`` interactive dialog.
+
+Each file is hyperlinked to its online version so you can see exactly what the
+blueprints do.
+
+Whole fort blueprint sets
+-------------------------
+
+These files contain the plans for entire fortresses. Each file has one or more
+help sections that walk you through how to build the fort, step by step.
+
+- :source:`library/dreamfort.csv `
+- :source:`library/quickfortress.csv `
+
+Dreamfort
+~~~~~~~~~
+
+Dreamfort is a fully functional, self-sustaining fortress with defenses,
+farming, a complete set of workshops, self-managing quantum stockpiles, a grand
+dining hall, hospital, jail, fresh water well system, guildhalls, and bedrooms
+for hundreds of dwarves. It also comes with manager work orders to automate
+basic fort needs, such as food and booze production. It can function by itself
+or as the core of a larger, more ambitious fortress. Read the high-level
+walkthrough by running ``quickfort run library/dreamfort.csv`` and list the
+walkthroughs for the individual levels by running ``quickfort list dreamfort -l
+-m notes`` or by opening the ``quickfort gui`` dialog, enabling the library
+with :kbd:`Alt`:kbd:`l`, and setting the filter to ``dreamfort notes``.
+
+Dreamfort blueprints are also available for easy viewing and copying `online
+`__.
+
+The Quick Fortresses
+~~~~~~~~~~~~~~~~~~~~
+
+The Quick Fortress is an updated version of the example fortress that came with
+`Python Quickfort 2.0 `__ (the program
+DFHack quickfort was inspired by). While it is not a complete fortress by
+itself, it is much simpler than Dreamfort and is good for a first introduction
+to `quickfort` blueprints. Read its walkthrough with ``quickfort run
+library/quickfortress.csv``.
+
+Layout helpers
+--------------
+
+These files simply draw diagonal marker-mode lines starting from the cursor.
+They are especially useful for finding the center of the map when you are
+planning your fortress. Once you are done using them for alignment, use
+``quickfort undo`` at the same cursor position to make them disappear. Since
+these ``#dig`` blueprints can only mark undug wall tiles for mining, they are
+best used underground. They won't do much on the surface, where there aren't
+many walls.
+
+- :source:`library/layout-helpers/mark_up_left.csv `
+- :source:`library/layout-helpers/mark_up_right.csv `
+- :source:`library/layout-helpers/mark_down_right.csv `
+- :source:`library/layout-helpers/mark_down_left.csv `
+
+Bedrooms
+--------
+
+These are popular bedroom layouts from the :wiki:`Bedroom design` page on the
+wiki. Each file has ``#dig``, ``#build``, and ``#query`` blueprints to dig the
+rooms, build the furniture, and configure the beds as bedrooms, respectively.
+
+- :source:`library/bedrooms/48-4-Raynard_Whirlpool_Housing.csv `
+- :source:`library/bedrooms/95-9-Hactar1_3_Branch_Tree.csv `
+- :source:`library/bedrooms/28-3-Modified_Windmill_Villas.csv `
+
+Tombs
+-----
+
+These blueprints have burial plot layouts for fortress that expect a lot of
+casualties.
+
+- :source:`library/tombs/Mini_Saracen.csv `
+- :source:`library/tombs/The_Saracen_Crypts.csv `
+
+Exploratory mining
+------------------
+
+Several mining patterns to choose from when searching for gems or ores. The
+patterns can be repeated up or down z-levels for exploring through the depths.
+
+- :source:`library/exploratory-mining/tunnels.csv `
+- :source:`library/exploratory-mining/vertical-mineshafts.csv `
+- :source:`library/exploratory-mining/connected-mineshafts.csv `
+
+Miscellaneous
+-------------
+
+Extra blueprints that are useful in specific situations.
+
+- :source:`library/embark.csv `
+
+The embark blueprints are useful directly after embark. It contains a ``#build``
+blueprint that builds important starting workshops (mason, carpenter, mechanic,
+and craftsdwarf) and a ``#place`` blueprint that lays down a pattern of useful
+starting stockpiles.
diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst
index 1d9c1a024..0deedc192 100644
--- a/docs/guides/quickfort-user-guide.rst
+++ b/docs/guides/quickfort-user-guide.rst
@@ -1,7 +1,8 @@
.. _quickfort-user-guide:
+.. _quickfort-blueprint-guide:
-Quickfort User Guide
-====================
+Quickfort Blueprint Guide
+=========================
`Quickfort ` is a DFHack script that helps you build fortresses from
"blueprint" .csv and .xlsx files. Many applications exist to edit these files,
@@ -15,12 +16,12 @@ macro. Joel Thornton reimplemented the core logic in Python and extended its
functionality with `Quickfort 2.0 `__. This
DFHack-native implementation, called "DFHack Quickfort" or just "quickfort",
builds upon Quickfort 2.0's formats and features. Any blueprint that worked in
-Python Quickfort 2.0 should work with DFHack Quickfort. DFHack Quickfort is
-written in Lua and interacts with Dwarf Fortress memory structures directly,
-allowing for instantaneous blueprint application, error checking and recovery,
-and many other advanced features.
+Python Quickfort 2.0 should work with DFHack Quickfort. DFHack Quickfort
+interacts with Dwarf Fortress memory structures directly, allowing for
+instantaneous blueprint application, error checking and recovery, and many other
+advanced features.
-This document focuses on DFHack Quickfort's capabilities and teaches players how
+This guide focuses on DFHack Quickfort's capabilities and teaches players how
to understand and create blueprint files. Some of the text was originally
written by Joel Thornton, reused here with his permission.
@@ -55,14 +56,15 @@ Features
- Supports .csv and multi-worksheet .xlsx blueprint files
- Near-instant application, even for very large and complex blueprints
- Blueprints can span multiple z-levels
- - Supports multiple blueprints per .csv file/spreadsheet sheet
- - "meta" blueprints that automate the application of sequences of blueprints
+ - You can package all blueprints and aliases needed for an entire fortress
+ in a single file for easy sharing
+ - "meta" blueprints that simplify the application of sequences of blueprints
- Undo functionality for dig, build, place, and zone blueprints
- Automatic cropping of blueprints so you don't get errors if the blueprint
extends off the map
- Can generate manager orders for everything required by a build blueprint
- - Library of ready-to-use blueprints included
- - Verbose output mode for debugging
+ - Includes a library of ready-to-use blueprints
+ - Verbose output mode for blueprint debugging
- Dig mode
@@ -75,53 +77,55 @@ Features
- Build mode
- - DFHack buildingplan integration, so you can place buildings before
- manufacturing all required source materials
- - Designate complete constructions at once, without having to wait for each
- tile to become supported before you can build it
+ - Fully integrated with DFHack buildingplan: you can place buildings before
+ manufacturing building materials and you can use the buildingplan UI for
+ setting materials preferences
+ - Designate entire constructions in mid-air without having to wait for each
+ tile to become supported
- Automatic expansion of building footprints to their minimum dimensions, so
only the center tile of a multi-tile building needs to be recorded in the
blueprint
- Tile occupancy and validity checking so, for example, buildings that
- cannot be placed on a certain tile will simply be skipped instead of the
- blueprint failing to apply. Blueprints that are only partially applied for
- any reason (for example, you need to dig out some more tiles) can be
- safely reapplied to build the remaining buildings.
+ cannot be placed on a target tile will be skipped instead of messing up
+ the blueprint. Blueprints that are only partially applied for any reason
+ (e.g. you need to dig out some more tiles) can be safely reapplied to
+ build the remaining buildings.
- Relaxed rules for farm plot and road placement: you can still place the
building even if an invalid tile (e.g. stone tiles for farm plots) splits
- the designated area into two parts
+ the designated area into two disconnected parts
- Intelligent boundary detection for adjacent buildings of the same type
(e.g. a 6x6 block of ``wj`` cells will be correctly split into 4 jeweler's
workshops)
- Place and zone modes
- - Define stockpiles and zones in any continguous shape, not just rectangular
- blocks
- - Configurable maximums for bins, barrels and wheelbarrows assigned to
- created stockpiles
+ - Define stockpiles and zones of shape, not just rectangles
+ - Configurable numbers of bins, barrels and wheelbarrows assigned to created
+ stockpiles
- Automatic splitting of stockpiles and zones that exceed maximum dimension
limits
- - Full access to all zone settings, such as hospital supply counts
+ - Fully configurable zone settings, such as pit/pond and hospital supply
+ counts
- Query mode
- Send arbitrary keystroke sequences to the UI -- *anything* you can do
through the UI is supported
- - Supports aliases to automate frequent keystroke combos
- - Includes a library of pre-made and tested aliases to automate most common
+ - Supports aliases to simplify frequent keystroke combos
+ - Includes a library of pre-made and tested aliases to simplify most common
tasks, such as configuring stockpiles for important item types or creating
named hauling routes for quantum stockpiles.
- - Supports including aliases in other aliases, and repeating key sequences a
- specified number of times
- - Skips sending key sequences when the cursor is over a tile that does not
- have a stockpile or building, so missing buildings won't desynchronize
- your blueprint
+ - Supports including aliases in other aliases for easy management of common
+ subsequences
+ - Supports repeating key sequences a specified number of times
+ - Skips sending keys when the cursor is over a tile that does not have a
+ stockpile or building, so missing buildings won't desynchronize your
+ blueprint
- Instant halting of query blueprint application when keystroke errors are
- detected, such as when a key sequence leaves us stuck in a submenu, to
- make blueprint misconfigurations easier to debug
+ detected, such as when a mistake in a key sequence leaves us stuck in a
+ submenu, to make query blueprints easier to debug
-Editing Blueprints
+Editing blueprints
------------------
We recommend using a spreadsheet editor such as Excel, `Google
@@ -129,38 +133,41 @@ Sheets `__, or `LibreOffice `__
to edit blueprint files, but any text editor will do.
The format of Quickfort-compatible blueprint files is straightforward. The first
-line (or upper-left cell) of the spreadsheet should look like this:
-
-::
+line (or upper-left cell) of the spreadsheet should look like this::
- #dig This is a decription.
+ #dig
-The keyword "dig" tells Quickfort we are going to be using the Designations menu
-in DF. The following "mode" keywords are understood:
+The keyword ``dig`` tells Quickfort we are going to be using the Designations
+menu in DF. The following "mode" keywords are understood:
-::
+============== ===========
+Blueprint mode Description
+============== ===========
+dig Designations menu (:kbd:`d`)
+build Build menu (:kbd:`b`)
+place Place stockpiles menu (:kbd:`p`)
+zone Activity zones menu (:kbd:`i`)
+query Set building tasks/prefs menu (:kbd:`q`)
+============== ===========
- dig Designations menu (d)
- build Build menu (b)
- place Place stockpiles menu (p)
- zone Activity zones menu (i)
- query Set building tasks/prefs menu (q)
+If no modeline appears in the first cell, Quickfort assumes that it's looking at
+a ``#dig`` blueprint.
-If no modeline appears in the first cell, the file or sheet is interpreted as a
-``#dig`` blueprint.
+There are also other modes that don't directly correspond to Dwarf Fortress
+menus, but we'll talk about those `later `.
-There are also "meta" and "notes" blueprints, but we'll talk about
-`those ` `later `.
+If you like, you may enter a comment after the mode keyword. This comment will
+appear in the output of ``quickfort list`` when run from the ``DFHack#`` prompt.
+You can use this space for explanations, attribution, etc.
-Optionally following this keyword and a space, you may enter a comment. This
-comment will appear in the output of ``quickfort list`` when run from the
-``DFHack#`` prompt. You can use this space for explanations, attribution, etc.
+::
-Below this line begin entering the keys you want sent in each cell. For example,
-we could dig out a 4x4 room like so (spaces are used as column separators here
-for clarity, but a real .csv file would have commas):
+ #dig grand dining room
-::
+Below this line begin entering keys in each spreadsheet cell that represent what
+you want designated in the corresponding game map tile. For example, we could
+dig out a 4x4 room like so (spaces are used as column separators here for
+readability, but a real .csv file would have commas)::
#dig
d d d d #
@@ -169,14 +176,12 @@ for clarity, but a real .csv file would have commas):
d d d d #
# # # # #
-Note the # symbols at the right end of each row and below the last row. These
-are completely optional, but can be helpful to make the row and column positions
-clear.
+Note the :kbd:`#` symbols at the right end of each row and below the last row.
+These are completely optional, but can be helpful to make the row and column
+positions clear.
Once the dwarves have that dug out, let's build a walled-in bedroom within our
-dug-out area:
-
-::
+dug-out area::
#build
Cw Cw Cw Cw #
@@ -185,10 +190,10 @@ dug-out area:
Cw Cw Cw #
# # # # #
-Note my generosity - in addition to the bed (b) I've built a chest (h) here for
-the dwarf as well. You must use the full series of keys needed to build
-something in each cell, e.g. 'Cw' enters DF's constructions submenu (C) and
-selects walls (w).
+Note my generosity - in addition to the bed (:kbd:`b`) I've built a chest
+(:kbd:`c`) here for the dwarf as well. You must use the full series of keys
+needed to build something in each cell, e.g. :kbd:`C`:kbd:`w` indicates we
+should enter DF's constructions submenu (:kbd:`C`) and select walls (:kbd:`w`).
I'd also like to place a booze stockpile in the 2 unoccupied tiles in the room.
@@ -196,34 +201,21 @@ I'd also like to place a booze stockpile in the 2 unoccupied tiles in the room.
#place Place a food stockpile
` ` ` ` #
- ` ` ` ` #
- ` f(2x1)#
- ` ` ` ` #
- # # # # #
-
-This illustration may be a little hard to understand. The f(2x1) is in column 2,
-row 3. All the other cells are empty. QF considers both "`" (backtick -- the
-character under the tilde) and "~" (tilde) characters within cells to be empty
-cells; this can help with multilayer or fortress-wide blueprint layouts as
-'chalk lines'.
-
-With f(2x1), we've asked QF to place a food stockpile 2 units wide by 1 high
-unit. Note that the f(2x1) syntax isn't actually necessary here; we could have
-just used:
-
-::
-
- #place Place a food stockpile
- ` ` ` ` #
- ` ` ` ` #
+ ` ~ ~ ` #
` f f ` #
- ` ` ` ` #
+ ` ` ` #
# # # # #
+This illustration may be a little hard to understand. The two :kbd:`f`
+characters are in row 3, columns 2 and 3. All the other cells are empty. QF
+considers both :kbd:`\`` (backtick -- the character under the tilde) and
+:kbd:`~` (tilde) characters within cells to be empty cells; this can help with
+multilayer or fortress-wide blueprint layouts as "chalk lines".
+
QF is smart enough to recognize this as a 2x1 food stockpile, and creates it as
-such rather than as two 1x1 food stockpiles. Quickfort recognizes any connected
-region of identical designations as a single stockpile. The tiles can be
-connected orthogonally or diagonally, just as long as they are touching somehow.
+such rather than as two 1x1 food stockpiles. Quickfort treats any connected
+region of identical designations as a single entity. The tiles can be connected
+orthogonally or diagonally, just as long as they are touching.
Lastly, let's turn the bed into a bedroom and set the food stockpile to hold
only booze.
@@ -237,29 +229,35 @@ only booze.
` ` ` ` #
# # # # #
-In column 2, row 2 we have "r&". This sends the "r" key to DF when the cursor is
-over the bed, causing us to 'make room' and "&", which is a special symbol that
-expands to "{Enter}", to indicate that we're done.
-
-In column 2, row 3 we have "booze". This is one of many alias keywords defined
-in the included :source:`baseline aliases file `.
-This particular alias sets a food stockpile to carry booze only. It sends the
-keys needed to navigate DF's stockpile settings menu, and then sends an Escape
-character ("^" or "{ESC}") to exit back to the map. It is important to exit out
-of any menus that you enter while in query mode so that the cursor can move to
-the next tile when it is done configuring the current tile.
-
-Check out the included :source:`blueprint library `
-to see many more examples. Read the baseline aliases file for helpful
-pre-packaged aliases, or create your own in
-:source:`dfhack-config/quickfort/aliases.txt` in your DFHack installation.
+In row 2, column 2 we have ``r&``. This sends the :kbd:`r` key to DF when the
+cursor is over the bed, causing us to "make room" and :kbd:`Enter`, represented
+by special ``&`` alias, to indicate that we're done setting the size (the
+default room size is fine here).
+
+In column 2, row 3 we have ``booze``. This is one of many alias keywords defined
+in the included :source:`aliases library `.
+This particular alias sets a food stockpile to accept only booze. It sends the
+keys needed to navigate DF's stockpile settings menu, and then it sends an
+Escape character to exit back to the map. It is important to exit out of any
+menus that you enter while in query mode so that the cursor can move to the next
+tile when it is done with the current tile.
+
+If there weren't an alias named ``booze`` then the literal characters
+:kbd:`b`:kbd:`o`:kbd:`o`:kbd:`z`:kbd:`e` would have been sent, so be sure to
+spell those aliases correctly!
+
+You can save a lot of time and effort by using aliases instead of adding all
+key seqences directly to your blueprints. For more details, check out the
+`Quickfort Alias Guide `. You can also see examples of
+aliases being used in the query blueprints in the
+:source:`DFHack blueprint library `. You can create
+your own aliases by adding them to :source:`dfhack-config/quickfort/aliases.txt`
+in your DFHack folder.
Area expansion syntax
~~~~~~~~~~~~~~~~~~~~~
-In Quickfort, the following blueprints are equivalent:
-
-::
+In Quickfort, the following blueprints are equivalent::
#dig a 3x3 area
d d d #
@@ -274,21 +272,13 @@ In Quickfort, the following blueprints are equivalent:
# # # #
The second example uses Quickfort's "area expansion syntax", which takes the
-form:
-
-::
+form::
keys(WxH)
-In Quickfort the above two examples of specifying a contiguous 3x3 area produce
-identical output: a single 3x3 designation will be performed, rather than nine
-1x1 designations as the first example might suggest.
-
-Area expansion syntax can only specify rectangular areas. If you want to create
-extent-based structures (e.g. farm plots or stockpiles) in different shapes, use
-the first format above. For example:
-
-::
+Note that area expansion syntax can only specify rectangular areas. If you want
+to create extent-based structures (e.g. farm plots or stockpiles) in different
+shapes, use the first format above. For example::
#place L shaped food stockpile
f f ` ` #
@@ -298,9 +288,7 @@ the first format above. For example:
# # # # #
Area expansion syntax also sets boundaries, which can be useful if you want
-adjacent, but separate, stockpiles of the same type:
-
-::
+adjacent, but separate, stockpiles of the same type::
#place Two touching but separate food stockpiles
f(4x2) #
@@ -309,11 +297,9 @@ adjacent, but separate, stockpiles of the same type:
~ ~ ~ ~ #
# # # # #
-As mentioned previously, "~" characters are ignored as comment characters and
-can be used for visualizing the blueprint layout. The blueprint can be
-equivalently written as:
-
-::
+As mentioned previously, :kbd:`~` characters are ignored as comment characters
+and can be used for visualizing the blueprint layout. This blueprint can be
+equivalently written as::
#place Two touching but separate food stockpiles
f(4x2) #
@@ -326,9 +312,7 @@ since the area expansion syntax of the upper stockpile prevents it from
combining with the lower, freeform syntax stockpile.
Area expansion syntax can also be used for buildings which have an adjustable
-size, like bridges. The following blueprints are equivalent:
-
-::
+size, like bridges. The following blueprints are equivalent::
#build a 4x2 bridge from row 1, col 1
ga(4x2) ` #
@@ -345,19 +329,15 @@ Automatic area expansion
Buildings larger than 1x1, like workshops, can be represented in any of three
ways. You can designate just their center tile with empty cells around it to
-leave room for the footprint, like this:
-
-::
+leave room for the footprint, like this::
#build a mason workshop in row 2, col 2 that will occupy the 3x3 area
- ` ` ` #
- ` wm ` #
- ` ` ` #
- # # # #
+ ` ` ` #
+ ` wm ` #
+ ` ` ` #
+ # # # #
-Or you can fill out the entire footprint like this:
-
-::
+Or you can fill out the entire footprint like this::
#build a mason workshop
wm wm wm #
@@ -369,9 +349,7 @@ This format may be verbose for regular workshops, but it can be very helpful for
laying out structures like screw pump towers and waterwheels, whose "center
point" can be non-obvious.
-Finally, you can use area expansion syntax to represent the workshop:
-
-::
+Finally, you can use area expansion syntax to represent the workshop::
#build a mason workshop
wm(3x3) #
@@ -381,12 +359,10 @@ Finally, you can use area expansion syntax to represent the workshop:
This style can be convenient for laying out multiple buildings of the same type.
If you are building a large-scale block factory, for example, this will create
-20 mason workshops all in a row:
-
-::
+20 mason workshops all in a row::
#build line of 20 mason workshops
- wm(60x3) #
+ wm(60x3)
Quickfort will intelligently break large areas of the same designation into
appropriately-sized chunks.
@@ -421,9 +397,7 @@ Dig priorities
DF designation priorities are supported for ``#dig`` blueprints. The full syntax
is ``[letter][number][expansion]``, where if the ``letter`` is not specified,
``d`` is assumed, and if ``number`` is not specified, ``4`` is assumed (the
-default priority). So each of these blueprints is equivalent:
-
-::
+default priority). So each of these blueprints is equivalent::
#dig dig the interior of the room at high priority
d d d d d #
@@ -453,12 +427,10 @@ Marker mode
~~~~~~~~~~~
Marker mode is useful for when you want to plan out your digging, but you don't
-want to dig everything just yet. In ``#dig`` mode, you can add a ``m`` before
+want to dig everything just yet. In ``#dig`` mode, you can add a :kbd:`m` before
any other designation letter to indicate that the tile should be designated in
marker mode. For example, to dig out the perimeter of a room, but leave the
-center of the room marked for digging later:
-
-::
+center of the room marked for digging later::
#dig
d d d d d #
@@ -468,15 +440,15 @@ center of the room marked for digging later:
d d d d d #
# # # # # #
-Then you can use "Toggle Standard/Marking" (``d-M``) to convert the center tiles
-to regular designations at your leisure.
+Then you can use "Toggle Standard/Marking" (:kbd:`d`:kbd:`M`) to convert the
+center tiles to regular designations at your leisure.
To apply an entire dig blueprint in marker mode, regardless of what the
blueprint itself says, you can set the global quickfort setting
``force_marker_mode`` to ``true`` before you apply the blueprint.
-Note that the in-game UI setting "Standard/Marker Only" (``d-m``) does not have
-any effect on quickfort.
+Note that the in-game UI setting "Standard/Marker Only" (:kbd:`d`:kbd:`m`) does
+not have any effect on quickfort.
Stockpiles and zones
~~~~~~~~~~~~~~~~~~~~
@@ -484,20 +456,15 @@ Stockpiles and zones
It is very common to have stockpiles that accept multiple categories of items or
zones that permit more than one activity. Although it is perfectly valid to
declare a single-purpose stockpile or zone and then modify it with a ``#query``
-blueprint, quickfort also supports directly declaring all the types on the
+blueprint, quickfort also supports directly declaring all the types in the
``#place`` and ``#zone`` blueprints. For example, to declare a 20x10 stockpile
-that accepts both corpses and refuse, you could write:
-
-::
+that accepts both corpses and refuse, you could write::
#place refuse heap
yr(20x10)
-
And similarly, to declare a zone that is a pasture, a fruit picking area, and a
-meeting area all at once:
-
-::
+meeting area all at once::
#zone main pasture and picnic area
nmg(10x10)
@@ -505,24 +472,21 @@ meeting area all at once:
The order of the individual letters doesn't matter. If you want to configure the
stockpile from scratch in a ``#query`` blueprint, you can place unconfigured
"custom" stockpiles with (:kbd:`c`). It is more efficient, though, to place
-stockpiles using the keys that represent the types you want to store, and
-then only use a ``#query`` blueprint if you need fine-grained customization.
+stockpiles using the keys that represent the categories of items that you want
+to store, and then only use a ``#query`` blueprint if you need fine-grained
+customization.
Detailed configuration for zones, such as the pit/pond toggle, can also be set
by mimicking the hotkeys used to set them. Note that gather flags default to
true, so specifying them in a blueprint will turn the toggles off. If you need
to set configuration from multiple zone subscreens, separate the key sections
-with ``^``. Note the special syntax for setting hospital supply levels, which
-have no in-game hotkeys:
-
-::
+with :kbd:`^`. Note the special syntax for setting hospital supply levels, which
+have no in-game hotkeys::
#zone a combination hospital and shrub (but not fruit) gathering zone
gGtf^hH{hospital buckets=5 splints=20}(10x10)
-The valid hospital settings (and their maximum values) are:
-
-::
+The valid hospital settings (and their maximum values) are::
thread (1500000)
cloth (1000000)
@@ -532,11 +496,9 @@ The valid hospital settings (and their maximum values) are:
buckets (100)
soap (15000)
-To toggle the ``active`` flag for zones, add an ``a`` character to the string.
-For example, to create a *disabled* pond zone (that you later intend to
-carefully fill with 3-depth water for a dwarven bathtub):
-
-::
+To toggle the ``active`` flag for zones, add an :kbd:`a` character to the
+string. For example, to create a *disabled* pond zone (that you later intend to
+carefully fill with 3-depth water for a dwarven bathtub)::
#zone disabled pond zone
apPf(1x3)
@@ -552,19 +514,16 @@ simpler, so we'll start with them.
Constructed tracks
``````````````````
-Quickfort supports the designation of track stops and rollers through the normal
-mechanisms: a ``#build`` blueprint with ``CS`` and some number of ``d`` and
-``a`` characters (for selecting dump direction and friction) in a cell
-designates a track stop and a ``#build`` blueprint with ``Mr`` and some number
-of ``s`` and ``q`` characters (for direction and speed) designates a roller.
-This can get confusing very quickly and is very difficult to read in a
-blueprint. Constructed track segments don't even have keys associated with them
-at all!
+Quickfort supports the designation of track stops and rollers in ``#build``
+blueprints. You can build a track stop with :kbd:`C`:kbd:`S` and some number of
+:kbd:`d` and :kbd:`a` characters for selecting dump direction and friction. You
+can build a roller with :kbd:`M`:kbd:`r` and some number of :kbd:`s` and
+:kbd:`q` characters for direction and speed. However, this can get confusing
+very quickly and is very difficult to read in a blueprint. Moreover, constructed
+track segments don't even have keys associated with them at all!
To solve this problem, Quickfort provides the following keywords for use in
-build blueprints:
-
-::
+build blueprints::
-- Track segments --
trackN
@@ -624,89 +583,76 @@ build blueprints:
specified with 'trackstopaaaa'.
As an example, you can create an E-W track with stops at each end that dump to
-their outside directions with the following blueprint:
-
-::
+their outside directions with the following blueprint::
#build Example track
trackstopW trackEW trackEW trackEW trackstopE
Note that the **only** way to build track and track/ramp segments is with the
-keywords. The UI method of using "+" and "-" keys to select the track type from
-a list does not work since DFHack Quickfort doesn't actually send keys to the UI
-to build buildings. The text in your spreadsheet cells is mapped directly into
-DFHack API calls. Only ``#query`` blueprints still send actual keycodes to the
-UI.
+keywords. The UI method of using :kbd:`+` and :kbd:`-` keys to select the track
+type from a list does not work since DFHack Quickfort doesn't actually send keys
+to the UI to build buildings. The text in your spreadsheet cells is mapped
+directly onto DFHack API calls. Only ``#query`` blueprints send actual keycodes
+to the UI.
Carved tracks
`````````````
In the game, you carve a minecart track by specifying a beginning and ending
-tile and the game "adds" the designation to the tiles. You cannot designate
-single tiles. For example to carve two track segments that cross each other, you
-might use the cursor to designate a line of three vertical tiles like this:
+tile and the game "adds" the designation to the tiles in between. You cannot
+designate single tiles. For example to carve two track segments that cross each
+other, you might use the cursor to designate a line of three vertical tiles
+like this::
-::
-
- ` start here ` #
- ` ` ` #
- ` end here ` #
- # # # #
+ ` start here ` #
+ ` ` ` #
+ ` end here ` #
+ # # # #
-Then to carve the cross, you'd do a horizonal segment:
-
-::
+Then to carve the cross, you'd do a horizonal segment::
- ` ` ` #
- start here ` end here #
- ` ` ` #
- # # # #
+ ` ` ` #
+ start here ` end here #
+ ` ` ` #
+ # # # #
This will result in a carved track that would be equivalent to a constructed
-track of the form:
-
-::
+track of the form::
#build
- ` trackS ` #
- trackE trackNSEW trackW #
- ` trackN ` #
- # # # #
+ ` trackS ` #
+ trackE trackNSEW trackW #
+ ` trackN ` #
+ # # # #
To carve this same track with a ``#dig`` blueprint, you'd use area expansion
-syntax with a height or width of 1 to indicate the segments to designate:
-
-::
+syntax with a height or width of 1 to indicate the segments to designate::
#dig
- ` T(1x3) ` #
- T(3x1) ` ` #
- ` ` ` #
- # # # #
+ ` T(1x3) ` #
+ T(3x1) ` ` #
+ ` ` ` #
+ # # # #
"But wait!", I can hear you say, "How do you designate a track corner that opens
to the South and East? You can't put both T(1xH) and T(Wx1) in the same cell!"
This is true, but you can specify both width and height, and for tracks, QF
interprets it as an upper-left corner extending to the right W tiles and down H
-tiles. For example, to carve a track in a closed ring, you'd write:
-
-::
+tiles. For example, to carve a track in a closed ring, you'd write::
#dig
- T(3x3) ` T(1x3) #
- ` ` ` #
- T(3x1) ` ` #
- # # # #
-
-Which would result in a carved track simliar to a constructed track of the form:
+ T(3x3) ` T(1x3) #
+ ` ` ` #
+ T(3x1) ` ` #
+ # # # #
-::
+Which would result in a carved track simliar to a constructed track of the form::
#build
- trackSE trackEW trackSW #
- trackNS ` trackNS #
- trackNE trackEW trackNW #
- # # # #
+ trackSE trackEW trackSW #
+ trackNS ` trackNS #
+ trackNE trackEW trackNW #
+ # # # #
.. _quickfort-modeline:
@@ -722,9 +668,7 @@ about yet. You can:
- register a message to be displayed after the blueprint is successfully
applied
-The full modeline syntax, when everything is specified, is:
-
-::
+The full modeline syntax, when all optional elements are specified, is::
#mode label(mylabel) start(X;Y;STARTCOMMENT) hidden() message(mymessage) comment
@@ -732,9 +676,7 @@ Note that all elements are optional except for the initial ``#mode`` (though, as
mentioned in the first section, if a modeline doesn't appear at all in the first
cell of a spreadsheet, the blueprint is interpreted as a ``#dig`` blueprint with
no optional markers). Here are a few examples of modelines with optional
-elements before we discuss them in more detail:
-
-::
+elements before we discuss them in more detail::
#dig start(3; 3; Center tile of a 5-tile square) Regular blueprint comment
#build label(noblebedroom) start(10;15)
@@ -764,9 +706,7 @@ Start positions
Start positions specify a cursor offset for a particular blueprint, simplifying
the task of blueprint alignment. This is very helpful for blueprints that are
based on a central staircase, but it helps whenever a blueprint has an obvious
-"center". For example:
-
-::
+"center". For example::
#build start(2;2;center of workshop) label(masonw) a mason workshop
wm wm wm #
@@ -778,16 +718,14 @@ will build the workshop *centered* on the cursor, not down and to the right of
the cursor.
The two numbers specify the column and row (or X and Y offset) where the cursor
-is expected to be when you apply the blueprint. Position 1;1 is the top left
+is expected to be when you apply the blueprint. Position ``1;1`` is the top left
cell. The optional comment will show up in the ``quickfort list`` output and
should contain information about where to position the cursor. If the start
-position is 1;1, you can omit the numbers and just add a comment describing
+position is ``1;1``, you can omit the numbers and just add a comment describing
where to put the cursor. This is also useful for meta blueprints that don't
actually care where the cursor is, but that refer to other blueprints that have
fully-specified ``start()`` markers. For example, a meta blueprint that refers
-to the ``masonw`` blueprint above could look like this:
-
-::
+to the ``masonw`` blueprint above could look like this::
#meta start(center of workshop) a mason workshop
/masonw
@@ -810,15 +748,17 @@ Messages
A blueprint with a ``message()`` marker will display a message after the
blueprint is applied with ``quickfort run``. This is useful for reminding
-players to take manual steps that cannot be automated, like assigning animals to
-a pasture or assigning minecarts to a route, or listing the next step in a
-series of blueprints. For long or multi-part messages, you can embed newlines:
-
-::
+players to take manual steps that cannot be automated, like assigning minecarts
+to a route, or listing the next step in a series of blueprints. For long or
+multi-part messages, you can embed newlines::
"#meta label(surface1) message(This would be a good time to start digging the industry level.
Once the area is clear, continue with /surface2.) clear the embark site and set up pastures"
+The quotes surrounding the cell text are only necessary if you are writing a
+.csv file by hand. Spreadsheet applications will surround multi-line text with
+quotes automatically when they save/export the file.
+
.. _quickfort-packaging:
Packaging a set of blueprints
@@ -826,7 +766,7 @@ Packaging a set of blueprints
A complete specification for a section of your fortress may contain 5 or more
separate blueprints, one for each "phase" of construction (dig, build, place
-stockpiles, designate zones, query building adjustments).
+stockpiles, designate zones, and query adjustments).
To manage all the separate blueprints, it is often convenient to keep related
blueprints in a single file. For .xlsx spreadsheets, you can keep each blueprint
@@ -838,11 +778,11 @@ sizes and coloring.
For both .csv files and .xlsx spreadsheets you can also add as many blueprints
as you want in a single file or sheet. Just add a modeline in the first column
to indicate the start of a new blueprint. Instead of multiple .csv files, you
-can concatenate them into one single file.
-
-For example, you can store multiple blueprints together like this:
+can concatenate them into one single file. This is especially useful when you
+are sharing your blueprints with others. A single file is much easier to manage
+than a directory of files.
-::
+For example, you can store multiple blueprints together like this::
#dig label(bed1)
d d d d #
@@ -876,9 +816,7 @@ For example, you can store multiple blueprints together like this:
# # # # #
Of course, you could still choose to keep your blueprints in single-sheet .csv
-files and just give related blueprints similar names:
-
-::
+files and just give related blueprints similar names::
bedroom.1.dig.csv
bedroom.2.build.csv
@@ -886,15 +824,33 @@ files and just give related blueprints similar names:
bedroom.4.query.csv
bedroom.5.query2.csv
-But the naming and organization is completely up to you.
+The naming and organization is completely up to you.
+
+.. _quickfort-other-modes:
+
+Other blueprint modes
+~~~~~~~~~~~~~~~~~~~~~
+
+There are a few additional blueprint modes that become useful when you are
+sharing your blueprints with others or managing complex blueprint sets. Instead
+of mapping tile positions to keystroke sequences like the basic modes do, these
+"blueprints" have specialized, higher-level uses:
+
+============== ===========
+Blueprint mode Description
+============== ===========
+meta Link sequences of blueprints together
+notes Display long messages, such as help text or blueprint
+ walkthroughs
+============== ===========
.. _quickfort-meta:
Meta blueprints
-~~~~~~~~~~~~~~~
+```````````````
-Meta blueprints are blueprints that script a series of other blueprints. Many
-blueprint packages follow this pattern:
+Meta blueprints are blueprints that script a series of other blueprints. For
+example, many blueprint sets follow this pattern:
1. Apply dig blueprint to designate dig areas
#. Wait for miners to dig
@@ -905,16 +861,15 @@ blueprint packages follow this pattern:
#. Apply a different query blueprint to configure rooms
Those three "apply"s in the middle might as well get done in one command instead
-of three. A meta blueprint can encode that sequence. A meta blueprint refers to
-other blueprints by their label (see the `Modeline markers`_ section above) in
-the same format used by the `quickfort` command: ``/