Merge branch 'develop' into Bumber64-patch-2

develop
Myk 2022-11-18 17:34:00 -08:00 committed by GitHub
commit 11c27d40dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
439 changed files with 19734 additions and 15820 deletions

@ -17,8 +17,8 @@ jobs:
plugins:
- default
include:
- os: ubuntu-20.04
gcc: 11
- os: ubuntu-22.04
gcc: 12
plugins: all
steps:
- name: Set up Python 3
@ -56,11 +56,12 @@ jobs:
echo "::set-output name=df_version::${DF_VERSION}"
echo "DF_VERSION=${DF_VERSION}" >> $GITHUB_ENV
echo "DF_FOLDER=${HOME}/DF/${DF_VERSION}/df_linux" >> $GITHUB_ENV
echo "CCACHE_DIR=${HOME}/.ccache" >> $GITHUB_ENV
- name: Fetch DF cache
uses: actions/cache@v2
with:
path: ~/DF
key: ${{ steps.env_setup.outputs.df_version }}-${{ hashFiles('ci/download-df.sh') }}
key: dfcache-${{ steps.env_setup.outputs.df_version }}-${{ hashFiles('ci/download-df.sh') }}
- name: Fetch ccache
uses: actions/cache@v2
with:
@ -85,18 +86,21 @@ jobs:
-DBUILD_TESTS:BOOL=ON \
-DBUILD_DEV_PLUGINS:BOOL=${{ matrix.plugins == 'all' }} \
-DBUILD_SIZECHECK:BOOL=${{ matrix.plugins == 'all' }} \
-DBUILD_SKELETON:BOOL=${{ matrix.plugins == 'all' }} \
-DBUILD_STONESENSE:BOOL=${{ matrix.plugins == 'all' }} \
-DBUILD_SUPPORTED:BOOL=1 \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_INSTALL_PREFIX="$DF_FOLDER"
- name: Build DFHack
run: |
ninja -C build-ci install
ccache --show-stats
- name: Run tests
id: run_tests
run: |
export TERM=dumb
status=0
mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init
script -qe -c "python ci/run-tests.py --headless --keep-status \"$DF_FOLDER\"" || status=$((status + 1))
python ci/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" || status=$((status + 2))
mkdir -p artifacts
@ -125,14 +129,14 @@ jobs:
python-version: 3
- name: Install dependencies
run: |
pip install 'sphinx<4.4.0'
pip install 'sphinx'
- name: Clone DFHack
uses: actions/checkout@v1
with:
submodules: true
- name: Build docs
run: |
sphinx-build -W --keep-going -j3 --color . docs/html
sphinx-build -W --keep-going -j auto --color . docs/html
- name: Upload docs
uses: actions/upload-artifact@v1
with:

7
.gitignore vendored

@ -15,9 +15,14 @@ build/VC2010
!build/
# Sphinx generated documentation
docs/_*
docs/changelogs/
docs/html/
docs/pdf/
docs/pseudoxml/
docs/tags/
docs/text/
docs/tools/
docs/xml/
# in-place build
build/Makefile

@ -4,7 +4,7 @@ ci:
repos:
# shared across repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
rev: v4.3.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
@ -20,11 +20,11 @@ repos:
args: ['--fix=lf']
- id: trailing-whitespace
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.16.0
rev: 0.18.4
hooks:
- id: check-github-workflows
- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: v1.2.0
rev: v1.3.1
hooks:
- id: forbid-tabs
exclude_types:
@ -41,4 +41,4 @@ repos:
entry: python3 ci/authors-rst.py
files: docs/Authors\.rst
pass_filenames: false
exclude: '^(depends/|data/examples/.*\.json$|.*\.diff$)'
exclude: '^(depends/|data/.*\.json$|.*\.diff$)'

@ -0,0 +1,22 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
build:
os: ubuntu-20.04
tools:
python: "3"
submodules:
include: all
sphinx:
configuration: conf.py
formats: all
python:
install:
- requirements: .readthedocs.requirements.txt

