Skip to content

Commit 59fb4da

Browse files
committed
2 parents 6199d69 + 0e58290 commit 59fb4da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3327
-809
lines changed

COMPILE.rst

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,13 @@ Valid and useful build types include 'Release', 'Debug' and
152152
================================
153153
Using the library as a developer
154154
================================
155-
Currently, the only way to use the library is to write a plugin that can be loaded by it.
155+
156+
Currently, the most direct way to use the library is to write a plugin that can be loaded by it.
156157
All the plugins can be found in the 'plugins' folder. There's no in-depth documentation
157158
on how to write one yet, but it should be easy enough to copy one and just follow the pattern.
158159

160+
Other than through plugins, it is possible to use DFHack via remote access interface, or by writing Lua scripts.
161+
159162
The most important parts of DFHack are the Core, Console, Modules and Plugins.
160163

161164
* Core acts as the centerpiece of DFHack - it acts as a filter between DF and SDL and synchronizes the various plugins with DF.
@@ -171,6 +174,24 @@ The main license is zlib/libpng, some bits are MIT licensed, and some are BSD li
171174
Feel free to add your own extensions and plugins. Contributing back to
172175
the dfhack repository is welcome and the right thing to do :)
173176

177+
DF data structure definitions
178+
=============================
179+
180+
DFHack uses information about the game data structures, represented via xml files in the library/xml/ submodule.
181+
182+
Data structure layouts are described in files following the df.*.xml name pattern. This information is transformed by a perl script into C++ headers describing the structures, and associated metadata for the Lua wrapper. These headers and data are then compiled into the DFHack libraries, thus necessitating a compatibility break every time layouts change; in return it significantly boosts the efficiency and capabilities of DFHack code.
183+
184+
Global object addresses are stored in symbols.xml, which is copied to the dfhack release package and loaded as data at runtime.
185+
186+
Remote access interface
187+
=======================
188+
189+
DFHack supports remote access by exchanging Google protobuf messages via a TCP socket. Both the core and plugins can define remotely accessible methods. The ``dfhack-run`` command uses this interface to invoke ordinary console commands.
190+
191+
Currently the supported set of requests is limited, because the developers don't know what exactly is most useful.
192+
193+
Protocol client implementations exist for Java and C#.
194+
174195
Contributing to DFHack
175196
======================
176197

