Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/about/Removed.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ autohauler
==========
An automated labor management tool that only addressed hauling labors, leaving the assignment
of skilled labors entirely up to the player. Fundamentally incompatible with the work detail
system of labor management in v50 of Dwarf Fortress.
system of labor management in v50 of Dwarf Fortress. A dedicated laborer pool for unskilled
jobs (including hauling) is now provided by the `labormanager` command of `autolabor`.

.. _automaterial:

Expand Down
2 changes: 2 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Template for new versions:
- `export-world-map`: Export world map data for GIS and other external tools.

## New Features
- `labormanager`: the `autolabor` plugin now provides a second command that manages labors through the work detail system instead of writing the labor matrix; use ``<cmd> mode legacy|modern`` or the work details overlay to switch
- `labormanager`: track job posting age and show a "task starvation" notification in the DFHack warning panel when any posting sits unclaimed for over a day
- `autodump`: new ``undestroy`` option reverts pending item destruction while the game is still paused
- `buildingplan`: new "Do now" option marks the jobs of subsequently placed buildings as high priority
- `getplants`: new ``--dry-run`` option counts affected plants without designating, and new ``--brewable``/``--edible``/``--oil``/``--cloth``/``--dye`` trait filters restrict the selection by plant use
Expand Down
33 changes: 22 additions & 11 deletions docs/plugins/autolabor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ autolabor
:summary: Automatically manage dwarf labors.
:tags: fort auto labors

The ``autolabor`` command runs the plugin's *legacy* engine, which writes the
labor matrix directly and bypasses the work detail system. The same plugin
also provides the `labormanager` command, a modern engine that works through
the work detail system instead. A third *monitor* mode watches the job
board and shows task starvation warnings without managing labors at all.
Only one mode can be active at a time;
``autolabor mode [legacy|modern|monitor]`` or the overlay on the work
details screen switches between them, and the selected mode persists
across save/load.

Autolabor attempts to keep as many dwarves as possible busy while allowing
dwarves to specialize in specific skills.

Expand Down Expand Up @@ -32,24 +42,21 @@ untouched by autolabor.
logging level using the `debugfilter<debug>` command (setting either ``debug`` or ``trace`` level for the
``cycle`` mode) but be warned that this may generate a large amount of console spam, especially in a large fort.

When it is enabled, autolabor automatically disables the work detail system. You cannot
use autolabor and work details at the same time. If you attempt to open the work detail screen while
autolabor is active, a warning box should appear advising you that autolabor is managing labors and preventing
you from making any changes on that screen.
When it is enabled in legacy mode, autolabor automatically disables the work detail system. You cannot
use legacy autolabor and work details at the same time. The DFHack overlay panel on the work details
screen (the same panel that provides the `gui/settings-manager` save/load buttons) shows the active
mode and warns you when legacy mode is preventing changes on that screen from taking effect.

Finally, should you disable autolabor, autolabor will automatically reenable the vanilla work detail system.
However, the work detail system only updates labors when the work detail screen is open and some change is
made on that screen. Therefore, if you choose to disable autolabor, you should probably immediately
thereafter open the work details screen and make some change to force the game to recompute all labor
assignments based on the vanilla algorithm. At this time, it is not possible for autolabor to do this
automatically.
Should you disable autolabor or switch to modern mode, the vanilla work
detail system is automatically reenabled and all citizens' labors are
recomputed from the work details.

Usage
-----

::

enable autolabor
autolabor enable

Anything beyond this is optional - autolabor works well with the default
settings. Once you have enabled it in a fortress, it stays enabled until you
Expand Down Expand Up @@ -114,5 +121,9 @@ Advanced usage
Turn off autolabor for a specific labor.
``autolabor reset-all|<labor> reset``
Return a labor (or all labors) to the default handling.
``autolabor mode [legacy|modern|monitor]``
Show or change which engine runs when the plugin is enabled. Monitor
mode performs no labor management; it only watches the job board and
reports starving job postings via the DFHack notification panel.

See `autolabor-artisans` for a differently-tuned setup.
248 changes: 141 additions & 107 deletions docs/plugins/labormanager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,131 +2,165 @@ labormanager
============

.. dfhack-tool::
:summary: Automatically manage dwarf labors.
:tags: unavailable

