This plugins embeds a ruby interpreter inside DFHack (ie inside Dwarf Fortress). The plugin maps all the structures available in library/xml/ to ruby objects. These objects are described in ruby-autogen.rb, they are all in the DFHack:: module. The toplevel 'df' method is a shortcut to the DFHack module. The plugin does *not* map most of dfhack methods (MapCache, ...) ; only direct access to the raw DF data structures in memory is provided. Some library methods are stored in the ruby.rb file, with shortcuts to read a map block, find an unit or an item, etc. Global objects are accessible through the 'df' accessor (eg df.world). The ruby plugin defines 2 dfhack console commands: rb_load ; load a ruby script. Ex: rb_load hack/plants.rb (no quotes) rb_eval ; evaluate a ruby expression, show the result in the console. Ex: rb_eval df.find_unit.name.first_name You can use single-quotes for strings ; avoid double-quotes that are parsed and removed by the dfhack console. If dfhack reports 'rb_eval is not a recognized command', check stderr.log. You need a valid 32-bit ruby library to work, and ruby1.8 is prefered (ruby1.9 may crash DF on startup for now). Install the library in the df root folder (or hack/ on linux), the library should be named 'libruby.dll' (.so on linux). You can download a tested version at http://github.com/jjyg/dfhack/downloads/ The plugin also interfaces with dfhack 'onupdate' hook. To register ruby code to be run every graphic frame, use: handle = df.onupdate_register { puts 'i love flooding the console' } To stop being called, use: df.onupdate_unregister handle The same mechanism is available for onstatechange. Exemples -------- For more complex exemples, check the ruby/plugins/ source folder. Show info on the currently selected unit ('v' or 'k' DF menu) p df.find_unit.flags1 Set a custom nickname to unit with id '123' df.find_unit(123).name.nickname = 'moo' Show current unit profession p df.find_unit.profession Change current unit profession df.find_unit.profession = :MASON Center the screen on unit '123' df.center_viewscreen(df.find_unit(123)) Find an item at a given position, show its C++ classname df.find_item(df.cursor)._rtti_classname Find the raws name of the plant under cursor plant = df.world.plants.all.find { |plt| df.at_cursor?(plt) } p df.world.raws.plants.all[plant.mat_index].id Dig a channel under the cursor df.map_designation_at(df.cursor).dig = :Channel df.map_block_at(df.cursor).flags.designated = true Compilation ----------- The plugin consists of the ruby.rb file including user comfort functions and describing basic classes used by the autogenerated code, and ruby-autogen.rb, the auto-generated code. The generated code is generated by codegen.pl, which takes the codegen.out.xml file as input. For exemple, Will generate class Unit < MemHack::Compound field(:name, 0) { global :LanguageName } field(:custom_profession, 60) { stl_string } field(:profession, 64) { number 16, true } The syntax for the 'field' method is: 1st argument = name of the method 2nd argument = offset of this field from the beginning of the struct. The block argument describes the type of the field: uint32, ptr to global... Primitive type access is done through native methods in ruby.cpp (vector length, raw memory access, etc) MemHack::Pointers are automatically dereferenced ; so a vector of pointer to Units will yield Units directly. Null pointers yield the 'nil' value. This allows to use code such as 'df.world.units.all[0].pos', with 'all' being in fact a vector of *pointers* to DFHack::Unit objects.