github DFHack/dfhack 51.06-r2rc1
DFHack 51.06-r2rc1

pre-release13 hours ago

Q: How do I download DFHack?

A: Either add to your Steam library from our Steam page or scroll to the latest release on our GitHub releases page, expand the "Assets" list, and download the file for your platform (e.g. dfhack-XX.XX-rX-Windows-64bit.zip. If you are on Windows and are manually installing from the zip file, please remember to right click on the file after downloading, open the file properties, and select the "Unblock" checkbox. This will prevent issues with Windows antivirus programs.

This is a beta release, so if you're installing from Steam, be sure to select the beta branch for DFHack in your Steam client.

If you are on the Steam DF experimental branch, please also switch DFHack to its experimental branch in your Steam client.


This release is compatible with all distributions of Dwarf Fortress: Steam, Itch, and Classic.

Please report any issues (or feature requests) on the DFHack GitHub issue tracker. When reporting issues, please upload a zip file of your savegame and a zip file of your mods directory to the cloud and add links to the GitHub issue. Make sure your files are downloadable by "everyone with the link". We need your savegame to reproduce the problem and test the fix, and we need your active mods so we can load your savegame. Issues with savegames and mods attached get fixed first!

Highlights

Follow your dwarves like a pro, or watch them like a fish tank, Skip adventure messages, Attach notes to the map, Schedule cheese making according to milk supplies

Follow your dwarves like a pro, or watch them like a fish tank

The spectate tool has had a complete overhaul, and is now integrated into the vanilla follow mode. There are lots of ways you can interact with it.

If you start following a dwarf by clicking on the vanilla "camera" button, you'll see that the little panel that shows up in the lower left corner has a few more widgets on it. You can hit the right arrow key (or click on the icon) to follow another target, or you can hit the left arrow key (or click on the icon) to follow the previous target. This means you can quickly switch to a new dwarf and then back to a previous dwarf just by tapping the arrow keys.

specate_panel

There is also an indicator for whether "spectate mode" is on. If you turn it on, you can let the game run and spectate will periodically shift the camera to follow a different dwarf. If you've managed to get your fort into a stable state, this is a good way to sit back, relax, and watch your dwarves like a fish tank.

image

How does it choose the next dwarf to follow? It's random, but you can tweak how it chooses targets with the new gui/spectate interface. You can launch it by clicking on the gear icon on the follow panel, where the new left and right arrow widgets are. You can choose which kinds of units other than your own dwarves to include as possible targets, like livestock, enemies, or visitors. By default, the camera will prefer to follow units that are in combat and units that have newly arrived on the map.

image

If spectate mode is enabled and the new "cinematic action" option is on, the camera will even switch targets more quickly when there is combat afoot! If the "Auto unpause" option is on, events that would normally pause the game, like sieges or artifact announcements, will not pause the game at all. This allows a "true" fish tank mode where you can see your beautiful fort rise and fall of its own accord.

Spectate mode will automatically disengage when you jump in to take control. It switches off when you move the camera: the exact same way that vanilla follow mode switches off. Spectate mode will also disengage when you open the squads panel.

We've also made it easier to jump to following a specific target. There is a new global hotkey: Ctrl-g (for "go to"). It is available when you are on the main dwarf map (or the main adventure map, but "follow" mode isn't relevant there).

image

Ctrl-g will pop up the gui/sitemap interface. You can start typing to search for a name, and Shift-click or Shift-Enter will start following that unit directly!

image

But wait, there's more!

You can also use gui/spectate to configure live tooltips for your dwarves. If you turn on the spectate.tooltips overlay, you can display information like their name, their current happiness level, and their current job. The "Follow" set of toggles controls what information will follow your dwarves around on the map in floating tooltips. The "Hover" set of toggles controls what information will be shown in a pop up when you hover your mouse over a unit.

image

Give it a try! My favorite configuration so far is:

  • "Follow" shows an indicator for miserable and unhappy dwarves
  • "Hover" shows the current stress level, name, and job

In graphics mode, you might prefer to set the blink period to 0 (to disable it), but in ascii mode, you'll want the "follow" tooltips to blink periodically so you can see what they are covering on the map.

image

Skip adventure messages

The new advtools.fastcombat overlay allows you to skip combat animations and the announcement "More" button. If you're trying to walk through a populated area, this can be a huge time (and click) saver! Have you heard the one about the elf and the elf? Yes, we have! Let us walk across the room!