Labormanager is derived from `autolabor` but uses a completely different
approach to assigning jobs to dwarves. While autolabor tries to keep as many
dwarves busy as possible, labormanager instead strives to get jobs done as
quickly as possible.

Labormanager frequently scans the current job list, current list of dwarves, and
the map to determine how many dwarves need to be assigned to what labors in
order to meet all current labor needs without starving any particular type of
job.

Dwarves on active military duty or dwarves assigned to burrows are left
untouched.
:summary: Automatically manage dwarf labors via work details.
:tags: fort auto labors

``labormanager`` is the modern mode of the `autolabor` plugin. Instead of
writing the labor matrix directly, it expresses labor policy through Dwarf
Fortress's work detail system, so the game's job auction chooses which
dwarves take which jobs. The plugin's managed work details are visible on
the work details screen (``u`` -> Labor -> Work Details) with names
beginning with ``auto:``. The DFHack overlay panel on that screen (the
same panel that provides work detail save/load buttons from
`gui/settings-manager`) lets you switch modes and tune the plugin's
priorities.

Since the job auction already prefers skilled dwarves for skilled jobs,
labormanager focuses on the things the auction does poorly:

* **Unskilled job starvation.** The auction tends to starve jobs that
require no skill (hauling, cleaning, lever pulling, and so on) in favor of
skilled work. Labormanager maintains a laborer pool, assigned to the
``auto:Laborers`` work detail and restricted to unskilled labors, so there
are always dwarves that *can only* take unskilled work. The pool grows and
shrinks based on how many unclaimed unskilled job postings are piling up.

* **Skill growth and specialization.** Citizens with a useful skill are
assigned to a specialized ``auto:`` work detail covering the labors that
train that skill, so they spend their time practicing rather than hauling.
If the fortress has a guild hall dedicated to the dwarf's profession,
labormanager also protects some of that specialist's time so they can
participate in guild activities (see ``idle-reserve`` below).

Labormanager keeps statistics on which skills the fortress actually
exercises, based on the job postings that resolve on the job board. That
history shapes specialization:

* **No dead skills.** Skills the fort never uses (animal dissection and
gelding in most forts, for example) get no reserved work detail at all --
a dwarf whose only talent is an unused skill stays a generalist instead
of being pinned to irrelevant work.
* **Demand-weighted specialization.** Frequently-used skills are
prioritized over rarely-used ones when choosing which specialty to
assign, and units skilled in them are protected harder from laborer
duty.
* **Quality skills.** Skills whose products carry skill-scaled quality
(smithing, crafting, cooking, mechanics, engraving, and so on) are
preferred for higher-skilled workers -- both when choosing a specialty
and when deciding who to keep out of the laborer pool.
* **Strange-mood shaping.** Dwarves that can still have a strange mood
(their race has the ``STRANGE_MOODS`` token and they haven't had one
yet) and that have already started a moodable craft are steered toward
skills a strange mood can advance -- preferably valuable ones like
weaponsmithing or armorsmithing -- so a mood pays out in a useful
legendary skill.

Labormanager also reads each citizen's unmet personal needs and biases
assignments toward work that satisfies them:

* Citizens desperate to stay occupied, acquire things, or help others are
preferentially drafted into the laborer pool, where hauling, stockpiling,
depot runs, and patient care satisfy those needs.
* Citizens needing social time (gregarious, family-oriented, or just
wanting to take it easy) are kept out of the restrictive pools so they
can idle and socialize; guilded specialists with these needs earn guild
rest sooner.
* Citizens who crave wandering are steered toward fishing, hunting, and
plant gathering; those craving excitement toward trapping and hunting;
those craving creativity toward crafts. A completely unskilled citizen
can be assigned a specialty purely on inclination.

Dwarves on active military duty, in meetings, or assigned to burrows are
left untouched. Children are unaffected: their chores are governed by the
vanilla chores settings.

.. warning::

As with autolabor, labormanager will override any manual changes you make to
labors while it is enabled, including through other tools such as Dwarf
Therapist. Do not run both autolabor and labormanager at the same time!
While labormanager is enabled it will overwrite the membership of its
``auto:`` work details on every cycle. Player-created work details are
left alone, but manual edits to the managed details will be lost.