Compile.html

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,12 @@ <h1 class="title">Building DFHACK</h1>
334334
</li>
335335
<li><a class="reference internal" href="#build-types" id="id12">Build types</a></li>
336336
<li><a class="reference internal" href="#using-the-library-as-a-developer" id="id13">Using the library as a developer</a><ul>
337-
<li><a class="reference internal" href="#contributing-to-dfhack" id="id14">Contributing to DFHack</a><ul>
338-
<li><a class="reference internal" href="#coding-style" id="id15">Coding style</a></li>
339-
<li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id16">How to get new code into DFHack</a></li>
340-
<li><a class="reference internal" href="#memory-research" id="id17">Memory research</a></li>
337+
<li><a class="reference internal" href="#df-data-structure-definitions" id="id14">DF data structure definitions</a></li>
338+
<li><a class="reference internal" href="#remote-access-interface" id="id15">Remote access interface</a></li>
339+
<li><a class="reference internal" href="#contributing-to-dfhack" id="id16">Contributing to DFHack</a><ul>
340+
<li><a class="reference internal" href="#coding-style" id="id17">Coding style</a></li>
341+
<li><a class="reference internal" href="#how-to-get-new-code-into-dfhack" id="id18">How to get new code into DFHack</a></li>
342+
<li><a class="reference internal" href="#memory-research" id="id19">Memory research</a></li>
341343
</ul>
342344
</li>
343345
</ul>
@@ -470,9 +472,10 @@ <h1><a class="toc-backref" href="#id12">Build types</a></h1>
470472
</div>
471473
<div class="section" id="using-the-library-as-a-developer">
472474
<h1><a class="toc-backref" href="#id13">Using the library as a developer</a></h1>
473-
<p>Currently, the only way to use the library is to write a plugin that can be loaded by it.
475+
<p>Currently, the most direct way to use the library is to write a plugin that can be loaded by it.
474476
All the plugins can be found in the 'plugins' folder. There's no in-depth documentation
475477
on how to write one yet, but it should be easy enough to copy one and just follow the pattern.</p>
478+
<p>Other than through plugins, it is possible to use DFHack via remote access interface, or by writing Lua scripts.</p>
476479
<p>The most important parts of DFHack are the Core, Console, Modules and Plugins.</p>
477480
<ul class="simple">
478481
<li>Core acts as the centerpiece of DFHack - it acts as a filter between DF and SDL and synchronizes the various plugins with DF.</li>
@@ -485,18 +488,30 @@ <h1><a class="toc-backref" href="#id13">Using the library as a developer</a></h1
485488
The main license is zlib/libpng, some bits are MIT licensed, and some are BSD licensed.</p>
486489
<p>Feel free to add your own extensions and plugins. Contributing back to
487490
the dfhack repository is welcome and the right thing to do :)</p>
491+
<div class="section" id="df-data-structure-definitions">
492+
<h2><a class="toc-backref" href="#id14">DF data structure definitions</a></h2>
493+
<p>DFHack uses information about the game data structures, represented via xml files in the library/xml/ submodule.</p>
494+
<p>Data structure layouts are described in files following the df.*.xml name pattern. This information is transformed by a perl script into C++ headers describing the structures, and associated metadata for the Lua wrapper. These headers and data are then compiled into the DFHack libraries, thus necessitating a compatibility break every time layouts change; in return it significantly boosts the efficiency and capabilities of DFHack code.</p>
495+
<p>Global object addresses are stored in symbols.xml, which is copied to the dfhack release package and loaded as data at runtime.</p>
496+
</div>
497+
<div class="section" id="remote-access-interface">
498+
<h2><a class="toc-backref" href="#id15">Remote access interface</a></h2>
499+
<p>DFHack supports remote access by exchanging Google protobuf messages via a TCP socket. Both the core and plugins can define remotely accessible methods. The <tt class="docutils literal"><span class="pre">dfhack-run</span></tt> command uses this interface to invoke ordinary console commands.</p>
500+
<p>Currently the supported set of requests is limited, because the developers don't know what exactly is most useful.</p>
501+
<p>Protocol client implementations exist for Java and C#.</p>
502+
</div>
488503
<div class="section" id="contributing-to-dfhack">
489-
<h2><a class="toc-backref" href="#id14">Contributing to DFHack</a></h2>
504+
<h2><a class="toc-backref" href="#id16">Contributing to DFHack</a></h2>
490505
<p>Several things should be kept in mind when contributing to DFHack.</p>
491506
<div class="section" id="coding-style">
492-
<h3><a class="toc-backref" href="#id15">Coding style</a></h3>
507+
<h3><a class="toc-backref" href="#id17">Coding style</a></h3>
493508
<p>DFhack uses ANSI formatting and four spaces as indentation. Line
494509
endings are UNIX. The files use UTF-8 encoding. Code not following this
495510
won't make me happy, because I'll have to fix it. There's a good chance
496511
I'll make <em>you</em> fix it ;)</p>
497512
</div>
498513
<div class="section" id="how-to-get-new-code-into-dfhack">
499-
<h3><a class="toc-backref" href="#id16">How to get new code into DFHack</a></h3>
514+
<h3><a class="toc-backref" href="#id18">How to get new code into DFHack</a></h3>
500515
<p>You can send patches or make a clone of the github repo and ask me on
501516
the IRC channel to pull your code in. I'll review it and see if there
502517
are any problems. I'll fix them if they are minor.</p>
@@ -506,7 +521,7 @@ <h3><a class="toc-backref" href="#id16">How to get new code into DFHack</a></h3>
506521
fixing.</p>
507522
</div>
508523
<div class="section" id="memory-research">
509-
<h3><a class="toc-backref" href="#id17">Memory research</a></h3>
524+
<h3><a class="toc-backref" href="#id19">Memory research</a></h3>
510525
<p>If you want to do memory research, you'll need some tools and some knowledge.
511526
In general, you'll need a good memory viewer and optionally something
512527
to look at machine code without getting crazy :)</p>

LUA_API.rst

Lines changed: 178 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,26 @@ DFHack Lua API
44

55
.. contents::
66

7-
====================
8-
DF structure wrapper
9-
====================
7+
The current version of DFHack has extensive support for
8+
the Lua scripting language, providing access to:
9+
10+
1. Raw data structures used by the game.
11+
2. Many C++ functions for high-level access to these
12+
structures, and interaction with dfhack itself.
13+
3. Some functions exported by C++ plugins.
14+
15+
Lua code can be used both for writing scripts, which
16+
are treated by DFHack command line prompt almost as
17+
native C++ commands, and invoked by plugins written in c++.
18+
19+
This document describes native API available to Lua in detail.
20+
For the most part it does not describe utility functions
21+
implemented by Lua files located in hack/lua/...
22+
23+
24+
=========================
25+
DF data structure wrapper
26+
=========================
1027