@ -1,7 +1,7 @@
# main project file. use it from a build sub-folder, see COMPILE for details
## some generic CMake magic
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
cmake_minimum_required(VERSION 3.6 FATAL_ERROR)
cmake_policy(SET CMP0048 NEW)
project(dfhack)
@ -74,6 +74,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if(MSVC)
# increase warning level and treat warnings as errors
add_definitions("/WX")
add_definitions("/W3")
# disable C4819 code-page warning
add_definitions("/wd4819")
@ -192,7 +196,7 @@ endif()
# set up versioning.
set(DF_VERSION "0.47.05")
set(DFHACK_RELEASE "r5")
set(DFHACK_RELEASE "r7")
set(DFHACK_PRERELEASE FALSE)
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")
@ -206,11 +210,9 @@ set(DFHACK_BUILD_ID "" CACHE STRING "Build ID (should be specified on command li
if(UNIX)
# put the lib into DF/hack
set(DFHACK_LIBRARY_DESTINATION hack)
set(DFHACK_EGGY_DESTINATION libs)
else()
# windows is crap, therefore we can't do nice things with it. leave the libs on a nasty pile...
set(DFHACK_LIBRARY_DESTINATION .)
set(DFHACK_EGGY_DESTINATION .)
endif()
# external tools will be installed here:
@ -444,43 +446,67 @@ endif()
add_subdirectory(data)
add_subdirectory(scripts)
find_package(Sphinx QUIET)
if(BUILD_DOCS)
find_package(Python3)
find_package(Sphinx)
if(NOT SPHINX_FOUND)
message(SEND_ERROR "Sphinx not found but BUILD_DOCS enabled")
endif()
file(GLOB SPHINX_DEPS
"${CMAKE_CURRENT_SOURCE_DIR}/docs/*.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/guides/*.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/changelog.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_changelog.py"
file(GLOB SPHINX_GLOB_DEPS
LIST_DIRECTORIES false
"${CMAKE_CURRENT_SOURCE_DIR}/docs/images/*.png"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/styles/*"
"${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/about.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/*/about.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/data/init/*init"
)
file(GLOB_RECURSE SPHINX_GLOB_RECURSE_DEPS
"${CMAKE_CURRENT_SOURCE_DIR}/*.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/changelog.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/*py"
)
list(FILTER SPHINX_GLOB_RECURSE_DEPS
EXCLUDE REGEX "docs/changelogs"
)
file(GLOB_RECURSE SPHINX_SCRIPT_DEPS
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/*.lua"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/*.rb"
list(FILTER SPHINX_GLOB_RECURSE_DEPS
EXCLUDE REGEX "docs/html"
)
set(SPHINX_DEPS ${SPHINX_DEPS} ${SPHINX_SCRIPT_DEPS}
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.rst"
list(FILTER SPHINX_GLOB_RECURSE_DEPS
EXCLUDE REGEX "docs/tags"
)
list(FILTER SPHINX_GLOB_RECURSE_DEPS
EXCLUDE REGEX "docs/text"
)
list(FILTER SPHINX_GLOB_RECURSE_DEPS
EXCLUDE REGEX "docs/tools"
)
set(SPHINX_DEPS ${SPHINX_GLOB_DEPS} ${SPHINX_GLOB_RECURSE_DEPS} ${SPHINX_SCRIPT_DEPS}
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
)
set(SPHINX_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/html/.buildinfo")
set_source_files_properties(${SPHINX_OUTPUT} PROPERTIES GENERATED TRUE)
set_property(
DIRECTORY PROPERTY ADDITIONAL_CLEAN_FILES TRUE
"${CMAKE_CURRENT_SOURCE_DIR}/docs/changelogs"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/html"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/pdf"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/pseudoxml"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/tags"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/text"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/tools"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/xml"
"${CMAKE_BINARY_DIR}/docs/html"
"${CMAKE_BINARY_DIR}/docs/pdf"
"${CMAKE_BINARY_DIR}/docs/pseudoxml"
"${CMAKE_BINARY_DIR}/docs/text"
"${CMAKE_BINARY_DIR}/docs/xml"
)
add_custom_command(OUTPUT ${SPHINX_OUTPUT}
COMMAND ${SPHINX_EXECUTABLE}
-a -E -q -b html
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/html"
-w "${CMAKE_CURRENT_SOURCE_DIR}/docs/_sphinx-warnings.txt"
-j 2
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/docs/build.py"
html text --sphinx="${SPHINX_EXECUTABLE}" -- -q
DEPENDS ${SPHINX_DEPS}
COMMENT "Building HTML documentation with Sphinx"
COMMENT "Building documentation with Sphinx"
)
add_custom_target(dfhack_docs ALL
@ -492,8 +518,12 @@ if(BUILD_DOCS)
COMMAND ${CMAKE_COMMAND} -E touch ${SPHINX_OUTPUT})
install(DIRECTORY ${dfhack_SOURCE_DIR}/docs/html/
DESTINATION ${DFHACK_USERDOC_DESTINATION}/docs
FILES_MATCHING PATTERN "*"
PATTERN html/_sources EXCLUDE)
install(DIRECTORY ${dfhack_SOURCE_DIR}/docs/text/
DESTINATION ${DFHACK_USERDOC_DESTINATION}/docs)
install(FILES docs/_auto/news.rst docs/_auto/news-dev.rst DESTINATION ${DFHACK_USERDOC_DESTINATION})
install(FILES docs/changelogs/news.rst docs/changelogs/news-dev.rst DESTINATION ${DFHACK_USERDOC_DESTINATION})
install(FILES "README.html" DESTINATION "${DFHACK_DATA_DESTINATION}")
endif()

@ -5,9 +5,6 @@ set -e
df_tardest="df.tar.bz2"
save_tardest="test_save.tgz"
selfmd5=$(openssl md5 < "$0")
echo $selfmd5
cd "$(dirname "$0")"
echo "DF_VERSION: $DF_VERSION"
echo "DF_FOLDER: $DF_FOLDER"
@ -15,17 +12,7 @@ mkdir -p "$DF_FOLDER"
# back out of df_linux
cd "$DF_FOLDER/.."
if [ -f receipt ]; then
if [ "$selfmd5" != "$(cat receipt)" ]; then
echo "download-df.sh changed; re-downloading tarballs"
rm receipt
else
echo "Already downloaded $DF_VERSION tarballs"
fi
fi
if [ ! -f receipt ]; then
rm -f "$df_tardest" "$save_tardest"
if ! test -f "$df_tardest"; then
minor=$(echo "$DF_VERSION" | cut -d. -f2)
patch=$(echo "$DF_VERSION" | cut -d. -f3)
echo "Downloading DF $DF_VERSION"
@ -43,6 +30,7 @@ URLS
echo "DF failed to download: $df_tardest not found"
exit 1
fi
echo "Downloading test save"
#test_save_url="https://files.dfhack.org/DF/0.${minor}.${patch}/test_save.tgz"
test_save_url="https://drive.google.com/uc?export=download&id=1XvYngl-DFONiZ9SD9OC4B2Ooecu8rPFz"
@ -61,5 +49,4 @@ tar xf "$df_tardest" --strip-components=1 -C df_linux
tar xf "$save_tardest" -C df_linux/data/save
echo Done
echo "$selfmd5" > receipt
ls
ls -l

@ -97,7 +97,7 @@ class TrailingWhitespaceLinter(Linter):
msg = 'Contains trailing whitespace'
def check_line(self, line):
line = line.replace('\r', '').replace('\n', '')
return not line.strip() or line == line.rstrip('\t ')
return line == line.rstrip('\t ')
def fix_line(self, line):
return line.rstrip('\t ')

@ -68,7 +68,16 @@ init_contents = change_setting(init_contents, 'FPS', 'YES')
if args.headless:
init_contents = change_setting(init_contents, 'PRINT_MODE', 'TEXT')
test_init_file = 'dfhackzzz_test.init' # Core sorts these alphabetically
init_path = 'dfhack-config/init'
if not os.path.isdir('hack/init'):
# we're on an old branch that still reads init files from the root dir
init_path = '.'
try:
os.mkdir(init_path)
except OSError as error:
# ignore already exists errors
pass
test_init_file = os.path.join(init_path, 'dfhackzzz_test.init') # Core sorts these alphabetically
with open(test_init_file, 'w') as f:
f.write('''
devel/dump-rpc dfhack-rpc.txt

@ -1,12 +1,13 @@
#!/usr/bin/env python3
import os
from os.path import basename, dirname, join, splitext
from os.path import basename, dirname, exists, join, splitext
import sys
SCRIPT_PATH = sys.argv[1] if len(sys.argv) > 1 else 'scripts'
DOCS_PATH = join(SCRIPT_PATH, 'docs')
IS_GITHUB_ACTIONS = bool(os.environ.get('GITHUB_ACTIONS'))
def expected_cmd(path):
def get_cmd(path):
"""Get the command from the name of a script."""
dname, fname = basename(dirname(path)), splitext(basename(path))[0]
if dname in ('devel', 'fix', 'gui', 'modtools'):
@ -14,16 +15,6 @@ def expected_cmd(path):
return fname
def check_ls(fname, line):
"""Check length & existence of leading comment for "ls" builtin command."""
line = line.strip()
comment = '--' if fname.endswith('.lua') else '#'
if '[====[' in line or not line.startswith(comment):
print_error('missing leading comment (requred for `ls`)', fname)
return 1
return 0
def print_error(message, filename, line=None):
if not isinstance(line, int):
line = 1
@ -32,48 +23,42 @@ def print_error(message, filename, line=None):
print('::error file=%s,line=%i::%s' % (filename, line, message))
def check_ls(docfile, lines):
"""Check length & existence of first sentence for "ls" builtin command."""
# TODO
return 0
def check_file(fname):
errors, doclines = 0, []
tok1, tok2 = ('=begin', '=end') if fname.endswith('.rb') else \
('[====[', ']====]')
doc_start_line = None
with open(fname, errors='ignore') as f:
errors, doc_start_line = 0, None
docfile = join(DOCS_PATH, get_cmd(fname)+'.rst')
if not exists(docfile):
print_error('missing documentation file: {!r}'.format(docfile), fname)
return 1
with open(docfile, errors='ignore') as f:
lines = f.readlines()
if not lines:
print_error('empty file', fname)
print_error('empty documentation file', docfile)
return 1
errors += check_ls(fname, lines[0])
for i, l in enumerate(lines):
if doclines or l.strip().endswith(tok1):
if not doclines:
doc_start_line = i + 1
doclines.append(l.rstrip())
if l.startswith(tok2):
break
else:
if doclines:
print_error('docs start but do not end', fname, doc_start_line)
else:
print_error('no documentation found', fname)
return 1
if not doclines:
print_error('missing or malformed documentation', fname)
return 1
l = l.strip()
if l and not doc_start_line and doc_start_line != 0:
doc_start_line = i
doc_end_line = i
lines[i] = l
title, underline = [d for d in doclines
if d and '=begin' not in d and '[====[' not in d][:2]
title_line = doc_start_line + doclines.index(title)
errors += check_ls(docfile, lines)
title, underline = lines[doc_start_line:doc_start_line+2]
expected_underline = '=' * len(title)
if underline != expected_underline:
print_error('title/underline mismatch: expected {!r}, got {!r}'.format(
expected_underline, underline),
fname, title_line + 1)
docfile, doc_start_line+1)
errors += 1
if title != expected_cmd(fname):
if title != get_cmd(fname):
print_error('expected script title {!r}, got {!r}'.format(
expected_cmd(fname), title),
fname, title_line)
get_cmd(fname), title),
docfile, doc_start_line)
errors += 1
return errors

@ -15,178 +15,81 @@ serve to show the default.
# pylint:disable=redefined-builtin
import datetime
from io import open
import os
import re
import shlex # pylint:disable=unused-import
import sphinx
import sys
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'docs', 'sphinx_extensions'))
from dfhack.util import write_file_if_changed
# -- Support :dfhack-keybind:`command` ------------------------------------
# this is a custom directive that pulls info from dfhack.init-example
if os.environ.get('DFHACK_DOCS_BUILD_OFFLINE'):
# block attempted image downloads, particularly for the PDF builder
def request_disabled(*args, **kwargs):
raise RuntimeError('Offline build - network request blocked')
from docutils import nodes
from docutils.parsers.rst import roles
import urllib3.util
urllib3.util.create_connection = request_disabled
import urllib3.connection
urllib3.connection.HTTPConnection.connect = request_disabled
def get_keybinds():
"""Get the implemented keybinds, and return a dict of
{tool: [(full_command, keybinding, context), ...]}.
"""
with open('dfhack.init-example') as f:
lines = [l.replace('keybinding add', '').strip() for l in f.readlines()
if l.startswith('keybinding add')]
keybindings = dict()
for k in lines:
first, command = k.split(' ', 1)
bind, context = (first.split('@') + [''])[:2]
if ' ' not in command:
command = command.replace('"', '')
tool = command.split(' ')[0].replace('"', '')
keybindings[tool] = keybindings.get(tool, []) + [
(command, bind.split('-'), context)]
return keybindings
KEYBINDS = get_keybinds()
# pylint:disable=unused-argument,dangerous-default-value,too-many-arguments
def dfhack_keybind_role_func(role, rawtext, text, lineno, inliner,
options={}, content=[]):
"""Custom role parser for DFHack default keybinds."""
roles.set_classes(options)
if text not in KEYBINDS:
msg = inliner.reporter.error(
'no keybinding for {} in dfhack.init-example'.format(text),
line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
newnode = nodes.paragraph()
for cmd, key, ctx in KEYBINDS[text]:
n = nodes.paragraph()
newnode += n
n += nodes.strong('Keybinding: ', 'Keybinding: ')
for k in key:
n += nodes.inline(k, k, classes=['kbd'])
if cmd != text:
n += nodes.inline(' -> ', ' -> ')
n += nodes.literal(cmd, cmd, classes=['guilabel'])
if ctx:
n += nodes.inline(' in ', ' in ')
n += nodes.literal(ctx, ctx)
return [newnode], []
roles.register_canonical_role('dfhack-keybind', dfhack_keybind_role_func)
# -- Autodoc for DFhack scripts -------------------------------------------
def doc_dir(dirname, files):
"""Yield (command, includepath) for each script in the directory."""
import requests
requests.request = request_disabled
requests.get = request_disabled
# -- Autodoc for DFhack plugins and scripts -------------------------------
def doc_dir(dirname, files, prefix):
"""Yield (name, includepath) for each file in the directory."""
sdir = os.path.relpath(dirname, '.').replace('\\', '/').replace('../', '')
if prefix == '.':
prefix = ''
else:
prefix += '/'
for f in files:
if f[-3:] not in ('lua', '.rb'):
if f[-4:] != '.rst':
continue
with open(os.path.join(dirname, f), 'r', encoding='utf8') as fstream:
text = [l.rstrip() for l in fstream.readlines() if l.strip()]
# Some legacy lua files use the ruby tokens (in 3rdparty scripts)
tokens = ('=begin', '=end')
if f[-4:] == '.lua' and any('[====[' in line for line in text):
tokens = ('[====[', ']====]')
command = None
for line in text:
if command and line == len(line) * '=':
yield command, sdir + '/' + f, tokens[0], tokens[1]
break
command = line
yield prefix + f[:-4], sdir + '/' + f
def doc_all_dirs():
"""Collect the commands and paths to include in our docs."""
scripts = []
for root, _, files in os.walk('scripts'):
scripts.extend(doc_dir(root, files))
return tuple(scripts)
DOC_ALL_DIRS = doc_all_dirs()
tools = []
for root, _, files in os.walk('docs/builtins'):
tools.extend(doc_dir(root, files, os.path.relpath(root, 'docs/builtins')))
for root, _, files in os.walk('docs/plugins'):
tools.extend(doc_dir(root, files, os.path.relpath(root, 'docs/plugins')))
for root, _, files in os.walk('scripts/docs'):
tools.extend(doc_dir(root, files, os.path.relpath(root, 'scripts/docs')))
return tuple(tools)
def document_scripts():
"""Autodoc for files with the magic script documentation marker strings.
Returns a dict of script-kinds to lists of .rst include directives.
"""
# Next we split by type and create include directives sorted by command
kinds = {'base': [], 'devel': [], 'fix': [], 'gui': [], 'modtools': []}
for s in DOC_ALL_DIRS:
k_fname = s[0].split('/', 1)
if len(k_fname) == 1:
kinds['base'].append(s)
else:
kinds[k_fname[0]].append(s)
def template(arg):
tmp = '.. _{}:\n\n.. include:: /{}\n' +\
' :start-after: {}\n :end-before: {}\n'
if arg[0] in KEYBINDS:
tmp += '\n:dfhack-keybind:`{}`\n'.format(arg[0])
return tmp.format(*arg)
return {key: '\n\n'.join(map(template, sorted(value)))
for key, value in kinds.items()}
def write_script_docs():
def write_tool_docs():
"""
Creates a file for eack kind of script (base/devel/fix/gui/modtools)
with all the ".. include::" directives to pull out docs between the
magic strings.
Creates a file for each tool with the ".. include::" directives to pull in
the original documentation.
"""
kinds = document_scripts()
head = {
'base': 'Basic Scripts',
'devel': 'Development Scripts',
'fix': 'Bugfixing Scripts',
'gui': 'GUI Scripts',
'modtools': 'Scripts for Modders'}
for k in head:
title = ('.. _scripts-{k}:\n\n{l}\n{t}\n{l}\n\n'
'.. include:: /scripts/{a}about.txt\n\n'
'.. contents:: Contents\n'
' :local:\n\n').format(
k=k, t=head[k],
l=len(head[k])*'#',
a=('' if k == 'base' else k + '/')
)
mode = 'w' if sys.version_info.major > 2 else 'wb'
with open('docs/_auto/{}.rst'.format(k), mode) as outfile:
outfile.write(title)
outfile.write(kinds[k])
def all_keybinds_documented():
"""Check that all keybindings are documented with the :dfhack-keybind:
directive somewhere."""
configured_binds = set(KEYBINDS)
script_commands = set(i[0] for i in DOC_ALL_DIRS)
with open('./docs/Plugins.rst') as f:
plugin_binds = set(re.findall(':dfhack-keybind:`(.*?)`', f.read()))
undocumented_binds = configured_binds - script_commands - plugin_binds
if undocumented_binds:
raise ValueError('The following DFHack commands have undocumented '
'keybindings: {}'.format(sorted(undocumented_binds)))
# Actually call the docs generator and run test
write_script_docs()
all_keybinds_documented()
for k in doc_all_dirs():
label = ('.. _{name}:\n\n').format(name=k[0])
include = ('.. include:: /{path}\n\n').format(path=k[1])
os.makedirs(os.path.join('docs/tools', os.path.dirname(k[0])),
mode=0o755, exist_ok=True)
with write_file_if_changed('docs/tools/{}.rst'.format(k[0])) as outfile:
if k[0] != 'search':
outfile.write(label)
outfile.write(include)
# -- General configuration ------------------------------------------------
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'docs', 'sphinx_extensions'))
write_tool_docs()
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.8'
needs_sphinx = '3.4.3'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@ -195,22 +98,33 @@ extensions = [
'sphinx.ext.extlinks',
'dfhack.changelog',
'dfhack.lexer',
'dfhack.tool_docs',
]
sphinx_major_version = sphinx.version_info[0]
def get_caption_str(prefix=''):
return prefix + (sphinx_major_version >= 5 and '%s' or '')
# This config value must be a dictionary of external sites, mapping unique
# short alias names to a base URL and a prefix.
# See http://sphinx-doc.org/ext/extlinks.html
extlinks = {
'wiki': ('https://dwarffortresswiki.org/%s', ''),
'wiki': ('https://dwarffortresswiki.org/%s', get_caption_str()),
'forums': ('http://www.bay12forums.com/smf/index.php?topic=%s',
'Bay12 forums thread '),
'dffd': ('https://dffd.bay12games.com/file.php?id=%s', 'DFFD file '),
get_caption_str('Bay12 forums thread ')),
'dffd': ('https://dffd.bay12games.com/file.php?id=%s',
get_caption_str('DFFD file ')),
'bug': ('https://www.bay12games.com/dwarves/mantisbt/view.php?id=%s',
'Bug '),
'source': ('https://github.com/DFHack/dfhack/tree/develop/%s', ''),
'source-scripts': ('https://github.com/DFHack/scripts/tree/master/%s', ''),
'issue': ('https://github.com/DFHack/dfhack/issues/%s', 'Issue '),
'commit': ('https://github.com/DFHack/dfhack/commit/%s', 'Commit '),
get_caption_str('Bug ')),
'source': ('https://github.com/DFHack/dfhack/tree/develop/%s',
get_caption_str()),
'source-scripts': ('https://github.com/DFHack/scripts/tree/master/%s',
get_caption_str()),
'issue': ('https://github.com/DFHack/dfhack/issues/%s',
get_caption_str('Issue ')),
'commit': ('https://github.com/DFHack/dfhack/commit/%s',
get_caption_str('Commit ')),
}
# Add any paths that contain templates here, relative to this directory.
@ -259,7 +173,7 @@ version = release = get_version()
# for a list of supported languages.
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'
# strftime format for |today| and 'Last updated on:' timestamp at page bottom
today_fmt = html_last_updated_fmt = '%Y-%m-%d'
@ -268,11 +182,18 @@ today_fmt = html_last_updated_fmt = '%Y-%m-%d'
# directories to ignore when looking for source files.
exclude_patterns = [
'README.md',
'docs/html*',
'depends/*',
'build*',
'docs/_auto/news*',
'docs/_changelogs/',
'depends/*',
'docs/html/*',
'docs/tags/*',
'docs/text/*',
'docs/builtins/*',
'docs/pdf/*',
'docs/plugins/*',
'docs/pseudoxml/*',
'docs/xml/*',
'scripts/docs/*',
'plugins/*',
]
# The reST default role (used for this markup: `text`) to use for all
@ -345,16 +266,20 @@ html_sidebars = {
]
}
# If false, no module index is generated.
html_domain_indices = False
# If false, no index is generated.
# generate domain indices but not the (unused) genindex
html_use_index = False
html_domain_indices = True
# don't link to rst sources in the generated pages
html_show_sourcelink = False
html_css_files = [
'dfhack.css',
]
if sphinx_major_version >= 5:
html_css_files.append('sphinx5.css')
# -- Options for LaTeX output ---------------------------------------------
# Grouping the document tree into LaTeX files. List of tuples
@ -366,3 +291,15 @@ latex_documents = [
]
latex_toplevel_sectioning = 'part'
# -- Options for text output ---------------------------------------------
from sphinx.writers import text
# this value is arbitrary. it just needs to be bigger than the number of
# characters in the longest paragraph in the DFHack docs
text.MAXWIDTH = 1000000000
# this is the order that section headers will use the characters for underlines
# they are in the order of (subjective) text-mode readability
text_sectionchars = '=-~`+"*'

@ -1,9 +1,21 @@
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/init/
DESTINATION "${DFHACK_DATA_DESTINATION}/init")
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/base_command_counts.json
DESTINATION "${DFHACK_DATA_DESTINATION}/data/base_command_counts.json")
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/quickfort/
DESTINATION "${DFHACK_DATA_DESTINATION}/data/quickfort")
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/orders/
DESTINATION dfhack-config/orders/library)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/examples/
DESTINATION "${DFHACK_DATA_DESTINATION}/examples")
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/professions/
DESTINATION dfhack-config/professions/library)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/blueprints/
DESTINATION blueprints
FILES_MATCHING PATTERN "*"

@ -0,0 +1,145 @@
{
"manipulator": 75,
"autolabor": 59,
"reveal": 51,
"help": 50,
"ls": 50,
"die": 50,
"tags": 50,
"embark-assistant": 42,
"prospect": 37,
"autodump": 36,
"clean": 35,
"gui/workflow": 28,
"workflow": 28,
"exportlegends": 26,
"gui/autobutcher": 25,
"autobutcher": 25,
"digv": 24,
"fastdwarf": 22,
"autonestbox": 20,
"showmood": 19,
"gui/liquids": 18,
"liquids": 18,
"search": 18,
"gui/quickfort": 15,
"quickfort": 15,
"createitem": 14,
"stocks": 14,
"autofarm": 12,
"autochop": 12,
"tiletypes": 12,
"exterminate": 12,
"buildingplan": 12,
"quicksave": 11,
"gui/gm-editor": 11,
"cleanowned": 10,
"gui/autogems": 9,
"autogems": 9,
"stonesense": 9,
"gui/stockpiles": 8,
"stockpiles": 8,
"changevein": 8,
"gui/teleport": 7,
"teleport": 7,
"seedwatch": 6,
"automelt": 6,
"embark-tools": 6,
"cursecheck": 5,
"open-legends": 5,
"ban-cooking": 5,
"burial": 5,
"automaterial": 5,
"remove-stress": 5,
"gui/blueprint": 5,
"blueprint": 5,
"tailor": 4,
"startdwarf": 4,
"3dveins": 4,
"digcircle": 4,
"nestboxes": 3,
"deathcause": 3,
"list-agreements": 3,
"gui/room-list": 3,
"points": 3,
"region-pops": 3,
"gui/advfort": 3,
"unsuspend": 3,
"locate-ore": 3,
"changelayer": 3,
"source": 3,
"gui/gm-unit": 3,
"combine-drinks": 3,
"combine-plants": 3,
"deteriorate": 3,
"warn-starving": 3,
"gaydar": 2,
"gui/dfstatus": 2,
"gui/rename": 2,
"rename": 2,
"fix-ster": 2,
"job-material": 2,
"stockflow": 2,
"drain-aquifer": 2,
"full-heal": 2,
"spawnunit": 2,
"flashstep": 2,
"gui/family-affairs": 2,
"caravan": 2,
"mousequery": 2,
"tweak": 2,
"confirm": 2,
"autoclothing": 1,
"autounsuspend": 1,
"prioritize": 1,
"dwarfmonitor": 1,
"show-unit-syndromes": 1,
"troubleshoot-item": 1,
"gui/mechanisms": 1,
"gui/pathable": 1,
"hotkeys": 1,
"infiniteSky": 1,
"force": 1,
"hermit": 1,
"strangemood": 1,
"weather": 1,
"add-recipe": 1,
"autotrade": 1,
"zone": 1,
"autonick": 1,
"stripcaged": 1,
"unforbid": 1,
"workorder": 1,
"gui/mod-manager": 1,
"spotclean": 1,
"plant": 1,
"regrass": 1,
"dig-now": 1,
"build-now": 1,
"clear-webs": 1,
"gui/siege-engine": 1,
"assign-skills": 1,
"brainwash": 1,
"elevate-mental": 1,
"elevate-physical": 1,
"launch": 1,
"linger": 1,
"make-legendary": 1,
"rejuvenate": 1,
"resurrect-adv": 1,
"questport": 1,
"getplants": 1,
"gui/stamper": 1,
"tweak": 1,
"fixveins": 1,
"deramp": 1,
"fix/dead-units": 1,
"fix/fat-dwarves": 1,
"fix/loyaltycascade": 1,
"fix/retrieve-units": 1,
"tweak": 1,
"sort-items": 1,
"gui/color-schemes": 1,
"color-schemes": 1,
"season-palette": 1
}

@ -1,5 +1,5 @@
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 command reference](https://docs.dfhack.org/en/stable/docs/tools/quickfort.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)

@ -29,11 +29,11 @@
"Dreamfort works best at an embark site that is flat and has at least one soil layer. New players should avoid embarks with aquifers if they are not prepared to deal with them. Bring picks for mining, an axe for woodcutting, and an anvil for a forge. Bring a few blocks to speed up initial workshop construction as well. That's all you really need, but see the example embark profile in the online spreadsheets for a more complete setup."
""
"Other DFHack commands also work very well with Dreamfort, such as autofarm, autonestbox, prioritize, seedwatch, tailor, and, of course, buildingplan. An init file that gets everything configured for you is distributed with DFHack as hack/examples/init/onMapLoad_dreamfort.init."
Put that file in your Dwarf Fortress directory -- the same directory that has dfhack.init.
Put that file in your dfhack-config/init/ directory -- the same directory that has dfhack.init.
""
"Also copy the files in hack/examples/orders/ to dfhack-config/orders/ and the files in hack/examples/professions/ to professions/. We'll be using these files later. See https://docs.dfhack.org/en/stable/docs/guides/examples-guide.html for more information, including suggestions on how many dwarves of each profession you are likely to need at each stage of fort maturity."
"Also check out https://docs.dfhack.org/en/stable/docs/Plugins.html#professions for more information on the default labor professions that are distributed with DFHack, including suggestions on how many dwarves of each profession you are likely to need at each stage of fort maturity."
""
"Once you have your starting surface workshops up and running, you might want to configure buildingplan (in its global settings, accessible from any building placement screen, e.g.: b-a-G) to only use blocks for constructions so it won't use your precious wood, boulders, and bars to build floors and walls. If you bring at least 7 blocks with you on embark, you can even set this in your onMapLoad.init file like this:"
"Once you have your starting surface workshops up and running, you might want to configure buildingplan (in its global settings, accessible from any building placement screen, e.g.: b-a-G) to only use blocks for constructions so it won't use your precious wood, boulders, and bars to build floors and walls. If you bring at least 7 blocks with you on embark, you can even set this in your dfhack-config/init/onMapLoad.init file like this:"
on-new-fortress buildingplan set boulders false; buildingplan set logs false
""
"Directly after embark, run ""quickfort run library/dreamfort.csv -n /setup"" with your cursor on your wagon to set settings, and get started building your fort with ""quickfort run library/dreamfort.csv -n /surface1"" on the surface (see /surface_help for how to select a good spot). Read the walkthroughs for each level to understand what's going on and follow the checklist to keep track of where you are in the building process. Good luck, and have fun building an awesome Dreamfort-based fort!"
@ -49,9 +49,7 @@ interactively."
"Here is the recommended order for Dreamfort commands. You can copy/paste the command lines directly into the DFHack terminal, or, if you prefer, you can run the blueprints in the UI with gui/quickfort. See the walkthroughs (the ""help"" blueprints) for context and details. Also remember to read the messages the blueprints print out after you run them so you don't miss any important manual steps."
""
-- Preparation (before you embark!) --
Copy hack/examples/init/onMapLoad_dreamfort.init to your DF directory
Copy the fort automation orders from hack/examples/orders/*.json to the dfhack-config/orders/ directory
Optionally copy the premade profession definitions from hack/examples/professions/ to the professions/ directory
Copy hack/examples/init/onMapLoad_dreamfort.init to your dfhack-config/init directory inside your DF installation
Optionally copy the premade Dreamfort embark profile from the online spreadsheets to the data/init/embark_profiles.txt file
""
-- Set settings and preload initial orders --
@ -74,36 +72,36 @@ quickfort run library/dreamfort.csv -n /farming3,# Run when furniture has been p
quickfort run library/dreamfort.csv -n /industry2,# Run when the industry level has been dug out.
prioritize ConstructBuilding,# To get those workshops up and running ASAP. You may have to run this several times as the materials for the building construction jobs become ready.
quickfort run library/dreamfort.csv -n /surface4,"# Run after the walls and floors are built on the surface. Even if /surface3 is finished before you run /industry2, though, wait until after /industry2 to run this blueprint so that surface walls, floors, and roofing don't prevent your workshops from being built (due to lack of blocks)."
"quickfort run,orders library/dreamfort.csv -n /services2",# Run when the services levels have been dug out. Feel free to remove the orders for the ropes if you already brought them with you.
orders import basic,"# Run after the first migration wave, so you have dorfs to do all the basic tasks. Note that this is the ""orders"" plugin, not the ""quickfort orders"" command."
"quickfort run,orders library/dreamfort.csv -n /surface5","# Run when all marked trees on the surface are chopped down and walls and floors have been constructed, including the roof section over the future barracks."
"quickfort orders,run library/dreamfort.csv -n /services2",# Run when the services levels have been dug out. Feel free to remove the orders for the ropes if you already brought them with you.
orders import library/basic,"# Run after the first migration wave, so you have dorfs to do all the basic tasks. Note that this is the ""orders"" plugin, not the ""quickfort orders"" command."
"quickfort orders,run library/dreamfort.csv -n /surface5","# Run when all marked trees on the surface are chopped down and walls and floors have been constructed, including the roof section over the future barracks."
prioritize ConstructBuilding,# Run when you see the bridges ready to be built so the busy masons come and build them.
"quickfort run,orders library/dreamfort.csv -n /surface6",# Run when at least the beehives and weapon rack are constructed and you have linked all levers to their respective bridges.
"quickfort run,orders library/dreamfort.csv -n /surface7",# Run after the surface walls are completed and any marked trees are chopped down.
"quickfort orders,run library/dreamfort.csv -n /surface6",# Run when at least the beehives and weapon rack are constructed and you have linked all levers to their respective bridges.
"quickfort orders,run library/dreamfort.csv -n /surface7",# Run after the surface walls are completed and any marked trees are chopped down.
""
-- Plumbing --
"This is a good time to fill your well cisterns, either with a bucket brigade or by routing water from a freshwater stream or an aquifer (see the library/aquifer_tap.csv blueprint for help with this)."
"Also consider bringing magma up to your services level so you can replace the forge and furnaces on your industry level with more powerful magma versions. This is especially important if your embark has insufficient trees to convert into charcoal. Keep in mind that moving magma is a tricky process and can take a long time. Don't forget to continue making progress through the checklist! If you choose to use magma, I suggest getting it in place before importing the military and smelting automation orders since they make heavy use of furnaces and forges."
""
-- Mature fort (third migration wave onward) --
orders import furnace,# Automated production of basic furnace-related items. Don't forget to create a sand collection zone (or remove the sand- and glass-related orders if you have no sand).
"quickfort run,orders library/dreamfort.csv -n /suites2",# Run when the suites level has been dug out.
"quickfort run,orders library/dreamfort.csv -n /surface8","# Run if/when you need longer trap corridors on the surface for larger sieges, anytime after you run /surface7."
"quickfort run,orders library/dreamfort.csv -n /apartments2",# Run when the first apartment level has been dug out.
"quickfort run,orders library/dreamfort.csv -n /services3","# Run after the dining table and chair, weapon rack, and archery targets have been constructed. Also wait until after you complete /surface7, though, because surface defenses are more important than a grand dining hall."
"quickfort run,orders library/dreamfort.csv -n /guildhall2",# Run when the guildhall level has been dug out.
"quickfort run,orders library/dreamfort.csv -n ""/guildhall3, /guildhall4""",# Optionally run after /guildhall2 to build default furnishings and declare a library and temple.
"quickfort run,orders library/dreamfort.csv -n /apartments3",# Run when all beds have been constructed on the first apartments level.
"quickfort run,orders library/dreamfort.csv -n /farming4",# Run once you have a cache of potash.
orders import military,# Automated production of military equipment. Turn on automelt in the meltables piles on the industry level to automatically upgrade all metal military equipment to masterwork quality. These orders are optional if you are not using a military.
orders import smelting,# Automated production of all types of metal bars.
"quickfort run,orders library/dreamfort.csv -n /services4","# Run when you need a jail, anytime after the restraints are placed from /services3."
orders import rockstock,# Maintains a small stock of all types of rock furniture.
orders import glassstock,# Maintains a small stock of all types of glass furniture and parts (only import if you have sand).
orders import library/furnace,# Automated production of basic furnace-related items. Don't forget to create a sand collection zone (or remove the sand- and glass-related orders if you have no sand).
"quickfort orders,run library/dreamfort.csv -n /suites2",# Run when the suites level has been dug out.
"quickfort orders,run library/dreamfort.csv -n /surface8","# Run if/when you need longer trap corridors on the surface for larger sieges, anytime after you run /surface7."
"quickfort orders,run library/dreamfort.csv -n /apartments2",# Run when the first apartment level has been dug out.
"quickfort orders,run library/dreamfort.csv -n /services3","# Run after the dining table and chair, weapon rack, and archery targets have been constructed. Also wait until after you complete /surface7, though, because surface defenses are more important than a grand dining hall."
"quickfort orders,run library/dreamfort.csv -n /guildhall2",# Run when the guildhall level has been dug out.
"quickfort orders,run library/dreamfort.csv -n ""/guildhall3, /guildhall4""",# Optionally run after /guildhall2 to build default furnishings and declare a library and temple.
"quickfort orders,run library/dreamfort.csv -n /apartments3",# Run when all beds have been constructed on the first apartments level.
"quickfort orders,run library/dreamfort.csv -n /farming4",# Run once you have a cache of potash.
orders import library/military,# Automated production of military equipment. Turn on automelt in the meltables piles on the industry level to automatically upgrade all metal military equipment to masterwork quality. These orders are optional if you are not using a military.
orders import library/smelting,# Automated production of all types of metal bars.
"quickfort orders,run library/dreamfort.csv -n /services4","# Run when you need a jail, anytime after the restraints are placed from /services3."
orders import library/rockstock,# Maintains a small stock of all types of rock furniture.
orders import library/glassstock,# Maintains a small stock of all types of glass furniture and parts (only import if you have sand).
""
-- Repeat for each remaining apartments level as needed --
"quickfort run,orders library/dreamfort.csv -n /apartments2",# Run when the apartment level has been dug out.
"quickfort run,orders library/dreamfort.csv -n /apartments3",# Run when all beds have been constructed.
"quickfort orders,run library/dreamfort.csv -n /apartments2",# Run when the apartment level has been dug out.
"quickfort orders,run library/dreamfort.csv -n /apartments3",# Run when all beds have been constructed.
burial -pets,# Run once the coffins are placed to set them to allow for burial.
See this checklist online at https://docs.google.com/spreadsheets/d/13PVZ2h3Mm3x_G1OXQvwKd7oIR2lK4A1Ahf6Om1kFigw/edit#gid=1459509569
@ -232,6 +230,7 @@ https://drive.google.com/file/d/1Et42JTzeYK23iI5wrPMsFJ7lUXwVBQob/view?usp=shari
[PET:2:BIRD_GOOSE:FEMALE:STANDARD]
[PET:2:BIRD_GOOSE:MALE:STANDARD]
#meta label(all_orders) hidden() references all blueprints that generate orders; for testing only
/surface1
/surface2
/surface3
/surface4
@ -239,27 +238,25 @@ https://drive.google.com/file/d/1Et42JTzeYK23iI5wrPMsFJ7lUXwVBQob/view?usp=shari
/surface6
/surface7
/surface8
/farming1
/farming2
/farming3
/farming4
/industry1
/industry2
/services1
/services2
/services3
/services4
/guildhall1
/guildhall2
/guildhall3
/guildhall4
/suites1
/suites2
/apartments2
/apartments2
/apartments2
/apartments2
/apartments2
/apartments2
/apartments3
/apartments3
/apartments3
/apartments3
/apartments3
/apartments3
/apartments1 repeat(>5)
/apartments2 repeat(>5)
/apartments3 repeat(>5)
#notes label(surface_help)
Sets up a protected entrance to your fort in a flat area on the surface.
Screenshot: https://drive.google.com/file/d/1YL_vQJLB2YnUEFrAg9y3HEdFq3Wpw9WP
@ -317,7 +314,7 @@ Here are some tips and procedures for handling seiges -- including how to clean
""
"After a siege, you can use the caged prisoners to safely train your military. Here's how:"
""
"- Once the prisoners are hauled to the ""prisoner quantum"" stockpile, run ""stripcaged all"" in the DFHack console."
"- Once the prisoners are hauled to the ""prisoner quantum"" stockpile, run ""unforbid all"" and ""stripcaged all"" in the DFHack console (or GUI launcher)."
""
"- After all the prisoners' items have been confiscated, bring your military dwarves to the barracks (if they aren't already there)."
""
@ -334,10 +331,11 @@ corridor/surface_corridor
message(Once the central stairs are mined out deeply enough, you should start digging the industry level in a non-aquifer rock layer. You'll need the boulders from the digging to make blocks.
If your wagon is within the fort perimeter, deconstruct it to get it out of the way.
Once the marked trees are all chopped down (if any), continue with /surface2.) clear trees and set up pastures"
central_stairs/central_stairs repeat(down 10)
clear_small/surface_clear_small
zones/surface_zones
name_zones/surface_name_zones
#>
central_stairs/central_stairs repeat(down 10)
""
"#meta label(surface2) start(central stairs) message(Remember to enqueue manager orders for this blueprint.
Once the channels are dug out and the marked trees are cleared, continue with /surface3.) set up starting workshops/stockpiles, channel miasma vents, and clear more trees"
@ -363,6 +361,7 @@ Once the marked trees are cleared and at least the beehives and weapon rack have
place/surface_place
build/surface_build
query/surface_query
traffic/surface_traffic
clear_large/surface_clear_large
""
"#meta label(surface6) start(central stairs) message(Remember to enqueue manager orders for this blueprint.
@ -387,9 +386,9 @@ corridor/surface_corridor
corridor_traps/surface_corridor_traps
query_corridor/surface_query_corridor
#dig label(central_stairs_odd) start(2;2) hidden() spiral stairs odd levels
`,u,`
j6,`,j6
`,u,`
`,j6,`
u,`,u
`,j6,`
#meta label(central_stairs_even) hidden() spiral stairs even levels
/central_stairs_odd transform(cw)
#meta label(central_stairs) two levels of spiral stairs (use --repeat down)
@ -413,11 +412,11 @@ j6,`,j6
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,`,`,`,`,t1,`,`,`,`,`,`,,`,,`,`,`,`,`,t1,`,`,`,t1,`,`,,`
,,,`,,`,,`,t1,t1,,,,,,`,,,,,,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,,`,`,`,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,`,,`,~,`,,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,,`,`,`,,,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,`,,,,,,`,,,,,,,,,,`,,`
,,,`,,`,,`,t1,t1,,,,,,`,t1,t1,t1,t1,t1,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,t1,t1,t1,t1,t1,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,`,t1,j,t1,j,t1,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,t1,t1,t1,t1,t1,,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,`,t1,t1,t1,t1,t1,`,,,,,,,,,,`,,`
,,,`,,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,,`,`,`,`,`,`,`,,`
,,,`,,`,,,,,,,,,`,t1,,,,,,t1,`,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,t1,t1,,,,,,t1,t1,,,,,,,,,`,,`
@ -866,8 +865,8 @@ Feel free to assign an unimportant animal to the pasture in the main entranceway
,,,`,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,~,,,,,,~,`,,,,,,,Cf,Cf,`,,`
,,,`,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,~,~,Cf,Cf,Cf,Cf,Cf,~,~,,,,,,,,Cf,`,,`
,,,`,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,~,~,,~,~,~,,~,~,,,,,Cf,Cf,,Cf,`,,`
,,,`,,`,,Cf,,Cf,Cf,Cf,Cf,Cf,,Cf,,~,~,~,,Cf,,,,,,,,,Cf,`,,`
,,,`,,`,,Cf,,Cf,Cf,Cf,Cf,Cf,`,,,~,~,~,,,`,,,,,,,Cf,Cf,`,,`
,,,`,,`,,Cf,,Cf,Cf,Cf,Cf,Cf,,Cf,,~,~,~,,Cf,,,Cf,,,,,,Cf,`,,`
,,,`,,`,,Cf,,Cf,Cf,Cf,Cf,Cf,`,,,~,~,~,,,`,,Cf,,,,,Cf,Cf,`,,`
,,,`,,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,,`
,,,`,Cf,,,,,,,,,Cf,,,,,~,,,,,Cf,,,,,,,,,Cf,`
,,,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`
@ -982,6 +981,40 @@ You might also want to set the ""trade goods quantum"" stockpile to Auto Trade i
#dig label(surface_traffic) start(19; 19) hidden() set traffic designations
,,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,,`
,,,`,,`,,`,,,,,,,,`,,,,,,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,,`,`,`,,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,`,,`,`,`,,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,,`,`,`,,,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,`,,,,,,`,,,,,,,,,,`,,`
,,,`,,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,or,`,`,`,`,`,`,`,,`
,,,`,,`,,,,,,,,,`,,ol,ol,ol,ol,ol,,`,or,,,,,,,,`,,`
,,,`,,`,,,,,,,,,ol,ol,ol,ol,ol,ol,ol,ol,ol,or,,,,,,,,`,,`
,,,`,,`,,,,,,,,,ol,ol,,,,,,ol,ol,or,,,,,,,,`,,`
,,,`,,`,,,,,,,,,ol,ol,,,,,,ol,ol,or,,,,,,,,`,,`
,,,`,,`,,,,,,,,,`,,,,,,,,`,or,,,,,,,,`,,`
,,,`,,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,,`
,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,`,`,`,`,`,`,`,`,`,`,`,`,ol,ol,ol,ol,ol,ol,ol,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,ol,ol,ol,ol,ol,ol,ol
,,,,,,,,,,,,,,,ol,ol,ol,ol,ol,ol,ol
#dig label(surface_clear_large) start(19; 19) hidden() clear wider area of trees
t1(37x33)
@ -1110,8 +1143,8 @@ t1(37x33)
,,,`,,`,~,~,~,~,~,~,~,~,`,~,~,~,~,~,~,~,`,Cf,Cf,Cf,Cf,Cf,Cf,~,~,`,,`
,,,`,,`,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,Cf,Cf,Cf,Cf,Cf,Cf,Cf,~,`,,`
,,,`,,`,~,~,~,~,~,~,~,~,~,~,Cf,~,~,~,Cf,~,~,Cf,Cf,Cf,Cf,~,~,Cf,~,`,,`
,,,`,,`,Cf,~,Cf,~,~,~,~,~,~,~,Cf,~,~,~,Cf,~,~,Cf,Cf,Cf,Cf,Cf,Cf,Cf,~,`,,`
,,,`,,`,Cf,~,Cf,~,~,~,~,~,`,Cf,Cf,~,~,~,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,~,~,`,,`
,,,`,,`,Cf,~,Cf,~,~,~,~,~,~,~,Cf,~,~,~,Cf,~,~,Cf,~,Cf,Cf,Cf,Cf,Cf,~,`,,`
,,,`,,`,Cf,~,Cf,~,~,~,~,~,`,Cf,Cf,~,~,~,Cf,Cf,`,Cf,~,Cf,Cf,Cf,Cf,~,~,`,,`
,,,`,,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,,`
,,,`,~,,,,,,,,,,,Cf,Cf,Cf,~,Cf,Cf,Cf,,,,,,,,,,,~,`
,,,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`
@ -1532,6 +1565,7 @@ Farming Walkthrough:
Once furniture has been placed, continue with /farming3.) workshops, stockpiles, and important furniture"
build/farming_build
place/farming_place
traffic/farming_traffic
query_stockpiles/farming_query_stockpiles
link_stockpiles/farming_link
""
@ -1604,6 +1638,37 @@ build3/farming_build3
,,,,,,,,,,,,,,,ry
#dig label(farming_traffic) start(16; 18) hidden() keep hungry dwarves away from the crops and food stores so they prefer the prepared meals
,,,,,,,,,ol,ol,ol,,or,or,or,or,or,,ol,ol,ol,ol
,,,,,,,,,ol,ol,ol,,or,or,or,or,or,,ol,ol,ol,ol
,,,,,,,,,ol,ol,ol,,or,or,or,or,or,,ol,ol,ol,ol
,,,,,,,,,,,ol,,or,or,or,or,or,,ol,ol,ol,ol
,,,,,,,ol,ol,ol,,ol,,or,or,or,or,or,,ol,ol,ol,ol
,,,,,,,ol,ol,ol,ol,ol,,or,or,or,or,or,,ol,ol,ol,ol
,,,,,,,ol,ol,ol,,ol,,or,or,or,or,or,,ol
,,,,,,,,,,,ol,,or,or,or,or,or,,ol,,ol,ol,ol
,,,,,,ol,ol,ol,ol,,ol,,or,or,or,or,or,,ol,ol,ol,ol,ol
,,,,,,ol,ol,ol,ol,,ol,,or,or,or,or,or,,ol,,ol,ol,ol
,,,ol,ol,,ol,ol,ol,ol,,ol,,or,or,or,or,or,,ol
,,ol,ol,ol,,ol,ol,ol,ol,,ol,,or,or,or,or,or,,ol,,ol,ol,ol,,ol,ol,ol
,,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,,or,,or,,,ol,ol,ol,ol,ol,ol,ol,ol,ol
,,,ol,ol,,ol,ol,ol,ol,,ol,ol,ol,ol,ol,ol,ol,ol,ol,,ol,ol,ol,,ol,ol,ol
,,,,or,,,or,,,,,,ol,`,`,`,ol,,,,,or,,,,or
,,or,or,or,or,or,or,or,or,or,or,,ol,`,~,`,ol,,or,or,or,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,or,or,or,or,ol,`,`,`,ol,or,or,or,or,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,or,or,or,,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,or,or,,,,ol,,ol,,,,or,or,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,or,,,ol,ol,ol,ol,ol,ol,ol,,,or,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,or,,ol,ol,,,ol,,,ol,ol,,or,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,,,ol,ol,,ol,ol,ol,,ol,ol,,,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,,ol,ol,ol,,ol,ol,ol,,ol,ol,ol,,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,,ol,ol,ol,,ol,ol,ol,,ol,ol,ol,,or,or,or,or,or,or,or
,,or,or,or,or,or,or,or,,ol,ol,ol,,,ol,,,ol,ol,ol,,or,or,or,or,or,or,or
,,,,,,,,,,,,,,,ol
"#query label(farming_query_stockpiles) start(16; 18) hidden() message(remember to:
- assign a minecart to the refuse quantum stockpile (run ""assign-minecarts all"")
- if the industry level is already built, configure the jugs, pots, and bags stockpiles to take from the ""Goods"" quantum stockpile on the industry level) config stockpiles"
@ -1672,7 +1737,7 @@ build3/farming_build3
,,,,,,,,,`,`,`,,`,`,`,`,`,,`,`,`,`
,,,,,,,,,r&,`,`,,`,`,`,`,`,,`,`,`,`
,,,,,,,,,r&a+&,,,,`,`,`,`,`,,`,`,`,`
,,,,,,,,,`,`,`,,`,`,`,`,`,,`,`,r+&h
,,,,,,,,,,,`,,`,`,`,`,`,,`,`,`,`
,,,,,,,`,`,`,,`,,`,`,`,`,`,,`,`,`,`
@ -1830,7 +1895,6 @@ Workshops:
Manual steps you have to take:
- Assign minecarts to your quantum stockpile hauling routes
"- Give from the ""Goods"" quantum stockpile to the jugs, pots, and bags stockpiles on the farming level"
- Copy the fort automation manager orders (the .json files) from hack/examples/orders/ and put them in your dfhack-config/orders/ directory.
""
Optional manual steps you can take:
- Restrict the Mechanic's workshop to only allow skilled workers so unskilled trap-resetters won't be tasked to build mechanisms.
@ -1846,11 +1910,11 @@ Industry Walkthrough:
""
"3) Once the area is dug out, run /industry2. Remember to assign minecarts to to your quantum stockpile hauling routes, and if the farming level is already built, give from the ""Goods"" quantum stockpile (the one on the left) to the jugs, pots, and bags stockpiles on the farming level."
""
"4) Once you have enough dwarves to do maintenance tasks (that is, after the first or second migration wave), run ""orders import basic"" to use the provided basic.json to take care of your fort's basic needs, such as food, booze, and raw material processing."
"4) Once you have enough dwarves to do maintenance tasks (that is, after the first or second migration wave), run ""orders import library/basic"" to use the provided basic.json to take care of your fort's basic needs, such as food, booze, and raw material processing."
""
"5) If you want to automatically melt goblinite and other low-quality weapons and armor, mark the south-east stockpiles for auto-melt. If you don't have a high density of trees to make into charcoal, though, be sure to route magma to the level beneath this one and replace the forge and furnaces with magma equivalents."
""
"6) Once you have magma furnaces (or abundant fuel) and more dwarves, run ""orders import furnace"", ""orders import military"", and ""orders import smelting"" to import the remaining fort automation orders. The military orders are optional if you are not planning to have a military, of course."
"6) Once you have magma furnaces (or abundant fuel) and more dwarves, run ""orders import library/furnace"", ""orders import library/military"", and ""orders import library/smelting"" to import the remaining fort automation orders. The military orders are optional if you are not planning to have a military, of course."
""
"7) At any time, feel free to build extra workshops or designate custom stockpiles in the unused space in the top and bottom right. The space is there for you to use!"
"#dig label(industry1) start(18; 18; central stairs) message(Once the area is dug out, continue with /industry2.)"
@ -1969,7 +2033,7 @@ query/industry_query
- assign minecarts to to your quantum stockpile hauling routes (use ""assign-minecarts all"")
- if the farming level is already built, give from the ""Goods"" quantum stockpile to the jugs, pots, and bags stockpiles on the farming level
- if you want to automatically melt goblinite and other low-quality weapons and armor, mark the south-east stockpiles for auto-melt
- once you have enough dwarves, run ""orders import basic"" to automate your fort's basic needs (see /industry_help for more info on this file)
- once you have enough dwarves, run ""orders import library/basic"" to automate your fort's basic needs (see /industry_help for more info on this file)
- optionally, restrict the labors for your Craftsdwarf's and Mechanic's workshops as per the guidance in /industry_help)"
@ -2142,9 +2206,9 @@ Services Walkthrough:
"#meta label(services2) start(central stairs) message(Remember to enqueue manager orders for this blueprint.
Once furniture has been placed, continue with /services3.) dining hall anchors, stockpiles, hospital, garbage dump"
zones/services_zones
build/services_build
place/services_place
zones/services_zones
name_zones/services_name_zones
query_stockpiles/services_query_stockpiles
""
@ -2157,6 +2221,64 @@ build2/services_build2
build3/services_build3
place_jail/services_place_jail
query_jail/services_query_jail
"#zone label(services_zones) start(18; 18) hidden() message(If you'd like to fill your wells via bucket brigade, activate the inactive pond zones one level down from where the wells will be built.) garbage dump, hospital, and pond zones"
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
,,`,,,,`,,,,`,,,,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,,,,,`,,,,,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,,`,,`,,,,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,,`,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,,,d,,,,,ht,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,,,,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
#>
,,,,,,,,,,,,,`,apPf,`,,`,,`,apPf,`
,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,`,apPf,`,,`,,`,apPf,`
,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`,,,,,,,,,`
,,,,,,,,,,,,,,,,,`,,,,,,,,,`
,,,,,,,,,,,,,,,`,`,`,`,`,,,,,,,`
,,,,,,,,,,,,,,,`,`,`,`,`,,,,,,`,`,`
,,,,,,,,,,,,,,,`,`,`,`,`,,,,,,`,apPf,`
,,,,,,,,,,,,,,,`,`,`,`,`
,,,,,,,,,,,,,,,`,`,`,`,`
#build label(services_build) start(18; 18) hidden() build basic hospital and dining room anchor
,b,b,b,,b,b,b,,b,b,b,,`,`,`,,`,,`,`,`
@ -2170,7 +2292,7 @@ query_jail/services_query_jail
,`,`,`,`,`,`,`,`,`,`,`,,`,A,A,A,`,A,A,A,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,r,`,`,`,`,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,d,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,trackstopN,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,,`,,`,,b
,`,`,`,`,`,`,`,`,`,`,`,,,,,d,,d,,,,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,,`,`,`,t,`,`,`,`,R
@ -2205,9 +2327,9 @@ query_jail/services_query_jail
,`,`,`,`,`,`,`,`,`,`,`,,,,,,`,,,,,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,z(7x3),,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,c,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,z(7x1),,,`,`,`,`,`,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,,,,`,,`,,,,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -2229,64 +2351,6 @@ query_jail/services_query_jail
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
"#zone label(services_zones) start(18; 18) hidden() message(If you'd like to fill your wells via bucket brigade, activate the inactive pond zones one level down from where the wells will be built.) hospital, garbage dump, and pond zones"
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
,,`,,,,`,,,,`,,,,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,,,,,`,,,,,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,ht,,ht,,ht,,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,,`,,`,,,,,ht,,ht,,ht,,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,,`,,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,,ht,ht,ht,ht,ht,ht,ht,ht,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,,,d,,,,,,ht,,ht,,ht,,ht
,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,,,,,ht,,ht,,ht,,ht
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
#>
,,,,,,,,,,,,,`,apPf,`,,`,,`,apPf,`
,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,`,apPf,`,,`,,`,apPf,`
,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`
,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`,,,,,,,,,`
,,,,,,,,,,,,,,,,,`,,,,,,,,,`
,,,,,,,,,,,,,,,`,`,`,`,`,,,,,,,`
,,,,,,,,,,,,,,,`,`,`,`,`,,,,,,`,`,`
,,,,,,,,,,,,,,,`,`,`,`,`,,,,,,`,apPf,`
,,,,,,,,,,,,,,,`,`,`,`,`
,,,,,,,,,,,,,,,`,`,`,`,`
#query label(services_name_zones) start(18; 18) hidden()
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
@ -2345,7 +2409,7 @@ query_jail/services_query_jail
,,,,,,,,,,,,,,,`,`,`,`,`
,,,,,,,,,,,,,,,`,`,`,`,`
#query label(services_query_stockpiles) start(18; 18) hidden() message(Configure the training ammo stockpile to take from the metalworker quantum on the industry level.) configure stockpiles
"#query label(services_query_stockpiles) start(18; 18) hidden() message(Configure the training ammo stockpile to take from the metalworker quantum on the industry level. Assign a minecart to the training ammo quantum dump with ""assign-minecarts all"") configure stockpiles"
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
@ -2357,9 +2421,9 @@ query_jail/services_query_jail
,`,`,`,`,`,`,`,`,`,`,`,,,,,,`,,,,,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,nocontainers,{bolts}{forbidmetalbolts}{forbidartifactammo},"{givename name=""training bolts""}",`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,"{quantum name=""training quantum""}",`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,"{quantumstopfromsouth name=""Training quantum""}{givename name=""training dumper""}",`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,,`,nocontainers,{bolts}{forbidmetalbolts}{forbidartifactammo},"{givename name=""training bolts""}",`,`,`,`,`,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,,,,`,,`,,,,,`,,`,,`,,`
,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -2381,7 +2445,7 @@ query_jail/services_query_jail
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
"#query label(services_query_dining) start(18; 18) message(The tavern is restricted to residents only by default. If you'd like your tavern to attract vistors, please go to the (l)ocation menu and change the restriction.) set up dining room/tavern and barracks"
"#query label(services_query_dining) start(18; 18) hidden() message(The tavern is restricted to residents only by default. If you'd like your tavern to attract vistors, please go to the (l)ocation menu and change the restriction.) set up dining room/tavern and barracks"
,`,`,`,,`,`,`,,`,`,`,,`,`,`,,`,,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
@ -2417,7 +2481,7 @@ query_jail/services_query_jail
,`,`,`,`,`,,`,`,`,`,`
,`,`,`,`,`,,`,`,`,`,`
#query label(services_query_rented_rooms) start(18; 18) attach rented rooms to tavern
#query label(services_query_rented_rooms) start(18; 18) hidden() attach rented rooms to tavern
,r&l-&,r&l-&,r&l-&,,r&l-&,r&l-&,r&l-&,,r&l-&,r&l-&,r&l-&,,`,`,`,,`,,`,`,`
,`,`,`,,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
@ -2511,6 +2575,42 @@ query_jail/services_query_jail
,,,,,,,,,,,,,,,`,`,`,`,`
,,,,,,,,,,,,,,,`,`,`,`,`
#dig label(services_traffic) start(18; 18) hidden() promote the tavern as the place to eat
,ol,ol,ol,,ol,ol,ol,,ol,ol,ol,,or,or,or,,or,,or,or,or
,ol,ol,ol,,ol,ol,ol,,ol,ol,ol,,or,or,or,or,or,or,or,or,or
,ol,ol,ol,,ol,ol,ol,,ol,ol,ol,,or,or,or,,or,,or,or,or
,,ol,,,,ol,,,,ol,,,,,,,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,,or,,or,or,or,,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or,,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,,or,,or,or,or,,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,,,,,or,,,,,,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or,,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or,,,,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,or,or,or,or,or,or,or,or,or,,or,,or,,or,,or
,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,ol,,,,,or,,or,,,,,or,,or,,or,,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,,,,oh,oh,oh,oh,oh,,,,or,or,or,or,or,or,or,or,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,`,`,`,oh,oh,oh,oh,oh,oh,oh,oh,oh,or,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,,`,,oh,`,`,`,oh,,`,,oh,oh,oh,`,oh,or,or,or,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,`,`,`,oh,oh,oh,oh,oh,oh,oh,oh,oh,or,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,,,,oh,oh,oh,oh,oh,,,,or,or,or,or,or,or,or,or,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,,,,,,`,,,,,,or,,or,,or,,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,,,,,,,,,,,,or,,or,,or,,or
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh,oh
,,,,oh,oh,,oh,oh
,oh,oh,oh,oh,oh,,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,,oh,oh,oh,oh,oh
,oh,oh,oh,oh,oh,,oh,oh,oh,oh,oh
"#build label(services_build3) start(18; 18) hidden() jail, statues"
,~,~,~,,~,~,~,,~,~,~,,t,l,b,,`,,t,l,b

Can't render this file because it has a wrong number of fields in line 56.

@ -0,0 +1,6 @@
#query label(query)
,,"{givename name=""foo dumper""}"
,,"{givename name=""foo""}"
Can't render this file because it has a wrong number of fields in line 5.

@ -0,0 +1,28 @@
#build label(construct) start(14;14)
,trackNS,trackE,,trackW,trackS,trackN,,,,,,,,,,,,,,trackN,trackS,trackE,,trackW,trackNS
trackEW,,trackSE,,trackSW,trackNE,trackNW,,,,,,,,,,,,,,trackNE,trackNW,trackSE,,trackSW,,trackEW
trackS,trackSE,,,trackNSE,trackNSW,trackEW,,,,,,,,,,,,,,trackEW,trackNSE,trackNSW,,,trackSW,trackS
trackN,trackNE,trackSEW,,,trackSEW,trackNEW,,,,,,,,,,,,,,trackNEW,trackSEW,,,trackSEW,trackNW,trackN
trackE,trackSW,trackNEW,,trackNSE,,trackNSEW,,,,,,,,,,,,,,trackNSEW,,trackNSW,,trackNEW,trackSE,trackW
trackW,trackNW,trackNS,,trackNSW,trackNSEW,,,,,,,,,,,,,,,,trackNSEW,trackNSE,,trackNS,trackNE,trackE
,,,,,,,,,,trackrampNW,trackrampNS,trackrampN,,trackrampN,trackrampNS,trackrampNE
,,,,,,,,,trackrampNW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampNE
,,,,,,,,,trackrampEW,trackrampSEW,,trackrampNSEW,,trackrampNSEW,,trackrampSEW,trackrampEW
,,,,,,,,,trackrampW,trackrampNEW,trackrampNSEW,,,,trackrampNSEW,trackrampNEW,trackrampE
,,,,,,,,,trackrampW,trackrampSEW,trackrampNSEW,,,,trackrampNSEW,trackrampSEW,trackrampE
,,,,,,,,,trackrampEW,trackrampNEW,,trackrampNSEW,,trackrampNSEW,,trackrampNEW,trackrampEW
,,,,,,,,,trackrampSW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampSE
,,,,,,,,,,trackrampSW,trackrampNS,trackrampS,,trackrampS,trackrampNS,trackrampSE
trackW,trackSW,trackNS,,trackNSW,trackNSEW,,,,,,,,,,,,,,,,trackNSEW,trackNSE,,trackNS,trackSE,trackE
trackE,trackNW,trackSEW,,trackNSE,,trackNSEW,,,,,,,,,,,,,,trackNSEW,,trackNSW,,trackSEW,trackNE,trackW
trackS,trackSE,trackNEW,,,trackNEW,trackSEW,,,,,,,,,,,,,,trackSEW,trackNEW,,,trackNEW,trackSW,trackS
trackN,trackNE,,,trackNSE,trackNSW,trackEW,,,,,,,,,,,,,,trackEW,trackNSE,trackNSW,,,trackNW,trackN
trackEW,,trackNE,,trackNW,trackSE,trackSW,,,,,,,,,,,,,,trackSE,trackSW,trackNE,,trackNW,,trackEW
,trackNS,trackE,,trackW,trackN,trackS,,,,,,,,,,,,,,trackS,trackN,trackE,,trackW,trackNS
1 #build label(construct) start(14;14)
2 ,trackNS,trackE,,trackW,trackS,trackN,,,,,,,,,,,,,,trackN,trackS,trackE,,trackW,trackNS
3 trackEW,,trackSE,,trackSW,trackNE,trackNW,,,,,,,,,,,,,,trackNE,trackNW,trackSE,,trackSW,,trackEW
4 trackS,trackSE,,,trackNSE,trackNSW,trackEW,,,,,,,,,,,,,,trackEW,trackNSE,trackNSW,,,trackSW,trackS
5 trackN,trackNE,trackSEW,,,trackSEW,trackNEW,,,,,,,,,,,,,,trackNEW,trackSEW,,,trackSEW,trackNW,trackN
6 trackE,trackSW,trackNEW,,trackNSE,,trackNSEW,,,,,,,,,,,,,,trackNSEW,,trackNSW,,trackNEW,trackSE,trackW
7 trackW,trackNW,trackNS,,trackNSW,trackNSEW,,,,,,,,,,,,,,,,trackNSEW,trackNSE,,trackNS,trackNE,trackE
8 ,,,,,,,,,,trackrampNW,trackrampNS,trackrampN,,trackrampN,trackrampNS,trackrampNE
9 ,,,,,,,,,trackrampNW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampNE
10 ,,,,,,,,,trackrampEW,trackrampSEW,,trackrampNSEW,,trackrampNSEW,,trackrampSEW,trackrampEW
11 ,,,,,,,,,trackrampW,trackrampNEW,trackrampNSEW,,,,trackrampNSEW,trackrampNEW,trackrampE
12 ,,,,,,,,,trackrampW,trackrampSEW,trackrampNSEW,,,,trackrampNSEW,trackrampSEW,trackrampE
13 ,,,,,,,,,trackrampEW,trackrampNEW,,trackrampNSEW,,trackrampNSEW,,trackrampNEW,trackrampEW
14 ,,,,,,,,,trackrampSW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampSE
15 ,,,,,,,,,,trackrampSW,trackrampNS,trackrampS,,trackrampS,trackrampNS,trackrampSE
16 trackW,trackSW,trackNS,,trackNSW,trackNSEW,,,,,,,,,,,,,,,,trackNSEW,trackNSE,,trackNS,trackSE,trackE
17 trackE,trackNW,trackSEW,,trackNSE,,trackNSEW,,,,,,,,,,,,,,trackNSEW,,trackNSW,,trackSEW,trackNE,trackW
18 trackS,trackSE,trackNEW,,,trackNEW,trackSEW,,,,,,,,,,,,,,trackSEW,trackNEW,,,trackNEW,trackSW,trackS
19 trackN,trackNE,,,trackNSE,trackNSW,trackEW,,,,,,,,,,,,,,trackEW,trackNSE,trackNSW,,,trackNW,trackN
20 trackEW,,trackNE,,trackNW,trackSE,trackSW,,,,,,,,,,,,,,trackSE,trackSW,trackNE,,trackNW,,trackEW
21 ,trackNS,trackE,,trackW,trackN,trackS,,,,,,,,,,,,,,trackS,trackN,trackE,,trackW,trackNS

@ -0,0 +1,28 @@
#build label(build) start(14;14)
,~,~,,~,~,~,,gs(1x2),ga(2x1),,gx(1x2),gw(1x2),,gw(1x2),gx(1x2),gd(2x1),,gs(1x2),,~,~,~,,~,~
~,,~,,~,~,~,,,gd(2x1),,,,,,,ga(2x1),,,,~,~,~,,~,,~
~,~,,,~,~,~,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,~,~,~,,,~,~
,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
~,~,~,,,~,~,,CSa,,Mrss(1x2),Mw,,,,Mw,Mrss(1x2),,CSa,,~,~,,,~,~,~
~,~,~,,~,,~,,,Msm,,,Mhs(1x2),,Mhs(1x2),,,Msm,,,~,,~,,~,~,~
~,~,~,,~,~,,,Msu,,Mws,,,,,,Mws,,Msu,,,~,~,,~,~,~
,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
gs(2x1),,Mrqq(1x2),CSddaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSddaaaa,Mrqq(1x2),gs(2x1)
gw(1x2),gx(1x2),,,,Msk,,Mw,,,~,~,~,,~,~,~,,,Mw,,,Msh,,,gx(1x2),gw(1x2)
,,,Msm,Mrs(2x1),,Mw,,,~,,~,~,,~,~,,~,,,Mw,Mrsss(2x1),,Msm
gd(2x1),,Msu,,Mws,,,Mhs(1x2),,~,~,,~,,~,,~,~,,Mhs(1x2),,,Mws,,Msu,ga(2x1)
ga(2x1),,,Mws,,Mh(2x1),,,,~,~,~,,,,~,~,~,,,Mh(2x1),,,Mws,,gd(2x1)
ga(2x1),,,Mws,,Mh(2x1),,Mhs(1x2),,~,~,~,,,,~,~,~,,Mhs(1x2),Mh(2x1),,,Mws,,gd(2x1)
gd(2x1),,,,Mws,,,,,~,~,,~,,~,,~,~,,,,,Mws,,,ga(2x1)
gx(1x2),gw(1x2),Msm,,Mrs(2x1),,Mw,,,~,,~,~,,~,~,,~,,,Mw,Mrsss(2x1),,,Msm,gw(1x2),gx(1x2)
,,Mrssqq(1x2),Msu,,Msk,,Mw,,,~,~,~,,~,~,~,,,Mw,,,Msh,Msu,Mrssqq(1x2)
gs(2x1),,,CSdaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSdaaaa,,gs(2x1)
,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
~,~,~,,~,~,,,,,Mws,,Mhs(1x2),,Mhs(1x2),,Mws,,,,,~,~,,~,~,~
~,~,~,,~,,~,,Msm,,Mr(1x2),,,,,,Mr(1x2),,Msm,,~,,~,,~,~,~
~,~,~,,,~,~,,CSa,Msu,,Mw,,,,Mw,,Msu,CSa,,~,~,,,~,~,~
,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
~,~,,,~,~,~,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,~,~,~,,,~,~
~,,~,,~,~,~,,gs(1x2),gd(2x1),,gw(1x2),gx(1x2),,gx(1x2),gw(1x2),ga(2x1),,gs(1x2),,~,~,~,,~,,~
,~,~,,~,~,~,,,ga(2x1),,,,,,,gd(2x1),,,,~,~,~,,~,~
1 #build label(build) start(14;14)
2 ,~,~,,~,~,~,,gs(1x2),ga(2x1),,gx(1x2),gw(1x2),,gw(1x2),gx(1x2),gd(2x1),,gs(1x2),,~,~,~,,~,~
3 ~,,~,,~,~,~,,,gd(2x1),,,,,,,ga(2x1),,,,~,~,~,,~,,~
4 ~,~,,,~,~,~,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,~,~,~,,,~,~
5 ,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
6 ~,~,~,,,~,~,,CSa,,Mrss(1x2),Mw,,,,Mw,Mrss(1x2),,CSa,,~,~,,,~,~,~
7 ~,~,~,,~,,~,,,Msm,,,Mhs(1x2),,Mhs(1x2),,,Msm,,,~,,~,,~,~,~
8 ~,~,~,,~,~,,,Msu,,Mws,,,,,,Mws,,Msu,,,~,~,,~,~,~
9 ,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
10 gs(2x1),,Mrqq(1x2),CSddaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSddaaaa,Mrqq(1x2),gs(2x1)
11 gw(1x2),gx(1x2),,,,Msk,,Mw,,,~,~,~,,~,~,~,,,Mw,,,Msh,,,gx(1x2),gw(1x2)
12 ,,,Msm,Mrs(2x1),,Mw,,,~,,~,~,,~,~,,~,,,Mw,Mrsss(2x1),,Msm
13 gd(2x1),,Msu,,Mws,,,Mhs(1x2),,~,~,,~,,~,,~,~,,Mhs(1x2),,,Mws,,Msu,ga(2x1)
14 ga(2x1),,,Mws,,Mh(2x1),,,,~,~,~,,,,~,~,~,,,Mh(2x1),,,Mws,,gd(2x1)
15 ga(2x1),,,Mws,,Mh(2x1),,Mhs(1x2),,~,~,~,,,,~,~,~,,Mhs(1x2),Mh(2x1),,,Mws,,gd(2x1)
16 gd(2x1),,,,Mws,,,,,~,~,,~,,~,,~,~,,,,,Mws,,,ga(2x1)
17 gx(1x2),gw(1x2),Msm,,Mrs(2x1),,Mw,,,~,,~,~,,~,~,,~,,,Mw,Mrsss(2x1),,,Msm,gw(1x2),gx(1x2)
18 ,,Mrssqq(1x2),Msu,,Msk,,Mw,,,~,~,~,,~,~,~,,,Mw,,,Msh,Msu,Mrssqq(1x2)
19 gs(2x1),,,CSdaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSdaaaa,,gs(2x1)
20 ,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
21 ~,~,~,,~,~,,,,,Mws,,Mhs(1x2),,Mhs(1x2),,Mws,,,,,~,~,,~,~,~
22 ~,~,~,,~,,~,,Msm,,Mr(1x2),,,,,,Mr(1x2),,Msm,,~,,~,,~,~,~
23 ~,~,~,,,~,~,,CSa,Msu,,Mw,,,,Mw,,Msu,CSa,,~,~,,,~,~,~
24 ,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
25 ~,~,,,~,~,~,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,~,~,~,,,~,~
26 ~,,~,,~,~,~,,gs(1x2),gd(2x1),,gw(1x2),gx(1x2),,gx(1x2),gw(1x2),ga(2x1),,gs(1x2),,~,~,~,,~,,~
27 ,~,~,,~,~,~,,,ga(2x1),,,,,,,gd(2x1),,,,~,~,~,,~,~

@ -1,28 +0,0 @@
#build label(build) start(14;14)
,trackNS,trackE,,trackW,trackS,trackN,,gs(1x2),ga(2x1),,gx(1x2),gw(1x2),,gw(1x2),gx(1x2),gd(2x1),,gs(1x2),,trackN,trackS,trackE,,trackW,trackNS
trackEW,,trackSE,,trackSW,trackNE,trackNW,,,gd(2x1),,,,,,,ga(2x1),,,,trackNE,trackNW,trackSE,,trackSW,,trackEW
trackS,trackSE,,,trackNSE,trackNSW,trackEW,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,trackEW,trackNSE,trackNSW,,,trackSW,trackS
,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
trackN,trackNE,trackSEW,,,trackSEW,trackNEW,,CSa,,Mrss(1x2),Mw,,,,Mw,Mrss(1x2),,CSa,,trackNEW,trackSEW,,,trackSEW,trackNW,trackN
trackE,trackSW,trackNEW,,trackNSE,,trackNSEW,,,Msm,,,Mhs(1x2),,Mhs(1x2),,,Msm,,,trackNSEW,,trackNSW,,trackNEW,trackSE,trackW
trackW,trackNW,trackNS,,trackNSW,trackNSEW,,,Msu,,Mws,,,,,,Mws,,Msu,,,trackNSEW,trackNSE,,trackNS,trackNE,trackE
,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
gs(2x1),,Mrqq(1x2),CSddaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSddaaaa,Mrqq(1x2),gs(2x1)
gw(1x2),gx(1x2),,,,Msk,,Mw,,,trackrampNW,trackrampNS,trackrampN,,trackrampN,trackrampNS,trackrampNE,,,Mw,,,Msh,,,gx(1x2),gw(1x2)
,,,Msm,Mrs(2x1),,Mw,,,trackrampNW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampNE,,,Mw,Mrsss(2x1),,Msm
gd(2x1),,Msu,,Mws,,,Mhs(1x2),,trackrampEW,trackrampSEW,,trackrampNSEW,,trackrampNSEW,,trackrampSEW,trackrampEW,,Mhs(1x2),,,Mws,,Msu,ga(2x1)
ga(2x1),,,Mws,,Mh(2x1),,,,trackrampW,trackrampNEW,trackrampNSEW,,,,trackrampNSEW,trackrampNEW,trackrampE,,,Mh(2x1),,,Mws,,gd(2x1)
ga(2x1),,,Mws,,Mh(2x1),,Mhs(1x2),,trackrampW,trackrampSEW,trackrampNSEW,,,,trackrampNSEW,trackrampSEW,trackrampE,,Mhs(1x2),Mh(2x1),,,Mws,,gd(2x1)
gd(2x1),,,,Mws,,,,,trackrampEW,trackrampNEW,,trackrampNSEW,,trackrampNSEW,,trackrampNEW,trackrampEW,,,,,Mws,,,ga(2x1)
gx(1x2),gw(1x2),Msm,,Mrs(2x1),,Mw,,,trackrampSW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampSE,,,Mw,Mrsss(2x1),,,Msm,gw(1x2),gx(1x2)
,,Mrssqq(1x2),Msu,,Msk,,Mw,,,trackrampSW,trackrampNS,trackrampS,,trackrampS,trackrampNS,trackrampSE,,,Mw,,,Msh,Msu,Mrssqq(1x2)
gs(2x1),,,CSdaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSdaaaa,,gs(2x1)
,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
trackW,trackSW,trackNS,,trackNSW,trackNSEW,,,,,Mws,,Mhs(1x2),,Mhs(1x2),,Mws,,,,,trackNSEW,trackNSE,,trackNS,trackSE,trackE
trackE,trackNW,trackSEW,,trackNSE,,trackNSEW,,Msm,,Mr(1x2),,,,,,Mr(1x2),,Msm,,trackNSEW,,trackNSW,,trackSEW,trackNE,trackW
trackS,trackSE,trackNEW,,,trackNEW,trackSEW,,CSa,Msu,,Mw,,,,Mw,,Msu,CSa,,trackSEW,trackNEW,,,trackNEW,trackSW,trackS
,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
trackN,trackNE,,,trackNSE,trackNSW,trackEW,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,trackEW,trackNSE,trackNSW,,,trackNW,trackN
trackEW,,trackNE,,trackNW,trackSE,trackSW,,gs(1x2),gd(2x1),,gw(1x2),gx(1x2),,gx(1x2),gw(1x2),ga(2x1),,gs(1x2),,trackSE,trackSW,trackNE,,trackNW,,trackEW
,trackNS,trackE,,trackW,trackN,trackS,,,ga(2x1),,,,,,,gd(2x1),,,,trackS,trackN,trackE,,trackW,trackNS
1 #build label(build) start(14;14)
2 ,trackNS,trackE,,trackW,trackS,trackN,,gs(1x2),ga(2x1),,gx(1x2),gw(1x2),,gw(1x2),gx(1x2),gd(2x1),,gs(1x2),,trackN,trackS,trackE,,trackW,trackNS
3 trackEW,,trackSE,,trackSW,trackNE,trackNW,,,gd(2x1),,,,,,,ga(2x1),,,,trackNE,trackNW,trackSE,,trackSW,,trackEW
4 trackS,trackSE,,,trackNSE,trackNSW,trackEW,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,trackEW,trackNSE,trackNSW,,,trackSW,trackS
5 ,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
6 trackN,trackNE,trackSEW,,,trackSEW,trackNEW,,CSa,,Mrss(1x2),Mw,,,,Mw,Mrss(1x2),,CSa,,trackNEW,trackSEW,,,trackSEW,trackNW,trackN
7 trackE,trackSW,trackNEW,,trackNSE,,trackNSEW,,,Msm,,,Mhs(1x2),,Mhs(1x2),,,Msm,,,trackNSEW,,trackNSW,,trackNEW,trackSE,trackW
8 trackW,trackNW,trackNS,,trackNSW,trackNSEW,,,Msu,,Mws,,,,,,Mws,,Msu,,,trackNSEW,trackNSE,,trackNS,trackNE,trackE
9 ,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
10 gs(2x1),,Mrqq(1x2),CSddaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSddaaaa,Mrqq(1x2),gs(2x1)
11 gw(1x2),gx(1x2),,,,Msk,,Mw,,,trackrampNW,trackrampNS,trackrampN,,trackrampN,trackrampNS,trackrampNE,,,Mw,,,Msh,,,gx(1x2),gw(1x2)
12 ,,,Msm,Mrs(2x1),,Mw,,,trackrampNW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampNE,,,Mw,Mrsss(2x1),,Msm
13 gd(2x1),,Msu,,Mws,,,Mhs(1x2),,trackrampEW,trackrampSEW,,trackrampNSEW,,trackrampNSEW,,trackrampSEW,trackrampEW,,Mhs(1x2),,,Mws,,Msu,ga(2x1)
14 ga(2x1),,,Mws,,Mh(2x1),,,,trackrampW,trackrampNEW,trackrampNSEW,,,,trackrampNSEW,trackrampNEW,trackrampE,,,Mh(2x1),,,Mws,,gd(2x1)
15 ga(2x1),,,Mws,,Mh(2x1),,Mhs(1x2),,trackrampW,trackrampSEW,trackrampNSEW,,,,trackrampNSEW,trackrampSEW,trackrampE,,Mhs(1x2),Mh(2x1),,,Mws,,gd(2x1)
16 gd(2x1),,,,Mws,,,,,trackrampEW,trackrampNEW,,trackrampNSEW,,trackrampNSEW,,trackrampNEW,trackrampEW,,,,,Mws,,,ga(2x1)
17 gx(1x2),gw(1x2),Msm,,Mrs(2x1),,Mw,,,trackrampSW,,trackrampNSE,trackrampNSW,,trackrampNSE,trackrampNSW,,trackrampSE,,,Mw,Mrsss(2x1),,,Msm,gw(1x2),gx(1x2)
18 ,,Mrssqq(1x2),Msu,,Msk,,Mw,,,trackrampSW,trackrampNS,trackrampS,,trackrampS,trackrampNS,trackrampSE,,,Mw,,,Msh,Msu,Mrssqq(1x2)
19 gs(2x1),,,CSdaaaa,CSa,,Msh,,,,,,,,,,,,,,,Msk,CSa,CSdaaaa,,gs(2x1)
20 ,,,,,,,,,Mws,,Mh(2x1),,,Mh(2x1),,,Mws
21 trackW,trackSW,trackNS,,trackNSW,trackNSEW,,,,,Mws,,Mhs(1x2),,Mhs(1x2),,Mws,,,,,trackNSEW,trackNSE,,trackNS,trackSE,trackE
22 trackE,trackNW,trackSEW,,trackNSE,,trackNSEW,,Msm,,Mr(1x2),,,,,,Mr(1x2),,Msm,,trackNSEW,,trackNSW,,trackSEW,trackNE,trackW
23 trackS,trackSE,trackNEW,,,trackNEW,trackSEW,,CSa,Msu,,Mw,,,,Mw,,Msu,CSa,,trackSEW,trackNEW,,,trackNEW,trackSW,trackS
24 ,,,,,,,,CSdddaaaa,,Msk,,Mw,,Mw,,,Msh,CSddddaaaa
25 trackN,trackNE,,,trackNSE,trackNSW,trackEW,,Mrsssqq(2x1),,,Msh,,,,,Msk,Mrsqq(2x1),,,trackEW,trackNSE,trackNSW,,,trackNW,trackN
26 trackEW,,trackNE,,trackNW,trackSE,trackSW,,gs(1x2),gd(2x1),,gw(1x2),gx(1x2),,gx(1x2),gw(1x2),ga(2x1),,gs(1x2),,trackSE,trackSW,trackNE,,trackNW,,trackEW
27 ,trackNS,trackE,,trackW,trackN,trackS,,,ga(2x1),,,,,,,gd(2x1),,,,trackS,trackN,trackE,,trackW,trackNS

@ -0,0 +1,21 @@
#build label(construct)
Cw
Cf
Cr
Cu
Cd
Cx
CF
1 #build label(construct)
2 Cw
3 Cf
4 Cr
5 Cu
6 Cd
7 Cx
8 CF

@ -0,0 +1,33 @@
#build label(build)
a,Mg,,CS
b,Mh(1x1),S,CSa,,,,,,Mw,,,wm,,,wp
c,Mhs(1x1),m,CSaa,,,,,,,,,,,,,,,,,D
n,Mv,v,CSaaa,,Msu
,Mr(1x1),j,CSaaaa,,,,,,Mws,,,wu,,,ew
d,Mrq(1x1),A,CSd,,,Msk
,Mrqq(1x1),R,CSda
l,Mrqqq(1x1),N,CSdaa,,Msm,,,,we,,,wn,,,es,,,,,k
x,Mrqqqq(1x1),~h,CSdaaa
H,Mrs(1x1),~a,CSdaaaa,,,Msh
W,Mrsq(1x1),~c,CSdd,,,,,,wq,,,wr,,,el
G,Mrsqq(1x1),F,CSdda
B,Mrsqqq(1x1),o(1x1),CSddaa,,,,,,,,,,,,,,,,,ws
~,~b,Mrsqqqq(1x1),CSddaaa,,,,,,wM,,,wt,,,eg
~,f,Mrss(1x1),CSddaaaa
~,h,Mrssq(1x1),CSddd
~,r,Mrssqq(1x1),CSddda,,,,,,wo,,,wl,,,ea,,,,gx(1x2),gx(1x2)
~,s,Mrssqqq(1x1),CSdddaa
~,~s,Mrssqqqq(1x1),CSdddaaa,,,,,,,,,,,,,,gd(2x1),,gs(2x1),,ga(2x1)
~,t,Mrsss(1x1),CSdddaaaa,,,,,,wk,,,ww,,,ek,,gd(2x1),,gs(2x1),,ga(2x1)
gs(1x1),Mrsssq(1x1),,CSdddd,,,,,,,,,,,,,,,,gw(1x2),gw(1x2)
ga(1x1),Mrsssqq(1x1),,CSdddda
gd(1x1),Mrsssqqq(1x1),,CSddddaa,,,,,,wb,,,wz,,,en
gw(1x1),Mrsssqqqq(1x1),,CSddddaaa,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1),,Mhs(1x2),Mhs(1x2)
gx(1x1),,,CSddddaaaa,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1)
,,,Ts,,,,,,wc,,,wh,,,ib,,Mr(1x2),Mr(1x2),Mrs(2x1),,Mhs(1x2),Mhs(1x2)
y,,,Tw,,,,,,,,,,,,,,,,Mrs(2x1)
Y,,,Tl,,,,,,,,,,,,,,Mr(1x2),Mr(1x2),Mrsq(2x1),,Mrsq(2x1)
,,,Tp,,,,,,wf,,,wy,,,ic,,,,Mrsssqqqq(2x1),,Mrsssqqqq(2x1)
,,,Tc
,,,TS
,,,,,,,,,,wv,,,wd,,,wj,,,wS
1 #build label(build)
2 a,Mg,,CS
3 b,Mh(1x1),S,CSa,,,,,,Mw,,,wm,,,wp
4 c,Mhs(1x1),m,CSaa,,,,,,,,,,,,,,,,,D
5 n,Mv,v,CSaaa,,Msu
6 ,Mr(1x1),j,CSaaaa,,,,,,Mws,,,wu,,,ew
7 d,Mrq(1x1),A,CSd,,,Msk
8 ,Mrqq(1x1),R,CSda
9 l,Mrqqq(1x1),N,CSdaa,,Msm,,,,we,,,wn,,,es,,,,,k
10 x,Mrqqqq(1x1),~h,CSdaaa
11 H,Mrs(1x1),~a,CSdaaaa,,,Msh
12 W,Mrsq(1x1),~c,CSdd,,,,,,wq,,,wr,,,el
13 G,Mrsqq(1x1),F,CSdda
14 B,Mrsqqq(1x1),o(1x1),CSddaa,,,,,,,,,,,,,,,,,ws
15 ~,~b,Mrsqqqq(1x1),CSddaaa,,,,,,wM,,,wt,,,eg
16 ~,f,Mrss(1x1),CSddaaaa
17 ~,h,Mrssq(1x1),CSddd
18 ~,r,Mrssqq(1x1),CSddda,,,,,,wo,,,wl,,,ea,,,,gx(1x2),gx(1x2)
19 ~,s,Mrssqqq(1x1),CSdddaa
20 ~,~s,Mrssqqqq(1x1),CSdddaaa,,,,,,,,,,,,,,gd(2x1),,gs(2x1),,ga(2x1)
21 ~,t,Mrsss(1x1),CSdddaaaa,,,,,,wk,,,ww,,,ek,,gd(2x1),,gs(2x1),,ga(2x1)
22 gs(1x1),Mrsssq(1x1),,CSdddd,,,,,,,,,,,,,,,,gw(1x2),gw(1x2)
23 ga(1x1),Mrsssqq(1x1),,CSdddda
24 gd(1x1),Mrsssqqq(1x1),,CSddddaa,,,,,,wb,,,wz,,,en
25 gw(1x1),Mrsssqqqq(1x1),,CSddddaaa,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1),,Mhs(1x2),Mhs(1x2)
26 gx(1x1),,,CSddddaaaa,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1)
27 ,,,Ts,,,,,,wc,,,wh,,,ib,,Mr(1x2),Mr(1x2),Mrs(2x1),,Mhs(1x2),Mhs(1x2)
28 y,,,Tw,,,,,,,,,,,,,,,,Mrs(2x1)
29 Y,,,Tl,,,,,,,,,,,,,,Mr(1x2),Mr(1x2),Mrsq(2x1),,Mrsq(2x1)
30 ,,,Tp,,,,,,wf,,,wy,,,ic,,,,Mrsssqqqq(2x1),,Mrsssqqqq(2x1)
31 ,,,Tc
32 ,,,TS
33 ,,,,,,,,,,wv,,,wd,,,wj,,,wS

@ -1,33 +0,0 @@
#build label(build)
a,Mg,,CS,trackN
b,Mh(1x1),S,CSa,trackS,,,,,,Mw,,,wm,,,wp
c,Mhs(1x1),m,CSaa,trackE,,,,,,,,,,,,,,,,,D
n,Mv,v,CSaaa,trackW,,Msu
,Mr(1x1),j,CSaaaa,trackNS,,,,,,Mws,,,wu,,,ew
d,Mrq(1x1),A,CSd,trackNE,,,Msk
,Mrqq(1x1),R,CSda,trackNW
l,Mrqqq(1x1),N,CSdaa,trackSE,,Msm,,,,we,,,wn,,,es,,,,,k
x,Mrqqqq(1x1),~h,CSdaaa,trackSW
H,Mrs(1x1),~a,CSdaaaa,trackEW,,,Msh
W,Mrsq(1x1),~c,CSdd,trackNSE,,,,,,wq,,,wr,,,el
G,Mrsqq(1x1),F,CSdda,trackNSW
B,Mrsqqq(1x1),o(1x1),CSddaa,trackNEW,,,,,,,,,,,,,,,,,ws
~b,Mrsqqqq(1x1),Cw,CSddaaa,trackSEW,,,,,,wM,,,wt,,,eg
f,Mrss(1x1),Cf,CSddaaaa,trackNSEW
h,Mrssq(1x1),Cr,CSddd,trackrampN
r,Mrssqq(1x1),Cu,CSddda,trackrampS,,,,,,wo,,,wl,,,ea,,,,gx(1x2),gx(1x2)
s,Mrssqqq(1x1),Cd,CSdddaa,trackrampE
~s,Mrssqqqq(1x1),Cx,CSdddaaa,trackrampW,,,,,,,,,,,,,,gd(2x1),,gs(2x1),,ga(2x1)
t,Mrsss(1x1),CF,CSdddaaaa,trackrampNS,,,,,,wk,,,ww,,,ek,,gd(2x1),,gs(2x1),,ga(2x1)
gs(1x1),Mrsssq(1x1),,CSdddd,trackrampNE,,,,,,,,,,,,,,,,gw(1x2),gw(1x2)
ga(1x1),Mrsssqq(1x1),,CSdddda,trackrampNW
gd(1x1),Mrsssqqq(1x1),,CSddddaa,trackrampSE,,,,,,wb,,,wz,,,en
gw(1x1),Mrsssqqqq(1x1),,CSddddaaa,trackrampSW,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1),,Mhs(1x2),Mhs(1x2)
gx(1x1),,,CSddddaaaa,trackrampEW,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1)
,,,Ts,trackrampNSE,,,,,,wc,,,wh,,,ib,,Mr(1x2),Mr(1x2),Mrs(2x1),,Mhs(1x2),Mhs(1x2)
y,,,Tw,trackrampNSW,,,,,,,,,,,,,,,,Mrs(2x1)
Y,,,Tl,trackrampNEW,,,,,,,,,,,,,,Mr(1x2),Mr(1x2),Mrsq(2x1),,Mrsq(2x1)
,,,Tp,trackrampSEW,,,,,,wf,,,wy,,,ic,,,,Mrsssqqqq(2x1),,Mrsssqqqq(2x1)
,,,Tc,trackrampNSEW
,,,TS
,,,,,,,,,,wv,,,wd,,,wj,,,wS
1 #build label(build)
2 a,Mg,,CS,trackN
3 b,Mh(1x1),S,CSa,trackS,,,,,,Mw,,,wm,,,wp
4 c,Mhs(1x1),m,CSaa,trackE,,,,,,,,,,,,,,,,,D
5 n,Mv,v,CSaaa,trackW,,Msu
6 ,Mr(1x1),j,CSaaaa,trackNS,,,,,,Mws,,,wu,,,ew
7 d,Mrq(1x1),A,CSd,trackNE,,,Msk
8 ,Mrqq(1x1),R,CSda,trackNW
9 l,Mrqqq(1x1),N,CSdaa,trackSE,,Msm,,,,we,,,wn,,,es,,,,,k
10 x,Mrqqqq(1x1),~h,CSdaaa,trackSW
11 H,Mrs(1x1),~a,CSdaaaa,trackEW,,,Msh
12 W,Mrsq(1x1),~c,CSdd,trackNSE,,,,,,wq,,,wr,,,el
13 G,Mrsqq(1x1),F,CSdda,trackNSW
14 B,Mrsqqq(1x1),o(1x1),CSddaa,trackNEW,,,,,,,,,,,,,,,,,ws
15 ~b,Mrsqqqq(1x1),Cw,CSddaaa,trackSEW,,,,,,wM,,,wt,,,eg
16 f,Mrss(1x1),Cf,CSddaaaa,trackNSEW
17 h,Mrssq(1x1),Cr,CSddd,trackrampN
18 r,Mrssqq(1x1),Cu,CSddda,trackrampS,,,,,,wo,,,wl,,,ea,,,,gx(1x2),gx(1x2)
19 s,Mrssqqq(1x1),Cd,CSdddaa,trackrampE
20 ~s,Mrssqqqq(1x1),Cx,CSdddaaa,trackrampW,,,,,,,,,,,,,,gd(2x1),,gs(2x1),,ga(2x1)
21 t,Mrsss(1x1),CF,CSdddaaaa,trackrampNS,,,,,,wk,,,ww,,,ek,,gd(2x1),,gs(2x1),,ga(2x1)
22 gs(1x1),Mrsssq(1x1),,CSdddd,trackrampNE,,,,,,,,,,,,,,,,gw(1x2),gw(1x2)
23 ga(1x1),Mrsssqq(1x1),,CSdddda,trackrampNW
24 gd(1x1),Mrsssqqq(1x1),,CSddddaa,trackrampSE,,,,,,wb,,,wz,,,en
25 gw(1x1),Mrsssqqqq(1x1),,CSddddaaa,trackrampSW,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1),,Mhs(1x2),Mhs(1x2)
26 gx(1x1),,,CSddddaaaa,trackrampEW,,,,,,,,,,,,,,Mh(2x1),,Mh(2x1)
27 ,,,Ts,trackrampNSE,,,,,,wc,,,wh,,,ib,,Mr(1x2),Mr(1x2),Mrs(2x1),,Mhs(1x2),Mhs(1x2)
28 y,,,Tw,trackrampNSW,,,,,,,,,,,,,,,,Mrs(2x1)
29 Y,,,Tl,trackrampNEW,,,,,,,,,,,,,,Mr(1x2),Mr(1x2),Mrsq(2x1),,Mrsq(2x1)
30 ,,,Tp,trackrampSEW,,,,,,wf,,,wy,,,ic,,,,Mrsssqqqq(2x1),,Mrsssqqqq(2x1)
31 ,,,Tc,trackrampNSEW
32 ,,,TS
33 ,,,,,,,,,,wv,,,wd,,,wj,,,wS

@ -1,12 +1,3 @@
#build label(big) hidden()
gw(1x2),gx(1x2),gd(2x1),,gs(1x2)
,,ga(2x1)
,,Msk,Mrsqq(2x1)
Mw,,,Msh,CSddddaaaa
,Mw,Mrss(1x2),,CSa
Mhs(1x2),,,Msm
,,Mws,,Msu
Mh(2x1),,,Mws
#build label(outer) hidden()
trackN,trackS,trackE,,trackW,trackNS
trackNE,trackNW,trackSE,,trackSW
@ -19,10 +10,9 @@ trackrampN,trackrampNS,trackrampNE
trackrampNSE,trackrampNSW
trackrampNSEW
#meta label(chunk) hidden()
/big shift(1 -13)
/outer shift(7 -13)
/inner shift(1 -4)
#meta label(build)
#meta label(construct)
/chunk
/chunk transform(cw)
/chunk transform(cw cw)
1 #build label(big) hidden() #build label(outer) hidden()
#build label(big) hidden()
gw(1x2),gx(1x2),gd(2x1),,gs(1x2)
,,ga(2x1)
,,Msk,Mrsqq(2x1)
Mw,,,Msh,CSddddaaaa
,Mw,Mrss(1x2),,CSa
Mhs(1x2),,,Msm
,,Mws,,Msu
Mh(2x1),,,Mws
1 #build label(outer) hidden() #build label(outer) hidden()
2 trackN,trackS,trackE,,trackW,trackNS trackN,trackS,trackE,,trackW,trackNS
3 trackNE,trackNW,trackSE,,trackSW trackNE,trackNW,trackSE,,trackSW
10 trackrampNSEW trackrampNSEW
11 #meta label(chunk) hidden() #meta label(chunk) hidden()
12 /big shift(1 -13) /outer shift(7 -13)
/outer shift(7 -13)
13 /inner shift(1 -4) /inner shift(1 -4)
14 #meta label(build) #meta label(construct)
15 /chunk /chunk
16 /chunk transform(cw) /chunk transform(cw)
17 /chunk transform(cw cw) /chunk transform(cw cw)
18 /chunk transform(ccw) /chunk transform(ccw)

@ -0,0 +1,20 @@
#build label(big) hidden()
gw(1x2),gx(1x2),gd(2x1),,gs(1x2)
,,ga(2x1)
,,Msk,Mrsqq(2x1)
Mw,,,Msh,CSddddaaaa
,Mw,Mrss(1x2),,CSa
Mhs(1x2),,,Msm
,,Mws,,Msu
Mh(2x1),,,Mws
#meta label(chunk) hidden()
/big shift(1 -13)
#meta label(build)
/chunk
/chunk transform(cw)
/chunk transform(cw cw)
/chunk transform(ccw)
/chunk transform(fliph)
/chunk transform(flipv)
/chunk transform(cw flipv)
/chunk transform(ccw flipv)
1 #build label(big) hidden()
2 gw(1x2),gx(1x2),gd(2x1),,gs(1x2)
3 ,,ga(2x1)
4 ,,Msk,Mrsqq(2x1)
5 Mw,,,Msh,CSddddaaaa
6 ,Mw,Mrss(1x2),,CSa
7 Mhs(1x2),,,Msm
8 ,,Mws,,Msu
9 Mh(2x1),,,Mws
10 #meta label(chunk) hidden()
11 /big shift(1 -13)
12 #meta label(build)
13 /chunk
14 /chunk transform(cw)
15 /chunk transform(cw cw)
16 /chunk transform(ccw)
17 /chunk transform(fliph)
18 /chunk transform(flipv)
19 /chunk transform(cw flipv)
20 /chunk transform(ccw flipv)

@ -1,6 +1,7 @@
# This dfhack config file automates common tasks for your forts.
# It was written for the Dreamfort set of quickfort blueprints, but the
# configuration here is useful for any fort! Feed free to edit or override
# configuration here is useful for any fort! Copy this file to your
# dfhack-config/init directory to use. Feed free to edit or override
# to your liking.
# Uncomment this next line if you want buildingplan (and quickfort) to use only
@ -37,27 +38,18 @@ enable automelt
# creates manager orders to produce replacements for worn clothing
enable tailor
tailor enable
# auto-assigns nesting birds to nestbox zones and protects fertile eggs from
# being cooked/eaten
enable zone nestboxes
autonestbox start
enable zone autonestbox nestboxes
# manages seed stocks
enable seedwatch
seedwatch all 30
seedwatch start
# ensures important tasks get assigned to workers.
# otherwise these job types can get ignored in busy forts.
prioritize -a StoreItemInVehicle StoreItemInBag StoreItemInBarrel PullLever
prioritize -a StoreItemInLocation StoreItemInHospital
prioritize -a DestroyBuilding RemoveConstruction RecoverWounded DumpItem
prioritize -a CleanSelf SlaughterAnimal PrepareRawFish ExtractFromRawFish
prioritize -a TradeAtDepot BringItemToDepot CleanTrap ManageWorkOrders
prioritize -a --haul-labor=Food,Body StoreItemInStockpile
prioritize -a --reaction-name=TAN_A_HIDE CustomReaction
prioritize -aq defaults
# autobutcher settings are saved in the savegame, so we only need to set them once.
# this way, any custom settings you set during gameplay are not overwritten
@ -65,6 +57,7 @@ prioritize -a --reaction-name=TAN_A_HIDE CustomReaction
# feel free to change this to "target 0 0 0 0" if you don't expect to want to raise
# any animals not listed here -- you can always change it anytime during the game
# later if you change your mind.
on-new-fortress enable autobutcher
on-new-fortress autobutcher target 2 2 2 2 new
# dogs and cats. You should raise the limits for dogs if you will be training them
# for hunting or war.
@ -80,7 +73,7 @@ on-new-fortress autobutcher target 50 50 14 2 BIRD_GOOSE
on-new-fortress autobutcher target 2 2 4 2 ALPACA SHEEP LLAMA
# pigs give milk and meat and are zero-maintenance.
on-new-fortress autobutcher target 5 5 6 2 PIG
# butcher all unprofitable animals
# immediately butcher all unprofitable animals
on-new-fortress autobutcher target 0 0 0 0 HORSE YAK DONKEY WATER_BUFFALO GOAT CAVY BIRD_DUCK BIRD_GUINEAFOWL
# start it up!
on-new-fortress autobutcher start; autobutcher watch all; autobutcher autowatch
# watch for new animals
on-new-fortress autobutcher autowatch

@ -0,0 +1,8 @@
# Default DFHack commands to run on program init
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/dfhack.init
script hack/init/dfhack.keybindings.init
script hack/init/dfhack.tools.init

@ -0,0 +1,176 @@
# Default DFHack keybindings
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/dfhack.init
###################
# global bindings #
###################
# the GUI command launcher (two bindings since some keyboards don't have `)
keybinding add ` gui/launcher
keybinding add Ctrl-Shift-D gui/launcher
# show hotkey popup menu
keybinding add Ctrl-Shift-C hotkeys
# a dfhack prompt in df. Sublime text like.
keybinding add Ctrl-Shift-P command-prompt
# on-screen keyboard
keybinding add Ctrl-Shift-K gui/cp437-table
# an in-game init file editor
keybinding add Alt-S@title|dwarfmode/Default|dungeonmode gui/settings-manager
######################
# dwarfmode bindings #
######################
# quicksave, only in main dwarfmode screen and menu page
keybinding add Ctrl-Alt-S@dwarfmode/Default quicksave
# toggle the display of water level as 1-7 tiles
keybinding add Ctrl-W@dwarfmode|dungeonmode twaterlvl
# designate the whole vein for digging
keybinding add Ctrl-V@dwarfmode digv
keybinding add Ctrl-Shift-V@dwarfmode "digv x"
# clean the selected tile of blood etc
keybinding add Ctrl-C spotclean
# destroy the selected item
keybinding add Ctrl-K@dwarfmode autodump-destroy-item
# destroy items designated for dump in the selected tile
keybinding add Ctrl-Shift-K@dwarfmode autodump-destroy-here
# apply blueprints to the map (Alt-F for compatibility with LNP Quickfort)
keybinding add Ctrl-Shift-Q@dwarfmode gui/quickfort
keybinding add Alt-F@dwarfmode gui/quickfort
# show information collected by dwarfmonitor
keybinding add Alt-M@dwarfmode/Default "dwarfmonitor prefs"
keybinding add Ctrl-F@dwarfmode/Default "dwarfmonitor stats"
# set the zone or cage under the cursor as the default
keybinding add Alt-Shift-I@dwarfmode/Zones "zone set"
# Stocks plugin
keybinding add Ctrl-Shift-Z@dwarfmode/Default "stocks show"
# open an overview window summarising some stocks (dfstatus)
keybinding add Ctrl-Shift-I@dwarfmode/Default|dfhack/lua/dfstatus gui/dfstatus
# change quantity of manager orders
keybinding add Alt-Q@jobmanagement/Main gui/manager-quantity
# re-check manager orders
keybinding add Alt-R@jobmanagement/Main workorder-recheck
# set workorder item details (on workorder details screen press D again)
keybinding add D@workquota_details gui/workorder-details
# view combat reports for the selected unit/corpse/spatter
keybinding add Ctrl-Shift-R@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist|workshop_profile view-unit-reports
# view extra unit information
keybinding add Alt-I@dwarfmode/ViewUnits|unitlist gui/unit-info-viewer
# boost priority of jobs related to the selected entity
keybinding add Alt-N@dwarfmode|job|joblist|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist|textviewer|item|layer_assigntrade|tradegoods|store|assign_display_item|treasurelist do-job-now
# export a Dwarf's preferences screen in BBCode to post to a forum
keybinding add Ctrl-Shift-F@textviewer forum-dwarves
# q->stockpile - copy & paste stockpiles
keybinding add Alt-P@dwarfmode/QueryBuilding/Some/Stockpile copystock
# q->stockpile - load and save stockpile settings out of game
keybinding add Alt-L@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -load"
keybinding add Alt-S@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -save"
# q->workshop - duplicate the selected job
keybinding add Ctrl-D job-duplicate
# materials: q->workshop; b->select items
keybinding add Shift-A "job-material ALUNITE"
keybinding add Shift-M "job-material MICROCLINE"
keybinding add Shift-D "job-material DACITE"
keybinding add Shift-R "job-material RHYOLITE"
keybinding add Shift-I "job-material CINNABAR"
keybinding add Shift-B "job-material COBALTITE"
keybinding add Shift-O "job-material OBSIDIAN"
keybinding add Shift-T "job-material ORTHOCLASE"
keybinding add Shift-G "job-material GLASS_GREEN"
# sort units and items in the on-screen list
keybinding add Alt-Shift-N "sort-units name" "sort-items description"
keybinding add Alt-Shift-R "sort-units arrival"
keybinding add Alt-Shift-T "sort-units profession" "sort-items type material"
keybinding add Alt-Shift-Q "sort-units squad_position" "sort-items quality"
# browse linked mechanisms
keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms
# browse rooms of same owner
keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list
# interface for the liquids plugin - spawn water/magma/obsidian
keybinding add Alt-L@dwarfmode/LookAround gui/liquids
# machine power sensitive pressure plate construction
keybinding add Ctrl-Shift-M@dwarfmode/Build/Position/Trap gui/power-meter
# siege engine control
keybinding add Alt-A@dwarfmode/QueryBuilding/Some/SiegeEngine gui/siege-engine
# military weapon auto-select
keybinding add Ctrl-W@layer_military/Equip/Customize/View gui/choose-weapons
# military copy uniform
keybinding add Ctrl-C@layer_military/Uniforms gui/clone-uniform
# minecart Guide path
keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path
# workshop job details
keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job
# workflow front-end
keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow
keybinding add Alt-W@overallstatus "gui/workflow status"
# equivalent to the one above when gui/extended-status is enabled
keybinding add Alt-W@dfhack/lua/status_overlay "gui/workflow status"
# autobutcher front-end
keybinding add Shift-B@pet/List/Unit gui/autobutcher
# view pathable tiles from active cursor
keybinding add Alt-Shift-P@dwarfmode/LookAround gui/pathable
# gui/rename script - rename units and buildings
keybinding add Ctrl-Shift-N@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist gui/rename
keybinding add Ctrl-Shift-T@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit "gui/rename unit-profession"
#####################
# adv mode bindings #
#####################
keybinding add Ctrl-A@dungeonmode/ConversationSpeak adv-rumors
keybinding add Ctrl-B@dungeonmode adv-bodyswap
keybinding add Ctrl-Shift-B@dungeonmode "adv-bodyswap force"
keybinding add Shift-O@dungeonmode gui/companion-order
keybinding add Ctrl-T@dungeonmode gui/advfort
#########################
# legends mode bindings #
#########################
# export all information, or just the detailed maps (doesn't handle site maps)
keybinding add Ctrl-A@legends "exportlegends all"

@ -0,0 +1,132 @@
# Default DFHack tool configuration
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/dfhack.init
############################
# UI and game logic tweaks #
############################
# stabilize the cursor of dwarfmode when switching menus
tweak stable-cursor
# stop stacked liquid/bar/thread/cloth items from lasting forever
# if used in reactions that use only a fraction of the dimension.
# might be fixed by DF
# tweak fix-dimensions
# make reactions requiring containers usable in advmode - the issue is
# that the screen asks for those reagents to be selected directly
tweak advmode-contained
# support Shift-Enter in Trade and Move Goods to Depot screens for faster
# selection; it selects the current item or stack and scrolls down one line
tweak fast-trade
# stop the right list in military->positions from resetting to top all the time
tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
# make crafted cloth items wear out with time like in old versions (bug 6003)
tweak craft-age-wear
# stop adamantine clothing from wearing out (bug 6481)
#tweak adamantine-cloth-wear
# Add "Select all" and "Deselect all" options to farm plot menus
tweak farm-plot-select
# Add Shift-Left/Right controls to import agreement screen
tweak import-priority-category
# Fixes a crash in the work order contition material list (bug 9905).
tweak condition-material
# Adds an option to clear currently-bound hotkeys
tweak hotkey-clear
# Allows lowercase letters in embark profile names, and allows exiting the name prompt without saving
tweak embark-profile-name
# Reduce performance impact of temperature changes
tweak fast-heat 100
# Misc. UI tweaks
tweak block-labors # Prevents labors that can't be used from being toggled
tweak burrow-name-cancel
tweak cage-butcher
tweak civ-view-agreement
tweak do-job-now
tweak eggs-fertile
tweak fps-min
tweak hide-priority
tweak kitchen-prefs-all
tweak kitchen-prefs-empty
tweak max-wheelbarrow
tweak partial-items
tweak shift-8-scroll
tweak stone-status-all
tweak title-start-rename
tweak tradereq-pet-gender
###########################
# Globally acting plugins #
###########################
# Display DFHack version on title screen
enable title-version
# Dwarf Manipulator (simple in-game Dwarf Therapist replacement)
enable manipulator
# Search tool in various screens (by falconne)
enable search
# Improved build material selection interface (by falconne)
enable automaterial
# Other interface improvement tools
enable \
overlay \
confirm \
dwarfmonitor \
mousequery \
autogems \
autodump \
automelt \
autotrade \
buildingplan \
resume \
trackstop \
zone \
stocks \
autochop \
stockpiles
#end a line with a backslash to make it continue to the next line. The \ is deleted for the final command.
# Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console.
# You cannot extend a commented line.
# You can comment out the extension of a line.
# enable mouse controls and sand indicator in embark screen
embark-tools enable sticky sand mouse
# enable option to enter embark assistant
enable embark-assistant
###########
# Scripts #
###########
# write extra information to the gamelog
modtools/extra-gamelog enable
# extended status screen (bedrooms page)
enable gui/extended-status
# add information to item viewscreens
view-item-info enable
# a replacement for the "load game" screen
gui/load-screen enable

@ -0,0 +1,5 @@
# Default DFHack commands to run when a world is loaded
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onLoad.init

@ -0,0 +1,6 @@
# Default DFHack commands to run when a map is loaded, either in
# adventure or fort mode.
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onMapLoad.init

@ -0,0 +1,5 @@
# Default DFHack commands to run when a map is unloaded
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onMapUnload.init

@ -0,0 +1,5 @@
# Default DFHack commands to run when a world is unloaded
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onUnload.init

@ -1004,7 +1004,8 @@
"value" : 2
}
],
"job" : "MakeCrafts",
"item_subtype" : "ITEM_PANTS_LEGGINGS",
"job" : "MakePants",
"material_category" :
[
"shell"

@ -1,4 +1,4 @@
NAME Chef
NAME library/Chef
BUTCHER
TANNER
COOK

@ -1,4 +1,4 @@
NAME Craftsdwarf
NAME library/Craftsdwarf
WOOD_CRAFT
STONE_CRAFT
BONE_CARVE

@ -1,4 +1,4 @@
NAME Doctor
NAME library/Doctor
ANIMALCARE
DIAGNOSE
SURGERY

@ -1,4 +1,4 @@
NAME Farmer
NAME library/Farmer
PLANT
MILLER
BREWER

@ -1,4 +1,4 @@
NAME Fisherdwarf
NAME library/Fisherdwarf
FISH
CLEAN_FISH
DISSECT_FISH

@ -1,4 +1,4 @@
NAME Hauler
NAME library/Hauler
FEED_WATER_CIVILIANS
SIEGEOPERATE
MECHANIC

@ -1,4 +1,4 @@
NAME Laborer
NAME library/Laborer
SOAP_MAKER
BURN_WOOD
POTASH_MAKING

@ -1,4 +1,4 @@
NAME Marksdwarf
NAME library/Marksdwarf
MECHANIC
HAUL_STONE
HAUL_WOOD

@ -1,4 +1,4 @@
NAME Mason
NAME library/Mason
MASON
CUT_GEM
ENCRUST_GEM

@ -1,4 +1,4 @@
NAME Meleedwarf
NAME library/Meleedwarf
RECOVER_WOUNDED
MECHANIC
HAUL_STONE

@ -1,4 +1,4 @@
NAME Migrant
NAME library/Migrant
FEED_WATER_CIVILIANS
SIEGEOPERATE
MECHANIC

@ -1,4 +1,4 @@
NAME Miner
NAME library/Miner
MINE
DETAIL
RECOVER_WOUNDED

@ -1,4 +1,4 @@
NAME Outdoorsdwarf
NAME library/Outdoorsdwarf
CARPENTER
BOWYER
CUTWOOD

@ -1,4 +1,4 @@
NAME Smith
NAME library/Smith
FORGE_WEAPON
FORGE_ARMOR
FORGE_FURNITURE

@ -1,4 +1,4 @@
NAME StartManager
NAME library/StartManager
CUTWOOD
ANIMALCARE
DIAGNOSE

@ -1,4 +1,4 @@
NAME Tailor
NAME library/Tailor
DYER
LEATHER
WEAVER

@ -1 +1 @@
Subproject commit ae19aebd795d6d91803e60f46de037b604593cb4
Subproject commit 6ed8aa46462ea01a1122fc49422840a2facc9757

@ -1 +1 @@
Subproject commit ab8fd7f3e9df457e8bc1b5cb31b78d57df0ac5a4
Subproject commit 439fdbc259c13f23a3122e68ba35ad5a13bcd97c

@ -1,21 +1,3 @@
{
"widgets": [
{
"type": "weather",
"x": 1,
"y": -1
},
{
"type": "date",
"x": -30,
"y": 0,
"format": "Y-M-D"
},
{
"type": "misery",
"x": -2,
"y": -1,
"anchor": "right"
}
]
"date_format": "Y-M-D"
}

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/dfhack.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onLoad.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onMapLoad.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onMapUnload.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onUnload.default.init

@ -0,0 +1,5 @@
# This file runs when DFHack is initialized, when Dwarf Fortress is first
# started, before any world or save data is loaded.
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,6 @@
# This file runs when a world is loaded. This happens when you open a save file
# in fort, adventure, or legends mode. If a fort is being loaded, this file runs
# before any onMapLoad.init files.
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,5 @@
# This file runs when a map is loaded in adventure or fort mode, after any
# onLoad.init files (which run earlier, when the world is loaded).
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,5 @@
# This file runs when a fortress map is unloaded, before any onUnload.init files
# (which run later, when the world is unloaded).
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,4 @@
# This file runs when a world is unloaded.
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,14 @@
{
"dwarfmonitor.date": {
"enabled": true
},
"dwarfmonitor.misery": {
"enabled": true
},
"dwarfmonitor.weather": {
"enabled": true
},
"hotkeys.menu": {
"enabled": true
}
}

@ -1,297 +0,0 @@
##############################
# Generic dwarfmode bindings #
##############################
# show all current key bindings
keybinding add Ctrl-F1 hotkeys
keybinding add Alt-F1 hotkeys
# toggle the display of water level as 1-7 tiles
keybinding add Ctrl-W twaterlvl
# with cursor:
# designate the whole vein for digging
keybinding add Ctrl-V digv
keybinding add Ctrl-Shift-V "digv x"
# clean the selected tile of blood etc
keybinding add Ctrl-C spotclean
# destroy items designated for dump in the selected tile
keybinding add Ctrl-Shift-K autodump-destroy-here
# set the zone or cage under the cursor as the default
keybinding add Alt-Shift-I@dwarfmode/Zones "zone set"
# with an item selected:
# destroy the selected item
keybinding add Ctrl-K autodump-destroy-item
# scripts:
# quicksave, only in main dwarfmode screen and menu page
keybinding add Ctrl-Alt-S@dwarfmode/Default quicksave
# gui/quickfort script - apply pre-made blueprints to the map
keybinding add Ctrl-Shift-Q@dwarfmode gui/quickfort
keybinding add Alt-F@dwarfmode gui/quickfort
# gui/rename script - rename units and buildings
keybinding add Ctrl-Shift-N gui/rename
keybinding add Ctrl-Shift-T "gui/rename unit-profession"
# a dfhack prompt in df. Sublime text like.
keybinding add Ctrl-Shift-P command-prompt
# show information collected by dwarfmonitor
keybinding add Alt-M@dwarfmode/Default "dwarfmonitor prefs"
keybinding add Ctrl-F@dwarfmode/Default "dwarfmonitor stats"
# export a Dwarf's preferences screen in BBCode to post to a forum
keybinding add Ctrl-Shift-F@dwarfmode forum-dwarves
# an in-game init file editor
keybinding add Alt-S@title gui/settings-manager
keybinding add Alt-S@dwarfmode/Default gui/settings-manager
# change quantity of manager orders
keybinding add Alt-Q@jobmanagement/Main gui/manager-quantity
# re-check manager orders
keybinding add Alt-R@jobmanagement/Main workorder-recheck
# view combat reports for the selected unit/corpse/spatter
keybinding add Ctrl-Shift-R view-unit-reports
# view extra unit information
keybinding add Alt-I@dwarfmode/ViewUnits|unitlist gui/unit-info-viewer
##############################
# Generic adv mode bindings #
##############################
keybinding add Ctrl-B@dungeonmode adv-bodyswap
keybinding add Ctrl-Shift-B@dungeonmode "adv-bodyswap force"
keybinding add Shift-O@dungeonmode gui/companion-order
keybinding add Ctrl-T@dungeonmode gui/advfort
keybinding add Ctrl-A@dungeonmode/ConversationSpeak adv-rumors
##############################
# Generic legends bindings #
##############################
# export all information, or just the detailed maps (doesn't handle site maps)
keybinding add Ctrl-A@legends "exportlegends all"
#############################
# Context-specific bindings #
#############################
# Stocks plugin
keybinding add Ctrl-Shift-Z@dwarfmode/Default "stocks show"
# open an overview window summarising some stocks (dfstatus)
keybinding add Ctrl-Shift-I@dwarfmode/Default "gui/dfstatus"
keybinding add Ctrl-Shift-I@dfhack/lua/dfstatus "gui/dfstatus"
# q->stockpile - copy & paste stockpiles
keybinding add Alt-P copystock
# q->stockpile - load and save stockpile settings out of game
keybinding add Alt-L@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -load"
keybinding add Alt-S@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -save"
# q->workshop - duplicate the selected job
keybinding add Ctrl-D job-duplicate
# materials: q->workshop; b->select items
keybinding add Shift-A "job-material ALUNITE"
keybinding add Shift-M "job-material MICROCLINE"
keybinding add Shift-D "job-material DACITE"
keybinding add Shift-R "job-material RHYOLITE"
keybinding add Shift-I "job-material CINNABAR"
keybinding add Shift-B "job-material COBALTITE"
keybinding add Shift-O "job-material OBSIDIAN"
keybinding add Shift-T "job-material ORTHOCLASE"
keybinding add Shift-G "job-material GLASS_GREEN"
# sort units and items in the on-screen list
keybinding add Alt-Shift-N "sort-units name" "sort-items description"
keybinding add Alt-Shift-R "sort-units arrival"
keybinding add Alt-Shift-T "sort-units profession" "sort-items type material"
keybinding add Alt-Shift-Q "sort-units squad_position" "sort-items quality"
# browse linked mechanisms
keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms
# browse rooms of same owner
keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list
# interface for the liquids plugin - spawn water/magma/obsidian
keybinding add Alt-L@dwarfmode/LookAround gui/liquids
# machine power sensitive pressure plate construction
keybinding add Ctrl-Shift-M@dwarfmode/Build/Position/Trap gui/power-meter
# siege engine control
keybinding add Alt-A@dwarfmode/QueryBuilding/Some/SiegeEngine gui/siege-engine
# military weapon auto-select
keybinding add Ctrl-W@layer_military/Equip/Customize/View gui/choose-weapons
# military copy uniform
keybinding add Ctrl-C@layer_military/Uniforms gui/clone-uniform
# minecart Guide path
keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path
# workshop job details
keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job
# workflow front-end
keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow
keybinding add Alt-W@overallstatus "gui/workflow status"
# equivalent to the one above when gui/extended-status is enabled
keybinding add Alt-W@dfhack/lua/status_overlay "gui/workflow status"
# autobutcher front-end
keybinding add Shift-B@pet/List/Unit "gui/autobutcher"
# view pathable tiles from active cursor
keybinding add Alt-Shift-P@dwarfmode/LookAround gui/pathable
############################
# UI and game logic tweaks #
############################
# stabilize the cursor of dwarfmode when switching menus
tweak stable-cursor
# stop stacked liquid/bar/thread/cloth items from lasting forever
# if used in reactions that use only a fraction of the dimension.
# might be fixed by DF
# tweak fix-dimensions
# make reactions requiring containers usable in advmode - the issue is
# that the screen asks for those reagents to be selected directly
tweak advmode-contained
# support Shift-Enter in Trade and Move Goods to Depot screens for faster
# selection; it selects the current item or stack and scrolls down one line
tweak fast-trade
# stop the right list in military->positions from resetting to top all the time
tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
# make crafted cloth items wear out with time like in old versions (bug 6003)
tweak craft-age-wear
# stop adamantine clothing from wearing out (bug 6481)
#tweak adamantine-cloth-wear
# Add "Select all" and "Deselect all" options to farm plot menus
tweak farm-plot-select
# Add Shift-Left/Right controls to import agreement screen
tweak import-priority-category
# Fixes a crash in the work order contition material list (bug 9905).
tweak condition-material
# Adds an option to clear currently-bound hotkeys
tweak hotkey-clear
# Allows lowercase letters in embark profile names, and allows exiting the name prompt without saving
tweak embark-profile-name
# Reduce performance impact of temperature changes
tweak fast-heat 100
# Misc. UI tweaks
tweak block-labors # Prevents labors that can't be used from being toggled
tweak burrow-name-cancel
tweak cage-butcher
tweak civ-view-agreement
tweak do-job-now
tweak eggs-fertile
tweak fps-min
tweak hide-priority
tweak kitchen-prefs-all
tweak kitchen-prefs-empty
tweak max-wheelbarrow
tweak partial-items
tweak shift-8-scroll
tweak stone-status-all
tweak title-start-rename
tweak tradereq-pet-gender
###########################
# Globally acting plugins #
###########################
# Display DFHack version on title screen
enable title-version
# Dwarf Manipulator (simple in-game Dwarf Therapist replacement)
enable manipulator
# Search tool in various screens (by falconne)
enable search
# Improved build material selection interface (by falconne)
enable automaterial
# Other interface improvement tools
enable \
confirm \
dwarfmonitor \
mousequery \
autogems \
autodump \
automelt \
autotrade \
buildingplan \
resume \
trackstop \
zone \
stocks \
autochop \
stockpiles
#end a line with a backslash to make it continue to the next line. The \ is deleted for the final command.
# Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console.
# You cannot extend a commented line.
# You can comment out the extension of a line.
# enable mouse controls and sand indicator in embark screen
embark-tools enable sticky sand mouse
# enable option to enter embark assistant
enable embark-assistant
###########
# Scripts #
###########
# write extra information to the gamelog
modtools/extra-gamelog enable
# extended status screen (bedrooms page)
enable gui/extended-status
# add information to item viewscreens
view-item-info enable
# a replacement for the "load game" screen
gui/load-screen enable
##############################
# Extra DFHack command files #
##############################
# Create a file named "onLoad.init" to run commands when a world is loaded
# and/or create a file named "onMapLoad.init" to run commands when a map is
# loaded. See the hack/examples/init/ directory for useful pre-made init files.

@ -1,4 +1,4 @@
List of Authors
List of authors
===============
The following is a list of people who have contributed to DFHack, in
alphabetical order.
@ -134,6 +134,7 @@ potato
Priit Laes plaes
Putnam Putnam3145
Quietust quietust _Q
Rafał Karczmarczyk CarabusX
Raidau Raidau
Ralph Bisschops ralpha
Ramblurr Ramblurr

@ -40,8 +40,8 @@ This will check out the code on the default branch of the GitHub repo, currently
``develop``, which may be unstable. If you want code for the latest stable
release, you can check out the ``master`` branch instead::
git checkout master
git submodule update
git checkout master
git submodule update
In general, a single DFHack clone is suitable for development - most Git
operations such as switching branches can be done on an existing clone. If you
@ -289,7 +289,7 @@ DF, which causes DF to use your system libstdc++ instead::
rm libs/libstdc++.so.6
Note that distributing binaries compiled with newer GCC versions may result in
the opposite compatibily issue: users with *older* GCC versions may encounter
the opposite compatibility issue: users with *older* GCC versions may encounter
similar errors. This is why DFHack distributes both GCC 4.8 and GCC 7 builds. If
you are planning on distributing binaries to other users, we recommend using an
older GCC (but still at least 4.8) version if possible.
@ -314,7 +314,7 @@ Notes for GCC 8+ or OS X 10.10+ users
If none of these situations apply to you, skip to `osx-setup`.
If you have issues building on OS X 10.10 (Yosemite) or above, try definining
If you have issues building on OS X 10.10 (Yosemite) or above, try defining
the following environment variable::
export MACOSX_DEPLOYMENT_TARGET=10.9
@ -503,7 +503,7 @@ in their name. If this redirect doesn't occur, just copy, paste, and enter the
download link again and you should see the options. You need to get:
Visual C++ Build Tools for Visual Studio 2015 with Update 3.
Click the download button next to it and a dropdown of download formats will appear.
Select the DVD format to download an ISO file. When the donwload is complete,
Select the DVD format to download an ISO file. When the download is complete,
click on the ISO file and a folder will popup with the following contents:
* packages (folder)
@ -561,7 +561,7 @@ Additional dependencies: installing with the Chocolatey Package Manager
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The remainder of dependencies - Git, CMake, StrawberryPerl, and Python - can be
most easily installed using the Chocolatey Package Manger. Chocolatey is a
most easily installed using the Chocolatey Package Manager. Chocolatey is a
\*nix-style package manager for Windows. It's fast, small (8-20MB on disk)
and very capable. Think "``apt-get`` for Windows."

@ -9,10 +9,9 @@ DFHack Core
:depth: 2
Command Implementation
Command implementation
======================
DFHack commands can be implemented in three ways, all of which
are used in the same way:
DFHack commands can be implemented in any of three ways:
:builtin: commands are implemented by the core of DFHack. They manage
other DFHack tools, interpret commands, and control basic
@ -27,8 +26,9 @@ are used in the same way:
more flexible about versions, and easier to distribute.
Most third-party DFHack addons are scripts.
All tools distributed with DFHack are documented `here <genindex>`.
Using DFHack Commands
Using DFHack commands
=====================
DFHack commands can be executed in a number of ways:
@ -38,7 +38,7 @@ DFHack commands can be executed in a number of ways:
#. From one of several `init-files`, automatically
#. Using `script` to run a batch of commands from a file
The DFHack Console
The DFHack console
------------------
The command line has some nice line editing capabilities, including history
that's preserved between different runs of DF - use :kbd:`↑` and :kbd:`↓`
@ -113,269 +113,27 @@ second (Windows) example uses `kill-lua` to stop a Lua script.
you have multiple copies of DF running simultaneously. To assign a different
port, see `remote-server-config`.
.. _dfhack-config:
Built-in Commands
=================
The following commands are provided by the 'core' components
of DFHack, rather than plugins or scripts.
.. contents::
:local:
.. _alias:
alias
-----
The ``alias`` command allows configuring aliases to other DFHack commands.
Aliases are resolved immediately after built-in commands, which means that an
alias cannot override a built-in command, but can override a command implemented
by a plugin or script.
Usage:
:``alias list``: lists all configured aliases
:``alias add <name> <command> [arguments...]``: adds an alias
:``alias replace <name> <command> [arguments...]``: replaces an existing
alias with a new command, or adds the alias if it does not already exist
:``alias delete <name>``: removes the specified alias
Aliases can be given additional arguments when created and invoked, which will
be passed to the underlying command in order. An example with `devel/print-args`::
[DFHack]# alias add pargs devel/print-args example
[DFHack]# pargs text
example
text
.. _cls:
cls
---
Clear the terminal. Does not delete command history.
.. _die:
die
---
Instantly kills DF without saving.
.. _disable:
.. _enable:
enable
------
Many plugins can be in a distinct enabled or disabled state. Some of
them activate and deactivate automatically depending on the contents
of the world raws. Others store their state in world data. However a
number of them have to be enabled globally, and the init file is the
right place to do it.
Most such plugins or scripts support the built-in ``enable`` and ``disable``
commands. Calling them at any time without arguments prints a list
of enabled and disabled plugins, and shows whether that can be changed
through the same commands. Passing plugin names to these commands will enable
or disable the specified plugins. For example, to enable the `manipulator`
plugin::
enable manipulator
It is also possible to enable or disable multiple plugins at once::
enable manipulator search
.. _fpause:
fpause
------
Forces DF to pause. This is useful when your FPS drops below 1 and you lose
control of the game.
.. _help:
help
----
Most commands support using the ``help <command>`` built-in command
to retrieve further help without having to look at this document.
``? <cmd>`` and ``man <cmd>`` are aliases.
Some commands (including many scripts) instead take ``help`` or ``?``
as an option on their command line - ie ``<cmd> help``.
.. _hide:
hide
----
Hides the DFHack terminal window. Only available on Windows.
.. _keybinding:
keybinding
----------
To set keybindings, use the built-in ``keybinding`` command. Like any other
command it can be used at any time from the console, but bindings are not
remembered between runs of the game unless re-created in `dfhack.init`.
Currently, any combinations of Ctrl/Alt/Shift with A-Z, 0-9, or F1-F12 are supported.
Possible ways to call the command:
``keybinding list <key>``
List bindings active for the key combination.
``keybinding clear <key> <key>...``
Remove bindings for the specified keys.
``keybinding add <key> "cmdline" "cmdline"...``
Add bindings for the specified key.
``keybinding set <key> "cmdline" "cmdline"...``
Clear, and then add bindings for the specified key.
The ``<key>`` parameter above has the following *case-sensitive* syntax::
[Ctrl-][Alt-][Shift-]KEY[@context[|context...]]
where the *KEY* part can be any recognized key and [] denote optional parts.
When multiple commands are bound to the same key combination, DFHack selects
the first applicable one. Later ``add`` commands, and earlier entries within one
``add`` command have priority. Commands that are not specifically intended for use
as a hotkey are always considered applicable.
The ``context`` part in the key specifier above can be used to explicitly restrict
the UI state where the binding would be applicable. If called without parameters,
the ``keybinding`` command among other things prints the current context string.
Only bindings with a ``context`` tag that either matches the current context fully,
or is a prefix ending at a ``/`` boundary would be considered for execution, i.e.
when in context ``foo/bar/baz``, keybindings restricted to any of ``@foo/bar/baz``,
``@foo/bar``, ``@foo`` or none will be active.
Multiple contexts can be specified by separating them with a
pipe (``|``) - for example, ``@foo|bar|baz/foo`` would match
anything under ``@foo``, ``@bar``, or ``@baz/foo``.
Interactive commands like `liquids` cannot be used as hotkeys.
.. _kill-lua:
kill-lua
--------
Stops any currently-running Lua scripts. By default, scripts can
only be interrupted every 256 instructions. Use ``kill-lua force``
to interrupt the next instruction.
.. _load:
.. _unload:
.. _reload:
load
----
``load``, ``unload``, and ``reload`` control whether a plugin is loaded
into memory - note that plugins are loaded but disabled unless you do
something. Usage::
load|unload|reload PLUGIN|(-a|--all)
Allows dealing with plugins individually by name, or all at once.
Note that plugins do not maintain their enabled state if they are reloaded, so
you may need to use `enable` to re-enable a plugin after reloading it.
.. _ls:
ls
--
``ls`` does not list files like the Unix command, but rather
available commands - first built in commands, then plugins,
and scripts at the end. Usage:
:ls -a: Also list scripts in subdirectories of ``hack/scripts/``,
which are generally not intended for direct use.
:ls <plugin>: List subcommands for the given plugin.
.. _plug:
plug
----
Lists available plugins, including their state and detailed description.
``plug``
Lists available plugins (*not* commands implemented by plugins)
``plug [PLUGIN] [PLUGIN] ...``
List state and detailed description of the given plugins,
including commands implemented by the plugin.
.. _sc-script:
sc-script
---------
Allows additional scripts to be run when certain events occur
(similar to onLoad*.init scripts)
.. _script:
script
------
Reads a text file, and runs each line as a DFHack command
as if it had been typed in by the user - treating the
input like `an init file <init-files>`.
Some other tools, such as `autobutcher` and `workflow`, export
their settings as the commands to create them - which are later
loaded with ``script``
.. _show:
show
----
Shows the terminal window after it has been `hidden <hide>`.
Only available on Windows. You'll need to use it from a
`keybinding` set beforehand, or the in-game `command-prompt`.
.. _type:
type
----
``type command`` shows where ``command`` is implemented.
Other Commands
--------------
The following commands are *not* built-in, but offer similarly useful functions.
* `command-prompt`
* `hotkeys`
* `lua`
* `multicmd`
* `nopause`
* `quicksave`
* `rb`
* `repeat`
Configuration files
===================
Most DFHack settings can be changed by modifying files in the ``dfhack-config``
folder (which is in the DF folder). The default versions of these files, if they
exist, are in ``dfhack-config/default`` and are installed when DFHack starts if
necessary.
.. _init-files:
Init Files
==========
Init files
----------
.. contents::
:local:
DFHack allows users to automatically run commonly-used DFHack commands
when DF is first loaded, when a game is loaded, and when a game is unloaded.
when DF is first loaded, when a world is loaded, when a map is loaded, when a
map is unloaded, and when a world is unloaded.
Init scripts function the same way they would if the user manually typed
in their contents, but are much more convenient. In order to facilitate
@ -385,32 +143,33 @@ save-specific init files in the save folders.
DFHack looks for init files in three places each time they could be run:
#. The main DF directory
#. The :file:`dfhack-config/init` subdirectory in the main DF directory
#. :file:`data/save/{world}/raw`, where ``world`` is the current save, and
#. :file:`data/save/{world}/raw/objects`
When reading commands from dfhack.init or with the `script` command, if the final
character on a line is a backslash then the next uncommented line is considered a
continuation of that line, with the backslash deleted. Commented lines are skipped,
so it is possible to comment out parts of a command with the ``#`` character.
For each of those directories, all matching init files will be executed in
alphabetical order.
Before running matched init scripts in any of those locations, the
:file:`dfhack-config/init/default.*` file that matches the event will be run to
load DFHack defaults. Only the :file:`dfhack-config/init` directory is checked
for this file, not any :file:`raw` directories. If you want DFHack to load
without running any of its default configuration commands, edit the
:file:`dfhack-config/init/default.*` files and comment out the commands you see
there.
.. _dfhack.init:
dfhack*.init
------------
If your DF folder contains at least one file named ``dfhack*.init``
(where ``*`` is a placeholder for any string), then all such files
are executed in alphabetical order when DF is first started.
When reading commands from the init files or with the `script` command, if the
final character on a line is a backslash then the next uncommented line is
considered a continuation of that line, with the backslash deleted. Commented
lines are skipped, so it is possible to comment out parts of a command with the
``#`` character.
DFHack is distributed with :download:`/dfhack.init-example` as an example
with an up-to-date collection of basic commands; mostly setting standard
keybindings and `enabling <enable>` plugins. You are encouraged to look
through this file to learn which features it makes available under which
key combinations. You may also customise it and rename it to ``dfhack.init``.
.. _dfhack.init:
If your DF folder does not contain any ``dfhack*.init`` files, the example
will be run as a fallback.
dfhack\*.init
.............
On startup, DFHack looks for files of the form ``dfhack*.init`` (where ``*`` is
a placeholder for any string, including the empty string).
These files are best used for keybindings and enabling persistent plugins
which do not require a world to be loaded.
@ -418,51 +177,49 @@ which do not require a world to be loaded.
.. _onLoad.init:
onLoad*.init
------------
onLoad\*.init
.............
When a world is loaded, DFHack looks for files of the form ``onLoad*.init``,
where ``*`` can be any string, including the empty string.
All matching init files will be executed in alphabetical order.
A world being loaded can mean a fortress, an adventurer, or legends mode.
These files are best used for non-persistent commands, such as setting
a `fix <scripts-fix>` script to run on `repeat`.
a `bugfix-tag-index` script to run on `repeat`.
.. _onUnload.init:
.. _onMapLoad.init:
onUnload*.init
--------------
When a world is unloaded, DFHack looks for files of the form ``onUnload*.init``.
Again, these files may be in any of the above three places.
All matching init files will be executed in alphebetical order.
onMapLoad\*.init
................
When a map is loaded, either in adventure or fort mode, DFHack looks for files
of the form ``onMapLoad*.init``, where ``*`` can be any string, including the
empty string.
Modders often use such scripts to disable tools which should not affect
an unmodded save.
These files are best used for commands that are only relevant once there is a
game map loaded.
.. _other_init_files:
Other init files
----------------
.. _onMapUnload.init:
.. _onUnload.init:
* ``onMapLoad*.init`` and ``onMapUnload*.init`` are run when a map,
distinct from a world, is loaded. This is good for map-affecting
commands (e.g. `clean`), or avoiding issues in Legends mode.
onMapUnload\*.init and onUnload\*.init
......................................
When a map or world is unloaded, DFHack looks for files of the form
``onMapUnload*.init`` or ``onUnload*.init``, respectively.
* Any lua script named ``raw/init.d/*.lua``, in the save or main DF
directory, will be run when any world or that save is loaded.
Modders often use unload init scripts to disable tools which should not run
after a modded save is unloaded.
.. _dfhack-config:
.. _other_init_files:
Configuration Files
===================
raw/init.d/\*.lua
.................
Any lua script named ``raw/init.d/*.lua``, in the save or main DF directory,
will be run when any world or that save is loaded.
Some DFHack settings can be changed by modifying files in the ``dfhack-config``
folder (which is in the DF folder). The default versions of these files, if they
exist, are in ``dfhack-config/default`` and are installed when DFHack starts if
necessary.
.. _script-paths:
@ -503,7 +260,7 @@ modified programmatically at any time through the `Lua API <lua-api-internal>`.
.. _env-vars:
Environment Variables
Environment variables
=====================
DFHack's behavior can be adjusted with some environment variables. For example,
@ -549,7 +306,7 @@ Other (non-DFHack-specific) variables that affect DFHack:
sensitive), ``DF2CONSOLE()`` will produce UTF-8-encoded text. Note that this
should be the case in most UTF-8-capable \*nix terminal emulators already.
Miscellaneous Notes
Miscellaneous notes
===================
This section is for odd but important notes that don't fit anywhere else.

@ -22,7 +22,7 @@ Plugins
DFHack plugins are written in C++ and located in the ``plugins`` folder.
Currently, documentation on how to write plugins is somewhat sparse. There are
templates that you can use to get started in the ``plugins/skeleton``
templates that you can use to get started in the ``plugins/examples``
folder, and the source code of existing plugins can also be helpful.
If you want to compile a plugin that you have just added, you will need to add a
@ -35,13 +35,13 @@ other commands).
Plugins can also register handlers to run on every tick, and can interface with
the built-in `enable` and `disable` commands. For the full plugin API, see the
skeleton plugins or ``PluginManager.cpp``.
example ``skeleton`` plugin or ``PluginManager.cpp``.
Installed plugins live in the ``hack/plugins`` folder of a DFHack installation,
and the `load` family of commands can be used to load a recompiled plugin
without restarting DF.
See `plugins-index` for a list of all plugins included in DFHack.
Run `plug` at the DFHack prompt for a list of all plugins included in DFHack.
Scripts
-------
@ -51,10 +51,10 @@ is more complete and currently better-documented, however. Referring to existing
scripts as well as the API documentation can be helpful when developing new
scripts.
`Scripts included in DFHack <scripts-index>` live in a separate `scripts repository <https://github.com/dfhack/scripts>`_.
This can be found in the ``scripts`` submodule if you have
`cloned DFHack <compile-how-to-get-the-code>`, or the ``hack/scripts`` folder
of an installed copy of DFHack.
Scripts included in DFHack live in a separate
:source-scripts:`scripts repository <>`. This can be found in the ``scripts``
submodule if you have `cloned DFHack <compile-how-to-get-the-code>`, or the
``hack/scripts`` folder of an installed copy of DFHack.
Core
----

@ -1,143 +1,352 @@
.. _documentation:
###########################
DFHack Documentation System
DFHack documentation system
###########################
DFHack documentation, like the file you are reading now, is created as ``.rst`` files,
which are in `reStructuredText (reST) <https://www.sphinx-doc.org/rest.html>`_ format.
This is a documentation format common in the Python community. It is very
similar in concept - and in syntax - to Markdown, as found on GitHub and many other
DFHack documentation, like the file you are reading now, is created as a set of
``.rst`` files in `reStructuredText (reST) <https://www.sphinx-doc.org/rest.html>`_
format. This is a documentation format common in the Python community. It is very
similar in concept -- and in syntax -- to Markdown, as found on GitHub and many other
places. However it is more advanced than Markdown, with more features available when
compiled to HTML, such as automatic tables of contents, cross-linking, special
external links (forum, wiki, etc) and more. The documentation is compiled by a
Python tool, `Sphinx <https://www.sphinx-doc.org>`_.
Python tool named `Sphinx <https://www.sphinx-doc.org>`_.
The DFHack build process will compile the documentation, but this is disabled
by default due to the additional Python and Sphinx requirements. You typically
only need to build the docs if you're changing them, or perhaps
if you want a local HTML copy; otherwise, you can read an
`online version hosted by ReadTheDocs <https://dfhack.readthedocs.org>`_.
The DFHack build process will compile and install the documentation so it can be
displayed in-game by the `help` and `ls` commands (and any other command or GUI that
displays help text), but documentation compilation is disabled by default due to the
additional Python and Sphinx requirements. If you already have a version of the docs
installed (say from a downloaded release binary), then you only need to build the docs
if you're changing them and want to see the changes reflected in your game.
(Note that even if you do want a local copy, it is certainly not necessary to
You can also build the docs if you just want a local HTML- or text-rendered copy, though
you can always read the `online version <https://dfhack.readthedocs.org>`_ too.
The active development version of the documentation is tagged with ``latest`` and
is available `here <https://docs.dfhack.org/en/latest/index.html>`_
Note that even if you do want a local copy, it is certainly not necessary to
compile the documentation in order to read it. Like Markdown, reST documents are
designed to be just as readable in a plain-text editor as they are in HTML format.
The main thing you lose in plain text format is hyperlinking.)
The main thing you lose in plain text format is hyperlinking.
.. contents:: Contents
:local:
Concepts and general guidance
=============================
The source ``.rst`` files are compiled to HTML for viewing in a browser and to text
format for viewing in-game. For in-game help, the help text is read from its installed
location in ``hack/docs`` under the DF directory.
When writing documentation, remember that everything should be documented! If it's not
clear *where* a particular thing should be documented, ask on Discord or in the DFHack
thread on Bay12 -- you'll not only be getting help, you'll also be providing valuable
feedback that makes it easier for future contributors to find documentation on how to
write the documentation!
Try to keep lines within 80-100 characters so it's readable in plain text in the
terminal - Sphinx (our documentation system) will make sure paragraphs flow.
Short descriptions
------------------
Each command that a user can run -- as well as every plugin -- needs to have a
short (~54 character) descriptive string associated with it. This description text is:
- used in-game by the `ls` command and DFHack UI screens that list commands
- used in the generated index entries in the HTML docs
Tags
----
To make it easier for players to find related commands, all plugins and commands are marked
with relevant tags. These are used to compile indices and generate cross-links between the
commands, both in the HTML documents and in-game. See the list of available `tag-list` and
think about which categories your new tool belongs in.
Links
-----
If it would be helpful to mention another DFHack command, don't just type the
name - add a hyperlink! Specify the link target in backticks, and it will be
replaced with the corresponding title and linked: e.g. ```autolabor```
=> `autolabor`. Scripts and plugins have link targets that match their names
created for you automatically.
If you want to link to a heading in your own page, you can specify it like this::
`Heading text exactly as written`_
Note that the DFHack documentation is configured so that single backticks (with
no prefix or suffix) produce links to internal link targets, such as the
``autolabor`` target shown above. This is different from the reStructuredText
default behavior of rendering such text in italics (as a reference to a title).
For alternative link behaviors, see:
- `The reStructuredText documentation on roles <https://docutils.sourceforge.io/docs/ref/rst/roles.html>`__
- `The reStructuredText documentation on external links <https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#hyperlink-targets>`__
- `The Sphinx documentation on roles <https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html>`__
- ``:doc:`` is useful for linking to another document outside of DFHack.
.. _docs-standards:
Documentation standards
=======================
.. highlight:: rst
Whether you're adding new code or just fixing old documentation (and there's plenty),
there are a few important standards for completeness and consistent style. Treat
this section as a guide rather than iron law, match the surrounding text, and you'll
be fine.
Command documentation
---------------------
Where do I add the help text?
-----------------------------
Each command should have a short (~54 character) help string, which is shown
by the `ls` command. For scripts, this is a comment on the first line
(the comment marker and whitespace is stripped). For plugins it's the second
argument to ``PluginCommand``. Please make this brief but descriptive!
For scripts and plugins that are distributed as part of DFHack, documentation files
should be added to the :source-scripts:`scripts/docs <docs>` and :source:`docs/plugins` directories,
respectively, in a file named after the script or plugin. For example, a script named
``gui/foobar.lua`` (which provides the ``gui/foobar`` command) should be documented
in a file named ``docs/gui/foobar.rst`` in the scripts repo. Similarly, a plugin named
``foobaz`` should be documented in a file named ``docs/plugins/foobaz.rst`` in the dfhack repo.
For plugins, all commands provided by that plugin should be documented in that same file.
Everything should be documented! If it's not clear *where* a particular
thing should be documented, ask on IRC or in the DFHack thread on Bay12 -
as well as getting help, you'll be providing valuable feedback that
makes it easier for future readers!
Short descriptions (the ~54 character short help) for scripts and plugins are taken from
the ``summary`` attribute of the ``dfhack-tool`` directive that each tool help document must
have (see the `Header format`_ section below). Please make this brief but descriptive!
Scripts can use a custom autodoc function, based on the Sphinx ``include``
directive - anything between the tokens is copied into the appropriate scripts
documentation page. For Ruby, we follow the built-in docstring convention
(``=begin`` and ``=end``). For Lua, the tokens are ``[====[`` and ``]====]``
- ordinary multi-line strings. It is highly encouraged to reuse this string
as the in-console documentation by (e.g.) printing it when a ``-help`` argument
is given.
Short descriptions for commands provided by plugins are taken from the ``description``
parameter passed to the ``PluginCommand`` constructor used when the command is registered
in the plugin source file.
The docs **must** have a heading which exactly matches the command, underlined
with ``=====`` to the same length. For example, a lua file would have:
Header format
-------------
.. code-block:: lua
The docs **must** begin with a heading which exactly matches the script or plugin name, underlined
with ``=====`` to the same length. This must be followed by a ``.. dfhack-tool:`` directive with
at least the following parameters:
local helpstr = [====[
* ``:summary:`` - a short, single-sentence description of the tool
* ``:tags:`` - a space-separated list of `tags <tag-list>` that apply to the tool
add-thought
===========
Adds a thought or emotion to the selected unit. Can be used by other scripts,
or the gui invoked by running ``add-thought gui`` with a unit selected.
By default, ``dfhack-tool`` generates both a description of a tool and a command
with the same name. For tools (specifically plugins) that do not provide exactly
1 command with the same name as the tool, pass the ``:no-command:`` parameter (with
no content after it) to prevent the command block from being generated.
]====]
For tools that provide multiple commands, or a command by the same name but with
significantly different functionality (e.g. a plugin that can be both enabled
and invoked as a command for different results), use the ``.. dfhack-command:``
directive for each command. This takes only a ``:summary:`` argument, with the
same meaning as above.
For example, documentation for the ``build-now`` script might look like::
.. highlight:: rst
build-now
=========
Where the heading for a section is also the name of a command, the spelling
and case should exactly match the command to enter in the DFHack command line.
.. dfhack-tool::
:summary: Instantly completes unsuspended building construction jobs.
:tags: fort armok buildings
Try to keep lines within 80-100 characters, so it's readable in plain text
in the terminal - Sphinx (our documentation system) will make sure
paragraphs flow.
By default, all buildings on the map are completed, but the area of effect is configurable.
Command usage
-------------
And documentation for the ``autodump`` plugin might look like::
If there aren't many options or examples to show, they can go in a paragraph of
text. Use double-backticks to put commands in monospaced font, like this::
autodump
========
You can use ``cleanowned scattered x`` to dump tattered or abandoned items.
.. dfhack-tool::
:summary: Automatically set items in a stockpile to be dumped.
:tags: fort armok fps productivity items stockpiles
:no-command:
If the command takes more than three arguments, format the list as a table
called Usage. The table *only* lists arguments, not full commands.
Input values are specified in angle brackets. Example::
.. dfhack-command:: autodump
:summary: Teleports items marked for dumping to the cursor position.
Usage:
.. dfhack-command:: autodump-destroy-here
:summary: Destroy items marked for dumping under the cursor.
:arg1: A simple argument.
:arg2 <input>: Does something based on the input value.
:Very long argument:
Is very specific.
.. dfhack-command:: autodump-destroy-item
:summary: Destroys the selected item.
To demonstrate usage - useful mainly when the syntax is complicated, list the
full command with arguments in monospaced font, then indent the next line and
describe the effect::
When `enabled <enable>`, this plugin adds an option to the :kbd:`q` menu for
stockpiles.
``resume all``
Resumes all suspended constructions.
When invoked as a command, it can instantly move all unforbidden items marked
for dumping to the tile under the cursor.
Links
-----
Usage help
----------
If it would be helpful to mention another DFHack command, don't just type the
name - add a hyperlink! Specify the link target in backticks, and it will be
replaced with the corresponding title and linked: e.g. ```autolabor```
=> `autolabor`. Link targets should be equivalent to the command
described (without file extension), and placed above the heading of that
section like this::
The first section after the header and introductory text should be the usage section. You can
choose between two formats, based on whatever is cleaner or clearer for your syntax. The first
option is to show usage formats together, with an explanation following the block::
.. _autolabor:
Usage
-----
autolabor
=========
::
Add link targets if you need them, but otherwise plain headings are preferred.
Scripts have link targets created automatically.
build-now [<options>]
build-now here [<options>]
build-now [<pos> [<pos>]] [<options>]
Note that the DFHack documentation is configured so that single backticks (with
no prefix or suffix) produce links to internal link targets, such as the
``autolabor`` target shown above. This is different from the reStructuredText
default behavior of rendering such text in italics (as a reference to a title).
For alternative link behaviors, see:
Where the optional ``<pos>`` pair can be used to specify the
coordinate bounds within which ``build-now`` will operate. If
they are not specified, ``build-now`` will scan the entire map.
If only one ``<pos>`` is specified, only the building at that
coordinate is built.
- `The reStructuredText documentation on roles <https://docutils.sourceforge.io/docs/ref/rst/roles.html>`__
- `The reStructuredText documentation on external links <https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#hyperlink-targets>`__
- `The Sphinx documentation on roles <https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html>`__
The ``<pos>`` parameters can either be an ``<x>,<y>,<z>`` triple
(e.g. ``35,12,150``) or the string ``here``, which means the
position of the active game cursor.
The second option is to arrange the usage options in a list, with the full command
and arguments in monospaced font. Then indent the next line and describe the effect::
Usage
-----
``build-now [<options>]``
Scan the entire map and build all unsuspended constructions
and buildings.
``build-now here [<options>]``
Build the unsuspended construction or building under the
cursor.
``build-now [<pos> [<pos>]] [<options>]``
Build all unsuspended constructions within the specified
coordinate box.
- ``:doc:`` is useful for linking to another document
The ``<pos>`` parameters are specified as...
Note that in both options, the entire commandline syntax is written, including the command itself.
Literal text is written as-is (e.g. the word ``here`` in the above example), and text that
describes the kind of parameter that is being passed (e.g. ``pos`` or ``options``) is enclosed in
angle brackets (``<`` and ``>``). Optional elements are enclosed in square brackets (``[`` and ``]``).
If the command takes an arbitrary number of elements, use ``...``, for example::
prioritize [<options>] <job type> [<job type> ...]
quickfort <command>[,<command>...] <list_id>[,<list_id>...] [<options>]
Examples
--------
If the only way to run the command is to type the command itself, then this section is not necessary.
Otherwise, please consider adding a section that shows some real, practical usage examples. For
many users, this will be the **only** section they will read. It is so important that it is a good
idea to include the ``Examples`` section **before** you describe any extended options your command
might take. Write examples for what you expect the popular use cases will be. Also be sure to write
examples showing specific, practical values being used for any parameter that takes a value or has
tricky formatting.
Examples should go in their own subheading. The examples themselves should be organized as in
option 2 for Usage above. Here is an example ``Examples`` section::
Examples
--------
``build-now``
Completes all unsuspended construction jobs on the map.
``build-now 37,20,154 here``
Builds the unsuspended, unconstructed buildings in the box
bounded by the coordinate x=37,y=20,z=154 and the cursor.
Options
-------
The options header should follow the examples, with each option in the same format as the
examples::
Options
-------
``-h``, ``--help``
Show help text.
``-l``, ``--quality <level>``
Set the quality of the architecture for built architected
builtings.
``-q``, ``--quiet``
Suppress informational output (error messages are still
printed).
Note that for parameters that have both short and long forms, any values that those options
take only need to be specified once (e.g. ``<level>``).
External scripts and plugins
============================
Scripts and plugins distributed separately from DFHack's release packages don't have the
opportunity to add their documentation to the rendered HTML or text output. However, these
scripts and plugins can use a different mechanism to at least make their help text available
in-game.
Note that since help text for external scripts and plugins is not rendered by Sphinx,
it should be written in plain text. Any reStructuredText markup will not be processed and,
if present, will be shown verbatim to the player (which is probably not what you want).
For external scripts, the short description comes from a comment on the first line
(the comment marker and extra whitespace is stripped). For Lua, this would look like:
.. code-block:: lua
-- A short description of my cool script.
and for Ruby scripts it would look like:
.. code-block:: ruby
# A short description of my cool script.
The main help text for an external script needs to appear between two markers. For
Lua, these markers are ``[====[`` and ``]====]``, and for Ruby they are ``=begin`` and
``=end``. The documentation standards above still apply to external tools, but there is
no need to include backticks for links or monospaced fonts. Here is a Lua example for an
entire script header::
-- Inventory management for adventurers.
-- [====[
gui/adv-inventory
=================
Tags: adventure | items
Allows you to quickly move items between containers. This
includes yourself and any followers you have.
Usage
-----
gui/adv-inventory [<options>]
Examples
--------
gui/adv-inventory
Opens the GUI with nothing preselected
gui/adv-inventory take-all
Opens the GUI with all container items already selected and
ready to move into the adventurer's inventory.
Options
-------
take-all
Starts the GUI with container items pre-selected
give-all
Starts the GUI with your own items pre-selected
]====]
For external plugins, help text for provided commands can be passed as the ``usage``
parameter when registering the commands with the ``PluginCommand`` constructor. There
is currently no way for associating help text with the plugin itself, so any
information about what the plugin does when enabled should be combined into the command
help.
Required dependencies
=====================
@ -145,10 +354,10 @@ Required dependencies
.. highlight:: shell
In order to build the documentation, you must have Python with Sphinx
version |sphinx_min_version| or later. Python 3 is recommended.
version |sphinx_min_version| or later and Python 3.
When installing Sphinx from OS package managers, be aware that there is
another program called Sphinx, completely unrelated to documentation management.
another program called "Sphinx", completely unrelated to documentation management.
Be sure you are installing the right Sphinx; it may be called ``python-sphinx``,
for example. To avoid doubt, ``pip`` can be used instead as detailed below.
@ -162,13 +371,12 @@ For more detailed platform-specific instructions, see the sections below:
:local:
:backlinks: none
Linux
-----
Most Linux distributions will include Python by default. If not, start by
installing Python (preferably Python 3). On Debian-based distros::
installing Python 3. On Debian-based distros::
sudo apt install python3
sudo apt install python3
Check your package manager to see if Sphinx |sphinx_min_version| or later is
available. On Debian-based distros, this package is named ``python3-sphinx``.
@ -177,11 +385,11 @@ want to use a newer Sphinx version (which may result in faster builds), you
can install Sphinx through the ``pip`` package manager instead. On Debian-based
distros, you can install pip with::
sudo apt install python3-pip
sudo apt install python3-pip
Once pip is available, you can then install Sphinx with::
pip3 install sphinx
pip3 install sphinx
If you run this as an unprivileged user, it may install a local copy of Sphinx
for your user only. The ``sphinx-build`` executable will typically end up in
@ -196,34 +404,23 @@ macOS has Python 2.7 installed by default, but it does not have the pip package
You can install Homebrew's Python 3, which includes pip, and then install the
latest Sphinx using pip::
brew install python3
pip3 install sphinx
Alternatively, you can simply install Sphinx directly from Homebrew::
brew install sphinx-doc
This will install Sphinx for macOS's system Python 2.7, without needing pip.
Either method works; if you plan to use Python for other purposes, it might best
to install Homebrew's Python 3 so that you have the latest Python as well as pip.
If not, just installing sphinx-doc for macOS's system Python 2.7 is fine.
brew install python3
pip3 install sphinx
Windows
-------
Python for Windows can be downloaded `from python.org <https://www.python.org/downloads/>`_.
The latest version of Python 3 is recommended, as it includes pip already.
The latest version of Python 3 includes pip already.
You can also install Python and pip through the Chocolatey package manager.
After installing Chocolatey as outlined in the `Windows compilation instructions <compile-windows>`,
run the following command from an elevated (admin) command prompt (e.g. ``cmd.exe``)::
choco install python pip -y
choco install python pip -y
Once you have pip available, you can install Sphinx with the following command::
pip install sphinx
pip install sphinx
Note that this may require opening a new (admin) command prompt if you just
installed pip from the same command prompt.
@ -258,33 +455,51 @@ ways to do this:
* 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
running another file, such as ``generate-msvc-all.bat``, you will need to edit
it to add the flag. You can also run ``cmake`` on the command line, similar to
other platforms.
the batch script 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.
By default, both HTML and text docs are built by CMake. The generated
documentation is stored in ``docs/html`` and ``docs/text`` (respectively) in the
root DFHack folder, and they will both be installed to ``hack/docs`` when you
install DFHack. The html and txt files will intermingle, but will not interfere
with one another.
Running Sphinx manually
-----------------------
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.
you only want to rebuild the documentation regardless of any code changes. The
``docs/build.py`` script will build the documentation in any specified formats
(HTML only by default) using the same command that CMake runs when building the
docs. Run the script with ``--help`` to see additional options.
Examples:
* ``docs/build.py``
Build just the HTML docs
* ``docs/build.py html text``
Build both the HTML and text docs
* ``docs/build.py --clean``
Build HTML and force a clean build (all source files are re-read)
To build the documentation with default options, run the following command from
the root DFHack folder::
The resulting documentation will be stored in ``docs/html`` and/or ``docs/text``.
Alternatively, you can run Sphinx manually with::
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).
or, to build plain-text output::
sphinx-build -b text . docs/text
Sphinx has many options to enable clean builds, parallel builds, logging, and
more - run ``sphinx-build --help`` for details.
more - run ``sphinx-build --help`` for details. If you specify a different
output path, be warned that Sphinx may overwrite existing files in the output
folder. Also be aware that when running ``sphinx-build`` directly, the
``docs/html`` folder may be polluted with intermediate build files that normally
get written in the cmake ``build`` directory.
Building a PDF version
----------------------
@ -295,10 +510,11 @@ 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
docs/build.py 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.
Alternatively, you can run Sphinx manually with::
sphinx-build -M latexpdf . docs/pdf
.. _build-changelog:
@ -318,17 +534,16 @@ changelogs are combined as part of the changelog build process:
* ``scripts/changelog.txt`` for changes made to scripts in the ``scripts`` repo
* ``library/xml/changelog.txt`` for changes made in the ``df-structures`` repo
Building the changelogs generates two files: ``docs/_auto/news.rst`` and
``docs/_auto/news-dev.rst``. These correspond to `changelog` and `dev-changelog`
and contain changes organized by stable and development DFHack releases,
respectively. For example, an entry listed under "0.44.05-alpha1" in
Building the changelogs generates two files: ``docs/changelogs/news.rst`` and
``docs/changelogs/news-dev.rst``. These correspond to `changelog` and
`dev-changelog` and contain changes organized by stable and development DFHack
releases, respectively. For example, an entry listed under "0.44.05-alpha1" in
changelog.txt will be listed under that version in the development changelog as
well, but under "0.44.05-r1" in the stable changelog (assuming that is the
closest stable release after 0.44.05-alpha1). An entry listed under a stable
release like "0.44.05-r1" in changelog.txt will be listed under that release in
both the stable changelog and the development changelog.
Changelog syntax
----------------

@ -1350,7 +1350,7 @@ Misc improvements
- `createitem`: in adventure mode it now defaults to the controlled unit as maker.
- `autotrade`: adds "(Un)mark All" options to both panes of trade screen.
- `mousequery`: several usability improvements; show live overlay (in menu area) of what's on the tile under the mouse cursor.
- `search`: workshop profile search added.
- `search-plugin`: workshop profile search added.
- `dwarfmonitor`: add screen to summarise preferences of fortress dwarfs.
- `getplants`: add autochop function to automate woodcutting.
- `stocks`: added more filtering and display options.
@ -1510,7 +1510,7 @@ New binary patches
New Plugins
-----------
- `fix-armory`: Together with a couple of binary patches and the `gui/assign-rack` script, this plugin makes weapon racks, armor stands, chests and cabinets in properly designated barracks be used again for storage of squad equipment.
- `search`: Adds an incremental search function to the Stocks, Trading, Stockpile and Unit List screens.
- `search-plugin`: Adds an incremental search function to the Stocks, Trading, Stockpile and Unit List screens.
- `automaterial`: Makes building constructions (walls, floors, fortifications, etc) a little bit easier by saving you from having to trawl through long lists of materials each time you place one.
- Dfusion: Reworked to make use of lua modules, now all the scripts can be used from other scripts.
- Eventful: A collection of lua events, that will allow new ways to interact with df world.

@ -96,13 +96,14 @@ When you `download DFHack <downloading>`, you will end up with a release archive
operating system should have built-in utilities capable of extracting files from
these archives.
The release archives contain several files and folders, including a ``hack``
folder, a ``dfhack-config`` folder, and a ``dfhack.init-example`` file. To
install DFHack, copy all of the files from the DFHack archive into the root DF
folder, which should already include a ``data`` folder and a ``raw`` folder,
among other things. Some packs and other redistributions of Dwarf Fortress may
place DF in another folder, so ensure that the ``hack`` folder ends up next to
the ``data`` folder.
The release archives contain several folders, including a ``hack`` folder where
DFHack binary and system data is stored, a ``dfhack-config`` folder where user
data and configuration is stored, and a ``blueprints`` folder where `quickfort`
blueprints are stored. To install DFHack, copy all of the files from the DFHack
archive into the root DF folder, which should already include a ``data`` folder
and a ``raw`` folder, among other things. Some packs and other redistributions
of Dwarf Fortress may place DF in another folder, so ensure that the ``hack``
folder ends up next to the ``data`` folder.
.. note::

Some files were not shown because too many files have changed in this diff Show More