Usage
-----

::

enable labormanager

Anything beyond this is optional - labormanager works well with the default
settings. Once you have enabled it in a fortress, it stays enabled until you
explicitly disable it, even if you save and reload your game.

The default priorities for each labor vary (some labors are higher priority by
default than others). The way the plugin works is that, once it determines how
many jobs of each labor are needed, it then sorts them by adjusted priority.
(Labors other than hauling have a bias added to them based on how long it's been
since they were last used to prevent job starvation.) The labor with the highest
priority is selected, the "best fit" dwarf for that labor is assigned to that
labor, and then its priority is *halved*. This process is repeated until either
dwarves or labors run out.

Because there is no easy way to detect how many haulers are actually needed at
any moment, the plugin always ensures that at least one dwarf is assigned to
each of the hauling labors, even if no hauling jobs are detected. At least one
dwarf is always assigned to construction removing and cleaning because these
jobs also cannot be easily detected. Lever pulling is always assigned to
everyone. Any dwarves for which there are no jobs will be assigned hauling,
lever pulling, and cleaning labors. If you use animal trainers, note that
labormanager will misbehave if you assign specific trainers to specific animals;
results are only guaranteed if you use "any trainer".

Labormanager also sometimes assigns extra labors to currently busy dwarfs so
that when they finish their current job, they will go off and do something
useful instead of standing around waiting for a job.

There is special handling to ensure that at least one dwarf is assigned to haul
food whenever food is detected left in a place where it will rot if not stored.
This will cause a dwarf to go idle if you have no stockpiles to haul food to.

Dwarves who are unable to work (child, in the military, wounded, handless,
asleep, in a meeting) are entirely excluded from labor assignment. Any dwarf
explicitly assigned to a burrow will also be completely ignored by labormanager.

The fitness algorithm for assigning jobs to dwarves generally attempts to favor
dwarves who are more skilled over those who are less skilled. It also tries to
avoid assigning female dwarfs with children to jobs that are "outside", favors
assigning "outside" jobs to dwarfs who are carrying a tool that could be used as
a weapon, and tries to minimize how often dwarves have to reequip.

Labormanager automatically determines medical needs and reserves health care
providers as needed. Note that this may cause idling if you have injured dwarves
but no or inadequate hospital facilities.

Hunting is never assigned without a butchery, and fishing is never assigned
without a fishery, and neither of these labors is assigned unless specifically
enabled (see below).

The method by which labormanager determines what labor is needed for a
particular job is complicated and, in places, incomplete. In some situations,
labormanager will detect that it cannot determine what labor is required. It
will, by default, pause and print an error message on the dfhack console,
followed by the message "LABORMANAGER: Game paused so you can investigate the
above message.". If this happens, please open an :issue:`<issue>` on GitHub,
reporting the lines that immediately preceded this message. You can tell
labormanager to ignore this error and carry on by running
``labormanager pause-on-error no``, but be warned that some job may go undone in
this situation.
labormanager enable

Anything beyond this is optional. Once enabled in a fortress, it stays
enabled until you explicitly disable it, even if you save and reload your
game.

The same plugin binary also provides the legacy `autolabor` command, which
uses the classic labor-matrix algorithm, and a *monitor* mode that does no
labor management at all -- it only watches the job board and reports
starving job postings (see the end of this document). Only one mode can be
active at a time; use ``labormanager mode`` (or the overlay on the work
details screen) to see or change which mode will run.

Examples
--------

``labormanager priority BREWER 500``
Boost the priority of brewing jobs.
``labormanager max FISH 1``
Only assign fishing to one dwarf at a time. Note that you also have to run
``labormanager allow-fishing`` for any dwarves to be assigned fishing at
all.
``labormanager balance staffing``
Prioritize preventing unskilled jobs from starving. Specialists will be
pulled into the laborer pool more aggressively when hauling backs up.
``labormanager balance skills``
Prioritize skill growth. Specialists keep their specialized labors even
when unskilled work is piling up.
``labormanager labor MINE unmanaged``
Leave the mining labor to the vanilla work details and any manual
assignments, while managing everything else.

Advanced usage
--------------