image

Now, to skip all the "More" messages, just hit any movement key. The first movement key will skip the messages to the end of the list. Hit the key again to move. It works the same with the mouse. The first click on the map will skip all messages to the end, and the second click will start your adventurer walking to that destination.

Attach notes to the map

We now have a tool for attaching notes to fort map tiles! gui/notes is the UI for adding and managing map notes. You can memorialize events where they occurred

image

or leave design plans for yourself on the levels where you plan to expand your fort.

image

Schedule cheese making according to milk supplies

Cheese making is difficult to automate using work orders. A single job can consume anything from a bucket with a single unit of milk to a barrel with 100 units of milk. This makes it hard to predict how much cheese will actually be produced by a regular manager work order.

If you enable autocheese in the DFHack control panel, it will scan your fort for barrels with a certain minimum amount of milk (default: 50), create a cheese making job specifically for that barrel, and assign this job to one of your idle dwarves (giving preference to skilled cheese makers).

image

Easy cheesy!

Announcements

Why beta?, PSAs

So why is this a beta?

In addition to the new features (which we always need feedback on!), DFHack has undergone an extensive internal reorganization to help align the code closer to how the internal DF structures are organized. For scripts, many of the df namespace paths have changed. If you are maintaining an out-of-tree script, find out what identifiers have changed in the Structures release notes below.

As a player, please keep an eye out for commands that return errors when you run them or functionality that appears not to work like it used to. It is possible that typos have crept in with all the updates.

PSAs

As always, remember that, just like the vanilla DF game, DFHack tools can also have bugs. It is a good idea to save often and keep backups of the forts that you care about.

Some DFHack tools that worked in previous (pre-Steam) versions of DF have not been updated yet and are marked with the "unavailable" tag in their docs. If you try to run them, they will show a warning and exit immediately. You can run the command again to override the warning (though of course the tools may not work). We make no guarantees of reliability for the tools that are marked as "unavailable".

The in-game interface for running DFHack commands (gui/launcher) will not show "unavailable" tools by default. You can still run them if you know their names, or you can turn on dev mode by hitting Ctrl-D while in gui/launcher and they will be added to the autocomplete list. Some tools listed as "unavailable" in the docs do not compile yet and are not accessible at all, even when in dev mode.

If you see a tool complaining about the lack of a cursor, know that it's referring to the keyboard cursor (which used to be the only real option in Dwarf Fortress). You can enable the keyboard cursor by entering mining mode or selecting the dump/forbid tool and hitting Alt-K (the DFHack keybinding for toggle-kbd-cursor). We're working on making DFHack tools more mouse-aware and accessible so this step isn't necessary in the future.

Changelog

New tools, fixes, and improvements

New Tools

  • autocheese: automatically make cheese using barrels that have accumulated sufficient milk
  • devel/export-map: export map tile data to a JSON file
  • gui/notes: UI for adding and managing notes attached to tiles on the map
  • gui/spectate: interactive UI for configuring new spectate features

New Features

  • advtools: new advtools.fastcombat overlay (enabled by default) allows you to skip combat animations and the announcement "More" button by mashing the movement keys
  • gui/sitemap: is now the official "go to" tool. new global hotkey for fort and adventure mode: Ctrl-G
  • spectate:
    • can now specify number of seconds (in real time) before switching to follow a new unit
    • new "cinematic-action" mode that dynamically speeds up perspective switches based on intensity of conflict
    • new global keybinding for toggling spectate mode: Ctrl-Shift-S
    • new overlay panel that allows you to cycle through following next/previous units (regardless of whether spectate mode is enabled)

Fixes

  • Windows console: fix possible hang if the console returns a too-small window width (for any reason)
  • changevein: fix a crash that could occur when attempting to change a vein into itself
  • createitem: produced items will now end up at the look cursor position (if it is active)
  • gui/liquids: using the remove tool with magma selected will no longer create unexpected unpathable tiles
  • overlay: reset draw context between rendering widgets so context changes can't propagate from widget to widget
  • position: support for adv mode look cursor
  • spectate: don't allow temporarily modified announcement settings to be written to disk when "auto-unpause" mode is enabled
  • stonesense:
    • megashots no longer leave stonesense unresponsive
    • items now properly render on top of stockpile indicators
    • minecarts and wheelbarrows are now shown on the correct layer

