Scripts for Modders

modtools/* scripts provide tools for modders, often with changes to the raw files, and are not intended to be called manually by end-users.

They all have standard arguments: arguments are of the form tool -argName1 argVal1 -argName2 argVal2. This is equivalent to tool -argName2 argVal2 -argName1 argVal1. It is not necessary to provide a value to an argument name: tool -argName3 is fine.

Argument names are preceded with a dash, and supplying the same argument name multiple times will result in an error.

The -help argument to any modtools script will print a descriptive usage string describing the arguments, similar to the documentation here.

For multiple word argument values, brackets must be used: tool -argName4 [ sadf1 sadf2 sadf3 ]. In order to allow passing literal braces as part of the argument, backslashes are used: tool -argName4 [ \] asdf \foo ] sets argName4 to \] asdf foo. The *-trigger scripts have a similar policy with backslashes.

modtools/add-syndrome

This allows adding and removing syndromes from units.

Arguments:

-syndrome name
    the name of the syndrome to operate on
    examples:
        "gila monster bite"
-resetPolicy policy
    specify a policy of what to do if the unit already has an
    instance of the syndrome.  examples:
        NewInstance
            default behavior: create a new instance of the syndrome
        DoNothing
        ResetDuration
        AddDuration
-erase
    instead of adding an instance of the syndrome, erase one
-eraseAll
    erase every instance of the syndrome
-eraseClass SYN_CLASS
    erase every instance of every syndrome with the given SYN_CLASS
-target id
    the unit id of the target unit
    examples:
        0
        28
-skipImmunities
    add the syndrome to the target even if it is immune to the syndrome

modtools/anonymous-script

This allows running a short simple Lua script passed as an argument instead of running a script from a file. This is useful when you want to do something too complicated to make with the existing modtools, but too simple to be worth its own script file. Example:

anonymous-script "print(args[1])" arg1 arg2
# prints "arg1"

modtools/change-build-menu

Change the build sidebar menus.

This script provides a flexible and comprehensive system for adding and removing items from the build sidebar menus. You can add or remove workshops/furnaces by text ID, or you can add/remove ANY building via a numeric building ID triplet.

Changes made with this script do not survive a save/load. You will need to redo your changes each time the world loads.

Just to be clear: You CANNOT use this script AT ALL if there is no world loaded!

Usage:

modtools/change-build-menu start|enable:

enable modtools/change-build-menu:

Start the ticker. This needs to be done before any changes will take effect. Note that you can make changes before or after starting the ticker, both options should work equally well.

modtools/change-build-menu stop|disable:

disable modtools/change-build-menu:

Stop the ticker. Does not clear stored changes. The ticker will automatically stop when the current world is unloaded.

modtools/change-build-menu add <ID> <CATEGORY> [<KEY>]:

Add the workshop or furnace with the ID <ID> to <CATEGORY>. <KEY> is an optional DF hotkey ID.

<CATEGORY> may be one of:
  • MAIN_PAGE
  • SIEGE_ENGINES
  • TRAPS
  • WORKSHOPS
  • FURNACES
  • CONSTRUCTIONS
  • MACHINES
  • CONSTRUCTIONS_TRACK
Valid <ID> values for hardcoded buildings are as follows:
  • CARPENTERS
  • FARMERS
  • MASONS
  • CRAFTSDWARFS
  • JEWELERS
  • METALSMITHSFORGE
  • MAGMAFORGE
  • BOWYERS
  • MECHANICS
  • SIEGE
  • BUTCHERS
  • LEATHERWORKS
  • TANNERS
  • CLOTHIERS
  • FISHERY
  • STILL
  • LOOM
  • QUERN
  • KENNELS
  • ASHERY
  • KITCHEN
  • DYERS
  • TOOL
  • MILLSTONE
  • WOOD_FURNACE
  • SMELTER
  • GLASS_FURNACE
  • MAGMA_SMELTER
  • MAGMA_GLASS_FURNACE
  • MAGMA_KILN
  • KILN

modtools/change-build-menu remove <ID> <CATEGORY>:

Remove the workshop or furnace with the ID <ID> from <CATEGORY>.

<CATEGORY> and <ID> may have the same values as for the “add” option.

modtools/change-build-menu revert <ID> <CATEGORY>:

Revert an earlier remove or add operation. It is NOT safe to “remove” an “add”ed building or vice versa, use this option to reverse any changes you no longer want/need.

Module Usage:

To use this script as a module put the following somewhere in your own script:

local buildmenu = reqscript "change-build-menu"

Then you can call the functions documented here like so:

  • Example: Remove the carpenters workshop:

    buildmenu.ChangeBuilding("CARPENTERS", "WORKSHOPS", false)
    
  • Example: Make it impossible to build walls (not recommended!):

    local typ, styp = df.building_type.Construction, df.construction_type.Wall
    buildmenu.ChangeBuildingAdv(typ, styp, -1, "CONSTRUCTIONS", false)
    

Note that to allow any of your changes to take effect you need to start the ticker. See the “Command Usage” section.

Global Functions:

GetWShopID(btype, bsubtype, bcustom):
GetWShopID returns a workshop’s or furnace’s string ID based on its numeric ID triplet. This string ID should match what is expected by eventful for hardcoded buildings.
GetWShopType(id):
GetWShopIDs returns a workshop or furnace’s ID numbers as a table. The passed in ID should be the building’s string identifier, it makes no difference if it is a custom building or a hardcoded one. The return table is structured like so: {type, subtype, custom}
IsEntityPermitted(id):
IsEntityPermitted returns true if DF would normally allow you to build a workshop or furnace. Use this if you want to change a building, but only if it is permitted in the current entity. You do not need to specify an entity, the current fortress race is used.

ChangeBuilding(id, category, [add, [key]]):

ChangeBuildingAdv(typ, subtyp, custom, category, [add, [key]]):

These two functions apply changes to the build sidebar menus. If “add” is true then the building is added to the specified category, else it is removed. When adding you may specify “key”, a string DF hotkey ID.

The first version of this function takes a workshop or furnace ID as a string, the second takes a numeric ID triplet (which can specify any building, not just workshops or furnaces).

RevertBuildingChanges(id, category):

RevertBuildingChangesAdv(typ, subtyp, custom, category):
These two functions revert changes made by “ChangeBuilding” and “ChangeBuildingAdv”. Like those two functions there are two versions, a simple one that takes a string ID and one that takes a numeric ID triplet.

modtools/create-item

Replaces the createitem plugin, with standard arguments. The other versions will be phased out in a later version.

Arguments:

-creator id
    specify the id of the unit who will create the item,
    or \\LAST to indicate the unit with id df.global.unit_next_id-1
    examples:
        0
        2
        \\LAST
-material matstring
    specify the material of the item to be created
    examples:
        INORGANIC:IRON
        CREATURE_MAT:DWARF:BRAIN
        PLANT_MAT:MUSHROOM_HELMET_PLUMP:DRINK
-item itemstr
    specify the itemdef of the item to be created
    examples:
        WEAPON:ITEM_WEAPON_PICK
-matchingShoes
    create two of this item
-matchingGloves
    create two of this item, and set handedness appropriately

modtools/create-unit

Creates a unit. Usage:

-race raceName
    specify the race of the unit to be created
    examples:
        DWARF
        HUMAN
-caste casteName
    specify the caste of the unit to be created
    examples:
        MALE
        FEMALE
-domesticate
    tames the unit if it lacks the CAN_LEARN and CAN_SPEAK tokens
-civId id
    Make the created unit a member of the specified civ
    (or none if id = -1).  If id is \\LOCAL, make it a member of the
    civ associated with the fort; otherwise id must be an integer
-groupId id
    Make the created unit a member of the specified group
    (or none if id = -1).  If id is \\LOCAL, make it a member of the
    group associated with the fort; otherwise id must be an integer
-setUnitToFort
    Sets the groupId and civId to the local fort
    Can be used instead of -civId \\LOCAL and -groupId \\LOCAL
-name entityRawName
    set the unit's name to be a random name appropriate for the
    given entity.  examples:
        MOUNTAIN
-nick nickname
    set the unit's nickname directly
-location [ x y z ]
    create the unit at the specified coordinates
-age howOld
    set the birth date of the unit by current age
-flagSet [ flag1 flag2 ... ]
    set the specified unit flags in the new unit to true
    flags may be selected from df.unit_flags1, df.unit_flags2,
    or df.unit_flags3
-flagClear [ flag1 flag2 ... ]
    set the specified unit flags in the new unit to false
    flags may be selected from df.unit_flags1, df.unit_flags2,
    or df.unit_flags3

modtools/equip-item

Force a unit to equip an item with a particular body part; useful in conjunction with the create scripts above. See also forceequip.

modtools/extra-gamelog

This script writes extra information to the gamelog. This is useful for tools like Soundsense.

modtools/force

This tool triggers events like megabeasts, caravans, and migrants.

Usage:

-eventType event
    specify the type of the event to trigger
    examples:
        MegaBeast
        Migrants
        Caravan
        Diplomat
        WildlifeCurious
        WildlifeMischievous
        WildlifeFlier
        NightCreature
-civ entity
    specify the civ of the event, if applicable
    examples:
        player
        MOUNTAIN
        EVIL
        28

modtools/if-entity

Run a command if the current entity matches a given ID.

To use this script effectively it needs to be called from “raw/onload.init”. Calling this from the main dfhack.init file will do nothing, as no world has been loaded yet.

Usage:

  • id:
    Specify the entity ID to match
  • cmd [ commandStrs ]:
    Specify the command to be run if the current entity matches the entity given via -id

All arguments are required.

Example:

# Print a message if you load an elf fort, but not a dwarf, human, etc # fort. if-entity -id “FOREST” -cmd [ lua “print(‘Dirty hippies.’)” ]

modtools/interaction-trigger

This triggers events when a unit uses an interaction on another. It works by scanning the announcements for the correct attack verb, so the attack verb must be specified in the interaction. It includes an option to suppress this announcement after it finds it.

Usage:

-clear
    unregisters all triggers
-onAttackStr str
    trigger the command when the attack verb is "str". both onAttackStr and onDefendStr MUST be specified
-onDefendStr str
    trigger the command when the defend verb is "str". both onAttackStr and onDefendStr MUST be specified
-suppressAttack
    delete the attack announcement from the combat logs
-suppressDefend
    delete the defend announcement from the combat logs
-command [ commandStrs ]
    specify the command to be executed
    commandStrs
        \\ATTACK_VERB
        \\DEFEND_VERB
        \\ATTACKER_ID
        \\DEFENDER_ID
        \\ATTACK_REPORT
        \\DEFEND_REPORT
        \\anything -> \anything
        anything -> anything

You must specify both an attack string and a defend string to guarantee correct performance. Either will trigger the script when it happens, but it will not be triggered twice in a row if both happen.

modtools/invader-item-destroyer

This tool configurably destroys invader items to prevent clutter or to prevent the player from getting tools exclusive to certain races.

Arguments:

-clear
    reset all registered data
-allEntities [true/false]
    set whether it should delete items from invaders from any civ
-allItems [true/false]
    set whether it should delete all invader items regardless of
    type when an appropriate invader dies
-item itemdef
    set a particular itemdef to be destroyed when an invader
    from an appropriate civ dies.  examples:
        ITEM_WEAPON_PICK
-entity entityName
    set a particular entity up so that its invaders destroy their
    items shortly after death.  examples:
        MOUNTAIN
        EVIL

modtools/item-trigger

This powerful tool triggers DFHack commands when a unit equips, unequips, or attacks another unit with specified item types, specified item materials, or specified item contaminants.

Arguments:

-clear
    clear all registered triggers
-checkAttackEvery n
    check the attack event at least every n ticks
-checkInventoryEvery n
    check inventory event at least every n ticks
-itemType type
    trigger the command for items of this type
    examples:
        ITEM_WEAPON_PICK
        RING
-onStrike
    trigger the command on appropriate weapon strikes
-onEquip mode
    trigger the command when someone equips an appropriate item
    Optionally, the equipment mode can be specified
    Possible values for mode:
        Hauled
        Weapon
        Worn
        Piercing
        Flask
        WrappedAround
        StuckIn
        InMouth
        Pet
        SewnInto
        Strapped
    multiple values can be specified simultaneously
    example: -onEquip [ Weapon Worn Hauled ]
-onUnequip mode
    trigger the command when someone unequips an appropriate item
    see above note regarding 'mode' values
-material mat
    trigger the commmand on items with the given material
    examples
        INORGANIC:IRON
        CREATURE:DWARF:BRAIN
        PLANT:OAK:WOOD
-contaminant mat
    trigger the command for items with a given material contaminant
    examples
        INORGANIC:GOLD
        CREATURE:HUMAN:BLOOD
        PLANT:MUSHROOM_HELMET_PLUMP:DRINK
        WATER
-command [ commandStrs ]
    specify the command to be executed
    commandStrs
        \\ATTACKER_ID
        \\DEFENDER_ID
        \\ITEM_MATERIAL
        \\ITEM_MATERIAL_TYPE
        \\ITEM_ID
        \\ITEM_TYPE
        \\CONTAMINANT_MATERIAL
        \\CONTAMINANT_MATERIAL_TYPE
        \\CONTAMINANT_MATERIAL_INDEX
        \\MODE
        \\UNIT_ID
        \\anything -> \anything
        anything -> anything

modtools/moddable-gods

This is a standardized version of Putnam’s moddableGods script. It allows you to create gods on the command-line.

Arguments:

-name godName
    sets the name of the god to godName
    if there's already a god of that name, the script halts
-spheres [ sphereList ]
    define a space-separated list of spheres of influence of the god
-depictedAs str
    often depicted as a str
-domain str
    set the domain of the god
-description str
    set the description of the god

modtools/outside-only

This allows you to specify certain custom buildings as outside only, or inside only. If the player attempts to build a building in an inappropriate location, the building will be destroyed.

Arguments:

-clear
    clears the list of registered buildings
-checkEvery n
    set how often existing buildings are checked for whether they
    are in the appropriate location to n ticks
-type [EITHER, OUTSIDE_ONLY, INSIDE_ONLY]
    specify what sort of restriction to put on the building
-building name
    specify the id of the building

modtools/projectile-trigger

This triggers dfhack commands when projectiles hit their targets. Usage:

-clear
    unregister all triggers
-material
    specify a material for projectiles that will trigger the command
    examples:
        INORGANIC:IRON
        CREATURE_MAT:DWARF:BRAIN
        PLANT_MAT:MUSHROOM_HELMET_PLUMP:DRINK
-command [ commandList ]
    \\LOCATION
    \\PROJECTILE_ID
    \\FIRER_ID
    \\anything -> \anything
    anything -> anything

modtools/random-trigger

Trigger random dfhack commands with specified probabilities. Register a few scripts, then tell it to “go” and it will pick one based on the probability weights you specified.

Events are mutually-exclusive - register a list of scripts along with relative weights, then tell the script to select and run one with the specified probabilities. The weights must be positive integers, but they do NOT have to sum to any particular number.

The outcomes are mutually exclusive: only one will be triggered. If you want multiple independent random events, call the script multiple times.

99% of the time, you won’t need to worry about this, but just in case, you can specify a name of a list of outcomes to prevent interference from other scripts that call this one. That also permits situations where you don’t know until runtime what outcomes you want. For example, you could make a modtools/reaction-trigger that registers the worker as a mayor candidate, then run this script to choose a random mayor from the list of units that did the mayor reaction.

Arguments:

-outcomeListName name
    specify the name of this list of outcomes to prevent interference
    if two scripts are registering outcomes at the same time.  If none
    is specified, the default outcome list is selected automatically.
-command [ commandStrs ]
    specify the command to be run if this outcome is selected
    must be specified unless the -trigger argument is given
-weight n
    the relative probability weight of this outcome
    n must be a non-negative integer
    if not specified, n=1 is used by default
-trigger
    selects a random script based on the specified outcomeList
    (or the default one if none is specified)
-preserveList
    when combined with trigger, preserves the list of outcomes so you
    don't have to register them again.
-withProbability p
    p is a real number between 0 and 1 inclusive
    triggers the command immediately with this probability
-seed s
    sets the random seed for debugging purposes
    (guarantees the same sequence of random numbers will be produced)
    use
-listOutcomes
    lists the currently registered list of outcomes of the outcomeList
    along with their probability weights, for debugging purposes
-clear
    unregister everything

Note

-preserveList is something of a beta feature, which should be avoided by users without a specific reason to use it.

It is highly recommended that you always specify -outcomeListName when you give this command to prevent almost certain interference. If you want to trigger one of 5 outcomes three times, you might want this option even without -outcomeListName.

The list is NOT retained across game save/load, as nobody has yet had a use for this feature. Contact expwnent if you would use it; it’s not that hard but if nobody wants it he won’t bother.

modtools/raw-lint

Checks for simple issues with raw files. Can be run automatically.

modtools/reaction-product-trigger

This triggers dfhack commands when reaction products are produced, once per product. Usage:

-clear
    unregister all reaction hooks
-reactionName name
    specify the name of the reaction
-command [ commandStrs ]
    specify the command to be run on the target(s)
    special args
        \\WORKER_ID
        \\REACTION
        \\BUILDING_ID
        \\LOCATION
        \\INPUT_ITEMS
        \\OUTPUT_ITEMS
        \\anything -> \anything
        anything -> anything

modtools/reaction-trigger

Triggers dfhack commands when custom reactions complete, regardless of whether it produced anything, once per completion. Arguments:

-clear
    unregister all reaction hooks
-reactionName name
    specify the name of the reaction
-syndrome name
    specify the name of the syndrome to be applied to the targets
-allowNonworkerTargets
    allow other units in the same building to be targetted by
    either the script or the syndrome
-allowMultipleTargets
    allow multiple targets to the script or syndrome
    if absent:
        if running a script, only one target will be used
        if applying a syndrome, then only one target will be infected
-resetPolicy policy
    the policy in the case that the syndrome is already present
    policy
        NewInstance (default)
        DoNothing
        ResetDuration
        AddDuration
-command [ commandStrs ]
    specify the command to be run on the target(s)
    special args
        \\WORKER_ID
        \\TARGET_ID
        \\BUILDING_ID
        \\LOCATION
        \\REACTION_NAME
        \\anything -> \anything
        anything -> anything

modtools/reaction-trigger-transition

Prints useful things to the console and a file to help modders transition from autoSyndrome to modtools/reaction-trigger.

This script is basically an apology for breaking backward compatibility in June 2014, and will be removed eventually.

modtools/skill-change

Sets or modifies a skill of a unit. Args:

-skill skillName:
 set the skill that we’re talking about
-mode (add/set):
 are we adding experience/levels or setting them?
-granularity (experience/level):
 direct experience, or experience levels?
-unit id:id of the target unit
-value amount:how much to set/add
-loud:if present, prints changes to console

modtools/spawn-flow

Creates flows at the specified location.

Arguments:

-material mat
    specify the material of the flow, if applicable
    examples:
        INORGANIC:IRON
        CREATURE_MAT:DWARF:BRAIN
        PLANT_MAT:MUSHROOM_HELMET_PLUMP:DRINK
-location [ x y z]
    the location to spawn the flow
-flowType type
    specify the flow type
    examples:
        Miasma
        Steam
        Mist
        MaterialDust
        MagmaMist
        Smoke
        Dragonfire
        Fire
        Web
        MaterialGas
        MaterialVapor
        OceanWave
        SeaFoam
-flowSize size
    specify how big the flow is

modtools/syndrome-trigger

Triggers dfhack commands when syndromes are applied to units.

Arguments:

-clear
    clear all triggers
-syndrome name
    specify the name of a syndrome
-command [ commandStrs ]
    specify the command to be executed after infection
    args
        \\SYNDROME_ID
        \\UNIT_ID
        \\LOCATION
        \\anything -> \anything
        anything -> anything

modtools/transform-unit

Transforms a unit into another unit type, possibly permanently. Warning: this will crash arena mode if you view the unit on the same tick that it transforms. If you wait until later, it will be fine.

Arguments:

-clear
    clear records of normal races
-unit id
    set the target unit
-duration ticks
    how long it should last, or "forever"
-setPrevRace
    make a record of the previous race so that you can
    change it back with -untransform
-keepInventory
    move items back into inventory after transformation
-race raceName
-caste casteName
-suppressAnnouncement
    don't show the Unit has transformed into a Blah! event
-untransform
    turn the unit back into what it was before