1128
DF structures described by the xml files in library/xml are exported
1229
to lua code as a tree of objects and functions under the ``df`` global,
@@ -426,13 +443,17 @@ not destroy any objects allocated in this way, so the user
426443
should be prepared to catch the error and do the necessary
427444
cleanup.
428445

429-
================
430-
DFHack utilities
431-
================
446+
==========
447+
DFHack API
448+
==========
432449

433450
DFHack utility functions are placed in the ``dfhack`` global tree.
434451

435-
Currently it defines the following features:
452+
Native utilities
453+
================
454+
455+
Input & Output
456+
--------------
436457

437458
* ``dfhack.print(args...)``
438459

@@ -451,6 +472,7 @@ Currently it defines the following features:
451472
* ``dfhack.color([color])``
452473

453474
Sets the current output color. If color is *nil* or *-1*, resets to default.
475+
Returns the previous color value.
454476

455477
* ``dfhack.is_interactive()``
456478

@@ -473,15 +495,27 @@ Currently it defines the following features:
473495

474496
If the interactive console is not accessible, returns *nil, error*.
475497

498+
499+
Exception handling
500+
------------------
501+
502+
* ``dfhack.error(msg[,level[,verbose]])``
503+
504+
Throws a dfhack exception object with location and stack trace.
505+
The verbose parameter controls whether the trace is printed by default.
506+
507+
* ``qerror(msg[,level])``
508+
509+
Calls ``dfhack.error()`` with ``verbose`` being *false*. Intended to
510+
be used for user-caused errors in scripts, where stack traces are not
511+
desirable.
512+
476513
* ``dfhack.pcall(f[,args...])``
477514

478515
Invokes f via xpcall, using an error function that attaches
479516
a stack trace to the error. The same function is used by SafeCall
480517
in C++, and dfhack.safecall.
481518

482-
The returned error is a table with separate ``message`` and
483-
``stacktrace`` string fields; it implements ``__tostring``.
484-
485519
* ``safecall(f[,args...])``, ``dfhack.safecall(f[,args...])``
486520

487521
Just like pcall, but also prints the error using printerr before
@@ -491,6 +525,34 @@ Currently it defines the following features:
491525

492526
Compares to coroutine.resume like dfhack.safecall vs pcall.
493527

528+
* ``dfhack.exception``
529+
530+
Metatable of error objects used by dfhack. The objects have the
531+
following properties:
532+
533+
``err.where``
534+
The location prefix string, or *nil*.
535+
``err.message``
536+
The base message string.
537+
``err.stacktrace``
538+
The stack trace string, or *nil*.
539+
``err.cause``
540+
A different exception object, or *nil*.
541+
``err.thread``
542+
The coroutine that has thrown the exception.
543+
``err.verbose``
544+
Boolean, or *nil*; specifies if where and stacktrace should be printed.
545+
``tostring(err)``, or ``err:tostring([verbose])``
546+
Converts the exception to string.
547+
548+
* ``dfhack.exception.verbose``
549+
550+
The default value of the ``verbose`` argument of ``err:tostring()``.
551+
552+
553+
Locking and finalization
554+
------------------------
555+
494556
* ``dfhack.with_suspend(f[,args...])``
495557

496558
Calls ``f`` with arguments after grabbing the DF core suspend lock.
@@ -529,7 +591,7 @@ Currently it defines the following features:
529591

530592

531593
Persistent configuration storage
532-
================================
594+
--------------------------------
533595

534596
This api is intended for storing configuration options in the world itself.
535597
It probably should be restricted to data that is world-dependent.
@@ -571,7 +633,7 @@ functions can just copy values in memory without doing any actual I/O.
571633
However, currently every entry has a 180+-byte dead-weight overhead.
572634

573635
Material info lookup
574-
====================
636+
--------------------
575637

576638
A material info record has fields:
577639

@@ -1148,6 +1210,11 @@ Internal API
11481210
These functions are intended for the use by dfhack developers,
11491211
and are only documented here for completeness:
11501212

1213+
* ``dfhack.internal.scripts``
1214+
1215+
The table used by ``dfhack.run_script()`` to give every script its own
1216+
global environment, persistent between calls to the script.
1217+
11511218
* ``dfhack.internal.getAddress(name)``
11521219

11531220
Returns the global address ``name``, or *nil*.
@@ -1156,14 +1223,38 @@ and are only documented here for completeness:
11561223

11571224
Sets the global address ``name``. Returns the value of ``getAddress`` before the change.
11581225

1159-
* ``dfhack.internal.getBase()``
1226+
* ``dfhack.internal.getVTable(name)``
1227+
1228+
Returns the pre-extracted vtable address ``name``, or *nil*.
11601229