``labormanager list``
Show current priorities and current allocation stats. Use this command to
see the IDs for all labors.
List every labor, whether labormanager is managing it, and which labors
currently have starving (long-unclaimed) job postings.
``labormanager status``
Show basic status information.
``labormanager priority <labor> <value>``
Set the priority value for labor <labor> to <value>.
``labormanager max <labor> <value>``
Set the maximum number of dwarves that can be assigned to a labor.
``labormanager max <labor> none``
Unrestrict the number of dwarves that can be assigned to a labor.
``labormanager max <labor> disable``
Don't manage the specified labor. Dwarves who you have manually enabled this
labor on will be less likely to have managed labors assigned to them.
``labormanager reset-all|reset <labor>``
Return a labor (or all labors) to the default priority.
Show the current balance setting, role counts, job board statistics
(how many postings resolved, their average and longest waits, and how
many are currently starving), and the most-used skills observed on the
job board.
``labormanager balance <0-4|staffing|lean-staffing|balanced|lean-skills|skills>``
Set where the balance slider sits. Lower values grow the laborer pool
more aggressively to keep unskilled jobs staffed; higher values protect
skill specialization. This is the same control shown as a slider on the
work details overlay.
``labormanager idle-reserve <0-100>``
Percentage of time to keep free for specialists whose profession has a
matching guild hall, so they can take part in guild demonstrations and
other off-duty activities. Defaults to 30.
``labormanager labor <labor> managed|unmanaged``
Include or exclude a specific labor from labormanager's work details.
Unmanaged labors are entirely governed by the player's own work detail
configuration.
``labormanager allow-fishing|forbid-fishing``
Allow/disallow fisherdwarves. *Warning* Allowing fishing tends to result in
most of the fort going fishing. Fishing is forbidden by default.
Allow/disallow fisherdwarf specialists. Fishing is forbidden by default
and also requires a fishery.
``labormanager allow-hunting|forbid-hunting``
Allow/disallow hunterdwarves. *Warning* Allowing hunting tends to result in
as many dwarves going hunting as you have crossbows. Hunting is forbidden by
default.
``labormanager pause-on-error yes|no``
Make labormanager pause/continue if the labor inference engine fails. See
the above section for details.
Allow/disallow hunter specialists. Hunting is forbidden by default and
also requires a butchery.
``labormanager mode [legacy|modern|monitor]``
Show or change which engine runs when the plugin is enabled. The same
command exists under `autolabor`. In monitor mode the plugin performs
no labor management -- all work details are left to the player -- but
still tracks the job board and shows the task starvation warning.

Monitor mode (``labormanager mode monitor`` or the work details overlay)
runs the same tracking without any labor management, for players who want
the starvation warning while keeping full manual control.

The tracking works as follows: job postings that sit unclaimed on the job
board are timed, and if any posting goes more than a full game day (1200
ticks) without being
claimed, a "task starvation" warning appears in the DFHack notification
panel (alongside the other fort warnings), naming the longest-starving
job and how long it has been waiting; clicking the warning zooms the map
to that job's location. The warning can be toggled in `gui/notify` under
``labor_starvation``.

All of labormanager's accumulated state -- job posting ages, skill usage
history, starvation streaks, and the guild rest rotation -- is saved with
the fortress and restored when the save is loaded, so statistics and
rotation carry over between play sessions.
17 changes: 14 additions & 3 deletions plugins/autolabor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
project(autolabor)
# A list of source files
set(COMMON_SRCS
joblabormapper.cpp
laborcommon.cpp
workdetails.cpp
legacyengine.cpp
modernengine.cpp
)
# A list of headers
set(COMMON_HDRS laborstatemap.h
set(COMMON_HDRS
laborstatemap.h
joblabormapper.h
laborcommon.h
workdetails.h
engines.h
legacyengine.h
modernengine.h
monitorengine.h
)
set_source_files_properties(${COMMON_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE)

# mash them together (headers are marked as headers and nothing will try to compile them)
list(APPEND COMMON_SRCS ${COMMON_HDRS})

#dfhack_plugin(labormanager labormanager.cpp joblabormapper.cpp ${COMMON_SRCS})

dfhack_plugin(autolabor autolabor.cpp ${COMMON_SRCS} LINK_LIBRARIES lua)
Loading
Loading