Misc Improvements

  • autobutcher: treat animals on restraints as unavailable for slaughter
  • gui/confirm: in the delete manager order confirmation dialog, show a description of which order you have selected to delete
  • gui/design: only display vanilla dimensions tooltip if the DFHack dimensions tooltip is disabled
  • gui/notify:
    • moody dwarf notification turns red when they can't reach workshop or items
    • save reminder now appears in adventure mode
    • save reminder changes color to yellow at 30 minutes and to orange at 60 minutes
  • gui/sitemap: shift click to start following the selected unit or artifact
  • hide-tutorials:
    • handle tutorial popups for adventure mode
    • new reset command that will re-enable popups in the current game (in case you hid them all and now want them back)
  • position:
    • add adventurer tile position
    • add global site position
    • when a tile is selected, display relevant map block and intra-block offset
  • prioritize:
    • when prioritizing jobs of a specified type, also output how many of those jobs were already prioritized before you ran the command
    • don't include already-prioritized jobs in the output of prioritize -j
  • spectate: player-set configuration is now stored globally instead of per-fort
  • stockpiles: add property filters for brewable, millable, and processable (e.g. at a Farmer's workshop) organic materials
  • stonesense: different types of dig-mode designations (normal, autodig, and the blueprint variants of both) now have distinct colors that more closely match the vanilla DF interface

Documentation

  • stonesense-art-guide: guide for making sprite art for Stonesense

Removed

  • orders: MakeCheese job removed from library/basic orders set. Please use autocheese instead!
  • stonesense: removed the "follow DF cursor" tracking mode since the keyboard cursor is no longer commonly used for moving the map around

API

  • Buildings::checkFreeTiles: now takes a building instead of a pointer to the building extents
  • Items::getItemBaseValue: adjust to the reduced value of prepared meals (changed in DF 51.06)
  • Items::getValue: magical powers now correctly contribute to item value
  • Military::removeFromSquad: removes unit from any squad assignments
  • Units::isUnitInBox, Units::getUnitsInBox: don't include inactive units

Lua

  • dfhack.buildings.checkFreeTiles: now takes a building pointer instead of an extents parameter
  • dfhack.military.removeFromSquad: Lua API for Military::removeFromSquad
  • dfhack.units.setAutomaticProfessions: sets unit labors according to current work detail settings
  • gui.dwarfmode: adventure mode cursor now supported in getCursorPos, setCursorPos, and clearCursorPos funcitons
  • overlay.isOverlayEnabled: new API for querying whether a given overlay is enabled
  • overlay: widgets can now declare overlay_onenable and overlay_ondisable functions to hook enable/disable

Structures

  • create numerous new structures whose contents had previously been missing or inlined into other structures
  • fix a variety of structure errors
  • merged several duplicate structure/enum types
  • promote all bay12 structures, enums, and bitfields to top-level types: this means that most T_* types now have top-level names
  • reorganize all structure definitions to match bay12 header layouts
  • specific changes:
    • Building vmethod countHospitalSupplies now returns abstract_building_contents instead of hospital_supplies, which has different field names
    • When indexing into a vector named scribejobs, replace item_id and written_content_id with target_id and relevant_id
    • conversation_state_type.DenyPermissionSleep is now SleepPermissionRequested
    • block_square_event_spoorst.[whatever] is now block_square_event_spoorst.info.[whatever]
    • building_stockpilest.max_*/container_* is now building_stockpilest.storage.max_*/container_*
    • building_civzonest.zone_settings.pen is now building_civzonest.zone_settings.pen.flags
    • building_civzonest.zone_settings.tomb is now building_civzonest.zone_settings.tomb.flags
    • building_bridgest.gate_flags.closed/closing/opening are now raised/raising/lowering
    • building_weaponst.gate_flags.closed/closing/opening are now retracted/retracting/unretracting
    • building.design.builder1/builder1_civ/builder2 are now .worker/worker_create_event/curworker (and the 2nd is a History Event, not an Entity)
    • stockpile_settings.allow_organic/allow_inorganic are now stockpile_settings.misc.allow_organic/allow_inorganic
    • world.busy_buildings[] is now world.building_uses.buildings[]
    • world.coin_batches is now world.coin_batches.all
    • spatter.flags.water_soluble is now external
    • creation_zone_pwg_alteration_campst.tent_matlgoss is now .tent_matgloss (spelling fix)
    • world.raws.body_templates and world.raws.bodyglosses are now world.raws.creaturebody.*
    • world.raws.tissue_templates/body_detail_plans/creature_variations are now world.raws.*.all
    • material_force_adjustst.mat_indx is now mat_index (spelling fix)
    • game.minimap.minimap[x][y] is now game.minimap.minimap[x][y].tile
    • historical_entity.relations.diplomacy[] is now historical_entity.relations.diplomacy.state[]
    • historical_entity.conquered_site_group_flags is now historical_entity.law.conquered_site_group_flags
    • world.effects is now world.effects.all
    • world.raws.entities is now world.raws.entities.all
    • site_type enum deleted, merged with world_site_type
    • world.event.dirty_waters[].* is now world.event.dirty_waters[].pos.*
    • death_condition_type enum replaced with histfig_body_state (notably in state_profilest.body_state)
    • history_hit_item, history_event_reason_info, and history_event_circumstance_info removed and substituted
    • knowledge_profilest.known_locations.ab_review[] is now .reports[] (because .known_locations got merged with site_reputation_info)
    • world.raws.interactions[] is now world.raws.interactions.all[]
    • itemdef_instrumentst.registers/timbre are now itemdef_instrumentst.timbre.registers/timbre
    • dye_info removed and substituted
    • job_art_specification removed and substituted
    • entity_activity_statistics.discovered_(creature_foods/creatures/plant_foods/plants) is now entity_activity_statistics.knowledge.*
    • world.mandates[] is now world.mandates.all[]
    • creature_interaction_effect.counter_trigger.required is now creature_interaction_effect.counter_trigger.flag.bits.REQUIRED
    • creature_interaction_effect_target removed and substituted
    • material_common removed, its contents prepended to material and material_template
    • world.raws.material_templates is now world.raws.material_templates.all
    • world.raws.syndromes is now world.raws.mat_table.syndromes
    • world.raws.effects is now world.raws.mat_table.effects
    • world.raws.inorganics is now world.raws.inorganics.all
    • world.raws.inorganics_subset is now world.raws.inorganics.cheap
    • plotinfo.main.selected_hotkey/in_rename_hotkey are now plotinfo.main.hotkey_interface.*
    • world.proj_list is now world.projectiles.all
    • general_ref_building_well_tag.direction is now a bitfield
    • world_region_details.edges.(split_x/split_y)[][].x/y are now .break_one/break_two
    • world_population_ref.depth is now world_population_ref.layer_depth and is now an integer instead of an enum
    • Bitfield region_weather_flag is now region_weather_bits (to avoid conflicts)
    • Rhythm beat_flag realigned (PrimaryAccent removed, because it wasn't really a unique flag)
    • dipscript_info.script_steps/script_vars are now dipscript_info.script.steps/vars
    • script_step_discussst.event is now script_step_discussst.duration
    • script_step_dipeventst and script_step_invasionst fields renamed
    • site_architecture_changest.spec_flag is now a tagged union
    • squad.schedule[x][y] is now squad.schedule.routine[x].month[y]
    • world.unit_chunks is now world.unit_chunks.all
    • historical_entity.events[] is now historical_entity.rumor_info.events
    • world.enemy_status_cache.rel_map[x][y] is now world.enemy_status_cache.rel_map[x][y].ur
    • unit.curse.interaction_id/interaction_time/interaction_delay/time_on_site/own_interaction/own_interaction_delay are now unit.curse.interaction.*
    • unit.cached_glowtile_type is now unit.cache.cached_glowtile_type
    • unit_preference.active is now unit_preference.flags.visible
    • witness_report_flags replaced with correct flags
    • caste_body_info.clothing_items.[] is now caste_body_info.clothing_items.bp[]
    • plant_tree_tile.branches_dir enum collapsed into 4 simple flags
    • world.populations is now world.populations.all
    • world_data.constructions.map[x][y][N] is now world_data.constructions.map[x][y].square[N]
    • world.family_info[] is now world.family_info.family[]
    • world.fake_world_info[] is now world.fake_world_info.language[]
    • world.selected_direction is now world.selected_direction[0] (and there are 3 additional entries)

Don't miss a new dfhack release

NewReleases is sending notifications on new releases.