1161-
Returns the base address of the process.
1230+
* ``dfhack.internal.getRebaseDelta()``
1231+
1232+
Returns the ASLR rebase offset of the DF executable.
11621233

11631234
* ``dfhack.internal.getMemRanges()``
11641235

11651236
Returns a sequence of tables describing virtual memory ranges of the process.
11661237

1238+
* ``dfhack.internal.memmove(dest,src,count)``
1239+
1240+
Wraps the standard memmove function. Accepts both numbers and refs as pointers.
1241+
1242+
* ``dfhack.internal.memcmp(ptr1,ptr2,count)``
1243+
1244+
Wraps the standard memcmp function.
1245+
1246+
* ``dfhack.internal.memscan(haystack,count,step,needle,nsize)``
1247+
1248+
Searches for ``needle`` of ``nsize`` bytes in ``haystack``,
1249+
using ``count`` steps of ``step`` bytes.
1250+
Returns: *step_idx, sum_idx, found_ptr*, or *nil* if not found.
1251+
1252+
* ``dfhack.internal.diffscan(old_data, new_data, start_idx, end_idx, eltsize[, oldval, newval, delta])``
1253+
1254+
Searches for differences between buffers at ptr1 and ptr2, as integers of size eltsize.
1255+
The oldval, newval or delta arguments may be used to specify additional constraints.
1256+
Returns: *found_index*, or *nil* if end reached.
1257+
11671258

11681259
Core interpreter context
11691260
========================
@@ -1231,6 +1322,42 @@ Features:
12311322
Invokes all listeners contained in the event in an arbitrary
12321323
order using ``dfhack.safecall``.
12331324

1325+
1326+
=======
1327+
Modules
1328+
=======
1329+
1330+
DFHack sets up the lua interpreter so that the built-in ``require``
1331+
function can be used to load shared lua code from hack/lua/.
1332+
The ``dfhack`` namespace reference itself may be obtained via
1333+
``require('dfhack')``, although it is initially created as a
1334+
global by C++ bootstrap code.
1335+
1336+
The following functions are provided:
1337+
1338+
* ``mkmodule(name)``
1339+
1340+
Creates an environment table for the module. Intended to be used as::
1341+
1342+
local _ENV = mkmodule('foo')
1343+
...
1344+
return _ENV
1345+
1346+
If called the second time, returns the same table; thus providing reload support.
1347+
1348+
* ``reload(name)``
1349+
1350+
Reloads a previously ``require``-d module *"name"* from the file.
1351+
Intended as a help for module development.
1352+
1353+
* ``dfhack.BASE_G``
1354+
1355+
This variable contains the root global environment table, which is
1356+
used as a base for all module and script environments. Its contents
1357+
should be kept limited to the standard Lua library and API described
1358+
in this document.
1359+
1360+
12341361
=======
12351362
Plugins
12361363
=======
@@ -1292,3 +1419,40 @@ sort
12921419

12931420
Does not export any native functions as of now. Instead, it
12941421
calls lua code to perform the actual ordering of list items.
1422+
1423+
1424+
=======
1425+
Scripts
1426+
=======
1427+
1428+
Any files with the .lua extension placed into hack/scripts/*
1429+
are automatically used by the DFHack core as commands. The
1430+
matching command name consists of the name of the file sans
1431+
the extension.
1432+
1433+
**NOTE:** Scripts placed in subdirectories still can be accessed, but
1434+
do not clutter the ``ls`` command list; thus it is preferred
1435+
for obscure developer-oriented scripts and scripts used by tools.
1436+
When calling such scripts, always use '/' as the separator for
1437+
directories, e.g. ``devel/lua-example``.
1438+
1439+
Scripts are re-read from disk every time they are used
1440+
(this may be changed later to check the file change time); however
1441+
the global variable values persist in memory between calls.
1442+
Every script gets its own separate environment for global
1443+
variables.
1444+
1445+
Arguments are passed in to the scripts via the **...** built-in
1446+
quasi-variable; when the script is called by the DFHack core,
1447+
they are all guaranteed to be non-nil strings.
1448+
1449+
DFHack core invokes the scripts in the *core context* (see above);
1450+
however it is possible to call them from any lua code (including
1451+
from other scripts) in any context, via the same function the core uses:
1452+
1453+
* ``dfhack.run_script(name[,args...])``
1454+
1455+
Run a lua script in hack/scripts/, as if it was started from dfhack command-line.
1456+
The ``name`` argument should be the name stem, as would be used on the command line.
1457+
1458+
Note that this function lets errors propagate to the caller.

0 commit comments

Comments
 (0)