|
|
|
@ -9,16 +9,16 @@ What is the difference between a script and a mod?
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
|
|
Well, sometimes there is no difference. A mod is anything you add to the game,
|
|
|
|
|
which can be graphics overrides, content in the raws, DFHack scripts, or both.
|
|
|
|
|
There are already resources out there for
|
|
|
|
|
which can be graphics overrides, content in the raws, DFHack scripts, any, or
|
|
|
|
|
all. There are already resources out there for
|
|
|
|
|
`raws modding <https://dwarffortresswiki.org/index.php/Modding>`__, so this
|
|
|
|
|
guide will focus more on scripts, both standalone and as an extension to
|
|
|
|
|
raws-based mods. A DFHack script is a Lua file that can be run as a command in
|
|
|
|
|
DFHack. Scripts can do pretty much anything, from displaying information to
|
|
|
|
|
enforcing new game mechanics.
|
|
|
|
|
raws-based mods.
|
|
|
|
|
|
|
|
|
|
If you don't already know Lua, there's a great primer at
|
|
|
|
|
`lua.org <https://www.lua.org/pil/contents.html>`__.
|
|
|
|
|
A DFHack script is a Lua file that can be run as a command in
|
|
|
|
|
DFHack. Scripts can do pretty much anything, from displaying information to
|
|
|
|
|
enforcing new game mechanics. If you don't already know Lua, there's a great
|
|
|
|
|
primer at `lua.org <https://www.lua.org/pil/contents.html>`__.
|
|
|
|
|
|
|
|
|
|
Why not just mod the raws?
|
|
|
|
|
--------------------------
|
|
|
|
@ -26,13 +26,14 @@ Why not just mod the raws?
|
|
|
|
|
It depends on what you want to do. Some mods *are* better to do in just the
|
|
|
|
|
raws. You don't need DFHack to add a new race or modify attributes. However,
|
|
|
|
|
DFHack scripts can do many things that you just can't do in the raws, like make
|
|
|
|
|
a creature that trails smoke. Some things *could* be done in the raws, but
|
|
|
|
|
writing a script is less hacky, easier to maintain, easier to extend, and is
|
|
|
|
|
not prone to side-effects. A great example is adding a syndrome when a reaction
|
|
|
|
|
is performed. If done in the raws, you have to create an exploding boulder to
|
|
|
|
|
apply the syndrome. DFHack scripts can add the syndrome directly and with much
|
|
|
|
|
more flexibility. In the end, complex mods will likely require a mix of raw
|
|
|
|
|
modding and DFHack scripting.
|
|
|
|
|
a creature that trails smoke or launch a unit into the air when they are hit
|
|
|
|
|
with a certain type of projectile. Some things *could* be done in the raws, but
|
|
|
|
|
a script is better (e.g. easier to maintain, easier to extend, and/or not prone
|
|
|
|
|
to side-effects). A great example is adding a syndrome when a reaction
|
|
|
|
|
is performed. If done in the raws, you have to create an exploding boulder as
|
|
|
|
|
an intermediary to apply the syndrome. DFHack scripts can add the syndrome
|
|
|
|
|
directly and with much more flexibility. In the end, complex mods will likely
|
|
|
|
|
require a mix of raw modding and DFHack scripting.
|
|
|
|
|
|
|
|
|
|
The structure of a mod
|
|
|
|
|
----------------------
|
|
|
|
@ -40,82 +41,102 @@ The structure of a mod
|
|
|
|
|
For reference, `Tachy Guns <https://www.github.com/wolfboyft/tachy-guns>`__ is a
|
|
|
|
|
full mod that conforms to this guide.
|
|
|
|
|
|
|
|
|
|
Create a folder for mod projects somewhere outside your Dwarf Fortress
|
|
|
|
|
installation directory (e.g. ``/path/to/mymods/``) and use your mod IDs as the
|
|
|
|
|
names for the mod folders within it. In the example below, we'll use a mod ID of
|
|
|
|
|
``example-mod``. I'm sure your mods will have more creative names! The
|
|
|
|
|
``example-mod`` mod will be developed in the ``/path/to/mymods/example-mod/``
|
|
|
|
|
directory and has a basic structure that looks like this::
|
|
|
|
|
In the example below, we'll use a mod name of ``example-mod``. I'm sure your
|
|
|
|
|
mods will have more creative names! Mods have a basic structure that looks like
|
|
|
|
|
this::
|
|
|
|
|
|
|
|
|
|
init.d/example-mod.lua
|
|
|
|
|
raw/objects/...
|
|
|
|
|
raw/scripts/example-mod.lua
|
|
|
|
|
raw/scripts/example-mod/...
|
|
|
|
|
README.md
|
|
|
|
|
info.txt
|
|
|
|
|
graphics/...
|
|
|
|
|
objects/...
|
|
|
|
|
scripts_modactive/example-mod.lua
|
|
|
|
|
scripts_modactive/internal/example-mod/...
|
|
|
|
|
scripts_modinstalled/...
|
|
|
|
|
README.md (optional)
|
|
|
|
|
|
|
|
|
|
Let's go through that line by line.
|
|
|
|
|
|
|
|
|
|
* A short (one-line) script in ``init.d/`` to initialise your
|
|
|
|
|
mod when a save is loaded.
|
|
|
|
|
* Modifications to the game raws (potentially with custom raw tokens) go in
|
|
|
|
|
``raw/objects/``.
|
|
|
|
|
* A control script in ``scripts/`` that handles enabling and disabling your
|
|
|
|
|
mod.
|
|
|
|
|
* A subfolder for your mod under ``scripts/`` will contain all the internal
|
|
|
|
|
scripts and/or modules used by your mod.
|
|
|
|
|
- The :file:`info.txt` file contains metadata about your mod that DF will
|
|
|
|
|
display in-game. You can read more about this file in the
|
|
|
|
|
`Official DF Modding Guide <https://bay12games.com/dwarves/modding_guide.html>`__.
|
|
|
|
|
- Modifications to the game raws (potentially with custom raw tokens) go in
|
|
|
|
|
the :file:`graphics/` and :file:`objects/` folders. You can read more about
|
|
|
|
|
the files that go in these directories on the :wiki:`Modding` wiki page.
|
|
|
|
|
- A control script in :file:`scripts_modactive/` directory that handles
|
|
|
|
|
system-level event hooks (e.g. reloading state when a world is loaded),
|
|
|
|
|
registering `overlays <overlay-dev-guide>`, and
|
|
|
|
|
`enabling/disabling <script-enable-api>` your mod. You can put other
|
|
|
|
|
scripts in this directory as well if you want them to appear as runnable
|
|
|
|
|
DFHack commands when your mod is active for the current world. Lua modules
|
|
|
|
|
that your main scripts use, but which don't need to be directly runnable by
|
|
|
|
|
the player, should go in a subdirectory under
|
|
|
|
|
:file:`scripts_modactive/internal/` so they don't show up in the DFHack
|
|
|
|
|
`launcher <gui/launcher>` command autocomplete lists.
|
|
|
|
|
- Scripts that you want to be available before a world is loaded (i.e. on the
|
|
|
|
|
DF title screen) or that you want to be runnable in any world, regardless
|
|
|
|
|
of whether your mod is active, should go in the
|
|
|
|
|
:file:`scripts_modinstalled/` folder. You can also have an :file:`internal/`
|
|
|
|
|
subfolder in here for private modules if you like.
|
|
|
|
|
- Finally, a :file:`README.md` file that has more information about your mod.
|
|
|
|
|
If you develop your mod using version control (recommended!), that
|
|
|
|
|
:file:`README.md` file can also serve as your git repository documentation.
|
|
|
|
|
|
|
|
|
|
These files end up in a subdirectory under :file:`data/installed_mods/` when
|
|
|
|
|
the mod is selected as "active" for the first time.
|
|
|
|
|
|
|
|
|
|
What if I just want to distribute a simple script?
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
|
|
If your mod is just a script with no raws modifications, things get a bit
|
|
|
|
|
simpler. All you need is::
|
|
|
|
|
|
|
|
|
|
It is a good idea to use a version control system to organize changes to your
|
|
|
|
|
mod code. You can create a separate Git repository for each of your mods. The
|
|
|
|
|
``README.md`` file will be your mod help text when people browse to your online
|
|
|
|
|
repository.
|
|
|
|
|
info.txt
|
|
|
|
|
scripts_modinstalled/yourscript.lua
|
|
|
|
|
README.md (optional)
|
|
|
|
|
|
|
|
|
|
Unless you want to install your ``raw/`` folder into your DF game folder every
|
|
|
|
|
time you make a change to your scripts, you should add your development scripts
|
|
|
|
|
directory to your script paths in ``dfhack-config/script-paths.txt``::
|
|
|
|
|
Adding your script to the :file:`scripts_modinstalled/` folder will allow
|
|
|
|
|
DFHack to find it and add your mod to the `script-paths`. Your script will be
|
|
|
|
|
runnable from the title screen and in any loaded world, regardless of whether
|
|
|
|
|
your mod is explicitly "active".
|
|
|
|
|
|
|
|
|
|
+/path/to/mymods/example-mod/scripts/
|
|
|
|
|
Be sure to remind players to mark your mod as "active" at least once so it gets
|
|
|
|
|
installed to the :file:`data/installed_mods/` folder. They may have to create a
|
|
|
|
|
new world just so they can mark the mod as "active". This is true both for
|
|
|
|
|
players who copied the mod into the :file:`mods/` folder manually and for
|
|
|
|
|
players who subscribed via
|
|
|
|
|
`Steam Workshop <https://steamcommunity.com/app/975370/workshop/>`__.
|
|
|
|
|
|
|
|
|
|
A mod-maker's development environment
|
|
|
|
|
-------------------------------------
|
|
|
|
|
|
|
|
|
|
While you're writing your mod, you need a place to store your in-development
|
|
|
|
|
scripts that will:
|
|
|
|
|
Create a folder for development somewhere outside your Dwarf Fortress
|
|
|
|
|
installation directory (e.g. ``/path/to/mymods/``). If you work on multiple
|
|
|
|
|
mods, you might want to make a subdirectory for each mod.
|
|
|
|
|
|
|
|
|
|
- be directly runnable by DFHack
|
|
|
|
|
- not get lost when you upgrade DFHack
|
|
|
|
|
If you have changes to the raws, you'll have to copy them into DF's ``data/
|
|
|
|
|
installed_mods/`` folder to have them take effect, but you can set things up so
|
|
|
|
|
that scripts are run directly from your dev directory. This way, you can edit
|
|
|
|
|
your scripts and have the changes available in the game immediately: no
|
|
|
|
|
copying, no restarting.
|
|
|
|
|
|
|
|
|
|
The recommended approach is to create a directory somewhere outside of your DF
|
|
|
|
|
installation (let's call it "/path/to/own-scripts") and do all your script
|
|
|
|
|
development in there.
|
|
|
|
|
How does this magic work? Just add a line like this to your
|
|
|
|
|
``dfhack-config/script-paths.txt`` file::
|
|
|
|
|
|
|
|
|
|
Inside your DF installation folder, there is a file named
|
|
|
|
|
:file:`dfhack-config/script-paths.txt`. If you add a line like this to that
|
|
|
|
|
file::
|
|
|
|
|
|
|
|
|
|
+/path/to/own-scripts
|
|
|
|
|
+/path/to/mymods/example-mod/scripts_modinstalled
|
|
|
|
|
|
|
|
|
|
Then that directory will be searched when you run DFHack commands from inside
|
|
|
|
|
the game. The ``+`` at the front of the path means to search that directory
|
|
|
|
|
first, before any other script directory (like :file:`hack/scripts` or
|
|
|
|
|
:file:`raw/scripts`). That way, your latest changes will always be used instead
|
|
|
|
|
of older copies that you may have in mods installed in the DF directory.
|
|
|
|
|
|
|
|
|
|
For scripts with the same name, the `order of precedence <script-paths>` will
|
|
|
|
|
be:
|
|
|
|
|
|
|
|
|
|
1. ``own-scripts/``
|
|
|
|
|
2. ``dfhack-config/scripts/``
|
|
|
|
|
3. ``save/*/scripts/``
|
|
|
|
|
4. ``hack/scripts/``
|
|
|
|
|
first, before any other script directory (like :file:`hack/scripts` or other
|
|
|
|
|
versions of your mod in ``data/installed_mods/``).
|
|
|
|
|
|
|
|
|
|
The structure of the game
|
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
|
|
"The game" is in the global variable `df <lua-df>`. The game's memory can be
|
|
|
|
|
found in ``df.global``, containing things like the list of all items, whether to
|
|
|
|
|
reindex pathfinding, et cetera. Also relevant to us in ``df`` are the various
|
|
|
|
|
types found in the game, e.g. ``df.pronoun_type`` which we will be using in this
|
|
|
|
|
guide. We'll explore more of the game structures below.
|
|
|
|
|
"The game" is in the global variable `df <lua-df>`. Most of the information
|
|
|
|
|
relevant to a script is found in ``df.global.world``, which contains things
|
|
|
|
|
like the list of all items, whether to reindex pathfinding, et cetera. Also
|
|
|
|
|
relevant to us are the various data types found in the game, e.g.
|
|
|
|
|
``df.pronoun_type`` which we will be using in this guide. We'll explore more of
|
|
|
|
|
the game structures below.
|
|
|
|
|
|
|
|
|
|
Your first script
|
|
|
|
|
-----------------
|
|
|
|
@ -127,8 +148,8 @@ First line, we get the unit::
|
|
|
|
|
|
|
|
|
|
local unit = dfhack.gui.getSelectedUnit()
|
|
|
|
|
|
|
|
|
|
If no unit is selected, an error message will be printed (which can be silenced
|
|
|
|
|
by passing ``true`` to ``getSelectedUnit``) and ``unit`` will be ``nil``.
|
|
|
|
|
If no unit is selected, ``unit`` will be ``nil`` and an error message will be
|
|
|
|
|
printed (which can be silenced by passing ``true`` to ``getSelectedUnit``).
|
|
|
|
|
|
|
|
|
|
If ``unit`` is ``nil``, we don't want the script to run anymore::
|
|
|
|
|
|
|
|
|
@ -138,33 +159,32 @@ If ``unit`` is ``nil``, we don't want the script to run anymore::
|
|
|
|
|
|
|
|
|
|
Now, the field ``sex`` in a unit is an integer, but each integer corresponds to
|
|
|
|
|
a string value ("it", "she", or "he"). We get this value by indexing the
|
|
|
|
|
bidirectional map ``df.pronoun_type``. Indexing the other way, incidentally,
|
|
|
|
|
with one of the strings, will yield its corresponding number. So::
|
|
|
|
|
bidirectional map ``df.pronoun_type``. Indexing the other way, with one of the
|
|
|
|
|
strings, will yield its corresponding number. So::
|
|
|
|
|
|
|
|
|
|
local pronounTypeString = df.pronoun_type[unit.sex]
|
|
|
|
|
print(pronounTypeString)
|
|
|
|
|
|
|
|
|
|
Simple. Save this as a Lua file in your own scripts directory and run it as
|
|
|
|
|
shown before when a unit is selected in the Dwarf Fortress UI.
|
|
|
|
|
Simple. Save this as a Lua file in your own scripts directory and run it from
|
|
|
|
|
`gui/launcher` when a unit is selected in the Dwarf Fortress UI.
|
|
|
|
|
|
|
|
|
|
Exploring DF structures
|
|
|
|
|
-----------------------
|
|
|
|
|
Exploring DF state
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
So how could you have known about the field and type we just used? Well, there
|
|
|
|
|
are two main tools for discovering the various fields in the game's data
|
|
|
|
|
structures. The first is the ``df-structures``
|
|
|
|
|
`repository <https://github.com/DFHack/df-structures>`__ that contains XML files
|
|
|
|
|
describing the contents of the game's structures. These are complete, but
|
|
|
|
|
describing the layouts of the game's structures. These are complete, but
|
|
|
|
|
difficult to read (for a human). The second option is the `gui/gm-editor`
|
|
|
|
|
script, an interactive data explorer. You can run the script while objects like
|
|
|
|
|
units are selected to view the data within them. You can also run
|
|
|
|
|
``gui/gm-editor scr`` to view the data for the current screen. Press :kbd:`?`
|
|
|
|
|
while the script is active to view help.
|
|
|
|
|
interface, an interactive data explorer. You can run the script while objects
|
|
|
|
|
like units are selected to view the data within them. Press :kbd:`?` while the
|
|
|
|
|
script is active to view help.
|
|
|
|
|
|
|
|
|
|
Familiarising yourself with the many structs of the game will help with ideas
|
|
|
|
|
immensely, and you can always ask for help in the `right places <support>`.
|
|
|
|
|
|
|
|
|
|
Detecting triggers
|
|
|
|
|
Reacting to events
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
The common method for injecting new behaviour into the game is to define a
|
|
|
|
@ -174,7 +194,7 @@ provides two libraries for this, ``repeat-util`` and `eventful <eventful-api>`.
|
|
|
|
|
frames (paused or unpaused), ticks (unpaused), in-game days, months, or years.
|
|
|
|
|
If you need to be aware the instant something happens, you'll need to run a
|
|
|
|
|
check once a tick. Be careful not to do this gratuitously, though, since
|
|
|
|
|
running that often can slow down the game!
|
|
|
|
|
running callbacks too often can slow down the game!
|
|
|
|
|
|
|
|
|
|
``eventful``, on the other hand, is much more performance-friendly since it will
|
|
|
|
|
only call your callback when a relevant event happens, like a reaction or job
|
|
|
|
@ -371,7 +391,8 @@ Then, let's make a ``repeat-util`` callback for once a tick::
|
|
|
|
|
repeatUtil.scheduleEvery(modId, 1, "ticks", function()
|
|
|
|
|
|
|
|
|
|
Let's iterate over every active unit, and for every unit, iterate over their
|
|
|
|
|
worn items to calculate how much we are going to take from their on-foot movement timers::
|
|
|
|
|
worn items to calculate how much we are going to take from their on-foot
|
|
|
|
|
movement timers::
|
|
|
|
|
|
|
|
|
|
for _, unit in ipairs(df.global.world.units.active) do
|
|
|
|
|
local amount = 0
|
|
|
|
@ -385,82 +406,78 @@ worn items to calculate how much we are going to take from their on-foot movemen
|
|
|
|
|
end
|
|
|
|
|
-- Subtract amount from on-foot movement timers if not on ground
|
|
|
|
|
if not unit.flags1.on_ground then
|
|
|
|
|
dfhack.units.subtractActionTimers(unit, amount, df.unit_action_type_group.MovementFeet)
|
|
|
|
|
dfhack.units.subtractActionTimers(unit, amount,
|
|
|
|
|
df.unit_action_type_group.MovementFeet)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
The structure of a full mod
|
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
|
|
For reference, `Tachy Guns <https://www.github.com/wolfboyft/tachy-guns>`__ is a
|
|
|
|
|
full mod that conforms to this guide.
|
|
|
|
|
|
|
|
|
|
Create a folder for mod projects somewhere outside your Dwarf Fortress
|
|
|
|
|
installation directory (e.g. ``/path/to/mymods/``) and use your mod IDs as the
|
|
|
|
|
names for the mod folders within it. In the example below, we'll use a mod ID of
|
|
|
|
|
``example-mod``. I'm sure your mods will have more creative names! The
|
|
|
|
|
``example-mod`` mod will be developed in the ``/path/to/mymods/example-mod/``
|
|
|
|
|
directory and has a basic structure that looks like this::
|
|
|
|
|
|
|
|
|
|
init.d/example-mod.lua
|
|
|
|
|
raw/objects/...
|
|
|
|
|
raw/scripts/example-mod.lua
|
|
|
|
|
raw/scripts/example-mod/...
|
|
|
|
|
README.md
|
|
|
|
|
Putting it all together
|
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
|
|
Let's go through that line by line.
|
|
|
|
|
Ok, you're all set up! Now, let's take a look at an example
|
|
|
|
|
``scripts_modinstalled/example-mod.lua`` file::
|
|
|
|
|
|
|
|
|
|
* A short (one-line) script in ``init.d/`` to initialise your
|
|
|
|
|
mod when a save is loaded.
|
|
|
|
|
* Modifications to the game raws (potentially with custom raw tokens) go in
|
|
|
|
|
``raw/objects/``.
|
|
|
|
|
* A control script in ``scripts/`` that handles enabling and disabling your
|
|
|
|
|
mod.
|
|
|
|
|
* A subfolder for your mod under ``scripts/`` will contain all the internal
|
|
|
|
|
scripts and/or modules used by your mod.
|
|
|
|
|
-- main file for example-mod
|
|
|
|
|
|
|
|
|
|
It is a good idea to use a version control system to organize changes to your
|
|
|
|
|
mod code. You can create a separate Git repository for each of your mods. The
|
|
|
|
|
``README.md`` file will be your mod help text when people browse to your online
|
|
|
|
|
repository.
|
|
|
|
|
-- these lines indicate that the script supports the "enable" API so you
|
|
|
|
|
-- can start it by running "enable example-mod" and stop it by running
|
|
|
|
|
-- "disable example-mod"
|
|
|
|
|
--@module = true
|
|
|
|
|
--@enable = true
|
|
|
|
|
|
|
|
|
|
Unless you want to install your ``raw/`` folder into your DF game folder every
|
|
|
|
|
time you make a change to your scripts, you should add your development scripts
|
|
|
|
|
directory to your script paths in ``dfhack-config/script-paths.txt``::
|
|
|
|
|
-- this is the help text that will appear in `help` and `gui/launcher`
|
|
|
|
|
-- Documentation on how to format docs here:
|
|
|
|
|
-- see possible tags here: https://docs.dfhack.org/en/latest/docs/Tags.html
|
|
|
|
|
--[====[
|
|
|
|
|
example-mod
|
|
|
|
|
===========
|
|
|
|
|
|
|
|
|
|
+/path/to/mymods/example-mod/scripts/
|
|
|
|
|
Tags: fort | gameplay
|
|
|
|
|
|
|
|
|
|
Ok, you're all set up! Now, let's take a look at an example
|
|
|
|
|
``scripts/example-mod.lua`` file::
|
|
|
|
|
Short one-sentence description ...
|
|
|
|
|
|
|
|
|
|
-- main setup and teardown for example-mod
|
|
|
|
|
-- this next line indicates that the script supports the "enable"
|
|
|
|
|
-- API so you can start it by running "enable example-mod" and stop
|
|
|
|
|
-- it by running "disable example-mod"
|
|
|
|
|
--@ enable = true
|
|
|
|
|
Longer description ...
|
|
|
|
|
|
|
|
|
|
local usage = [[
|
|
|
|
|
Usage
|
|
|
|
|
-----
|
|
|
|
|
|
|
|
|
|
enable example-mod
|
|
|
|
|
disable example-mod
|
|
|
|
|
]]
|
|
|
|
|
]====]
|
|
|
|
|
|
|
|
|
|
local repeatUtil = require('repeat-util')
|
|
|
|
|
local eventful = require('plugins.eventful')
|
|
|
|
|
|
|
|
|
|
-- you can reference global values or functions declared in any of
|
|
|
|
|
-- your internal scripts
|
|
|
|
|
local moduleA = reqscript('example-mod/module-a')
|
|
|
|
|
local moduleB = reqscript('example-mod/module-b')
|
|
|
|
|
local moduleC = reqscript('example-mod/module-c')
|
|
|
|
|
local moduleD = reqscript('example-mod/module-d')
|
|
|
|
|
local moduleA = reqscript('internal/example-mod/module-a')
|
|
|
|
|
local moduleB = reqscript('internal/example-mod/module-b')
|
|
|
|
|
local moduleC = reqscript('internal/example-mod/module-c')
|
|
|
|
|
local moduleD = reqscript('internal/example-mod/module-d')
|
|
|
|
|
|
|
|
|
|
local GLOBAL_KEY = 'example-mod'
|
|
|
|
|
|
|
|
|
|
enabled = enabled or false
|
|
|
|
|
local modId = 'example-mod'
|
|
|
|
|
|
|
|
|
|
function isEnabled()
|
|
|
|
|
return enabled
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
dfhack.onStateChange[GLOBAL_KEY] = function(sc)
|
|
|
|
|
if sc == SC_MAP_UNLOADED then
|
|
|
|
|
dfhack.run_command('disable', 'example-mod')
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if sc ~= SC_MAP_LOADED or df.global.gamemode ~= df.game_mode.DWARF then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
dfhack.run_command('enable', 'example-mod')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if not dfhack_flags.enable then
|
|
|
|
|
print(usage)
|
|
|
|
|
print(dfhack.script_help())
|
|
|
|
|
print()
|
|
|
|
|
print(('Example mod is currently '):format(
|
|
|
|
|
enabled and 'enabled' or 'disabled'))
|
|
|
|
@ -516,23 +533,17 @@ Ok, you're all set up! Now, let's take a look at an example
|
|
|
|
|
enabled = false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
You can call ``enable example-mod`` and ``disable example-mod`` yourself while
|
|
|
|
|
developing, but for end users you can start your mod automatically from
|
|
|
|
|
``init.d/example-mod.lua``::
|
|
|
|
|
|
|
|
|
|
dfhack.run_command('enable example-mod')
|
|
|
|
|
|
|
|
|
|
Inside ``raw/scripts/example-mod/module-a.lua`` you could have code like this::
|
|
|
|
|
Inside ``scripts_modinstalled/internal/example-mod/module-a.lua`` you could
|
|
|
|
|
have code like this::
|
|
|
|
|
|
|
|
|
|
--@ module = true
|
|
|
|
|
-- The above line is required for reqscript to work
|
|
|
|
|
|
|
|
|
|
function onLoad() -- global variables are exported
|
|
|
|
|
-- do initialization here
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- this is an internal function: local functions/variables
|
|
|
|
|
-- are not exported
|
|
|
|
|
-- this is a local function: local functions/variables
|
|
|
|
|
-- are not accessible to other scripts.
|
|
|
|
|
local function usedByOnTick(unit)
|
|
|
|
|
-- ...
|
|
|
|
|
end
|
|
|
|
@ -543,6 +554,6 @@ Inside ``raw/scripts/example-mod/module-a.lua`` you could have code like this::
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
The `reqscript <reqscript>` function reloads scripts that have changed, so you can modify
|
|
|
|
|
your scripts while DF is running and just disable/enable your mod to load the
|
|
|
|
|
changes into your ongoing game!
|
|
|
|
|
The `reqscript <reqscript>` function reloads scripts that have changed, so you
|
|
|
|
|
can modify your scripts while DF is running and just disable/enable your mod to
|
|
|
|
|
load the changes into your ongoing game!
|
|
|
|
|