DYNAMICALLY LOADABLE MODULES TinyMUSH versions 3.1 and higher provide an interface for dynamically loadable modules. This allows server administrators to write and install "hardcode" that extends the functionality of the server, without creating undue difficulties with future upgrades. If you are writing a module, or you are installing a module written by someone else, please be forewarned: Modules muck directly with the server's internals. Using a module is, for all practical purposes, exactly like directly hacking the server. Thus, the safeguards that exist with softcode do not exist with modules; if modules contain bugs, they could cause severe issues with instability and database corruption. If you are writing a module, you should be fluent in reading and writing the C programming language. You should take the time to carefully study the existing server code. It's assumed you can read code to figure out things that aren't explicitly documented (which is just about everything not directly related to module interface). It's also assumed that you understand how dynamic loading works. ----------------------------------------------------------------------------- HOW TO BUILD A MODULE Every module must have a one-word name, such as "hello", or "space3d", referred to generically as '' in the rest of this document. This is the prefix of the shared object files that are loaded by netmush. The source for your module should be placed in src/modules/. The directory must use the same name as the shared object files your code produces. The shared objects for modules go in the game/modules directory. In your module's source directory you should have at least 5 files: configure.in, configure, Makefile.inc.in, .depend, and a C source file. Your best bet to get started is to make a copy of the 'hello' module source, substitute your own code for hello.c, and modify Makefile.inc.in appropriately. More advanced module code might make use of a customized configure script and Makefile, but that is beyond the scope of this document. NOTE: You must change the AC_INIT macro at the top of your module's configure.in to reference one of your C source files (it doesn't matter which one as long as it exists) and then regenerate the configure script using the GNU autoconf utility. Please see: http://www.gnu.org/software/autoconf/autoconf.html Getting the server to load a module is simple. For each module, add the following line to your netmush.conf file: module Modules can only be loaded when the game is started. CAUTION: If you are changing a dynamically-loaded module while the game is running, do NOT overwrite the old shared objects. The Makefile fragments we've included will move old .so files out of the way, but because they keep only one backup copy, they won't help if you rebuild your module twice before reloading it into the game. To be certain, you must go to game/modules/ and rename the .so file associated with your module. ----------------------------------------------------------------------------- MODULE NAMES AND SYMBOLS Everything within a module should occupy a unique namespace. Functions names, non-static global variables, and other public entities should be named 'mod__'. Macros and constants should be named MOD__. This avoids potential namespace collisions. All modules should begin with the following line: #include "../../api.h" Including this file should get you access to the commonplace structures and functions in the MUSH server, as well as specific module API things. Please note that if you plan to use any symbol that's not defined within api.h or a file that is #include'd by api.h, you will either need to declare it extern within your module's .c file, or #include the appropriate main server .h file, as appropriate. CAUTION: Not all operating system's dlopen() calls properly check for unresolved references. On such a system, if you reference a symbol that your module cannot locate because it's not local and it wasn't declared as extern, the server will crash when it tries to resolve the symbol. ----------------------------------------------------------------------------- MODULE CONFIGURATION The module configuration should come next, since the rest of your module will use this information. You should declare a configuration structure for your module as follows: struct mod__confstorage { ; ; } mod__config; Then, you should declare a configuration table, as follows: CONF mod__conftable[] = { {(char *)"_alias", cf_alias, , , (int *)&mod___htab, (long)""}, {(char *)"", cf_bool, , , &mod__config., (long)""}, {(char *)"", cf_const, CA_STATIC, , &mod__config., (long)}, {(char *)"", cf_int, , , &mod__config., }, {(char *)"", cf_dbref, , , &mod__config., }, {(char *)"", cf_modify_bits, &mod__config., (long)}, {(char *)"_access", cf_ntab_access, , CA_DISABLED, (int *)
, (long)access_nametab}, {(char *)"", cf_option, , , &mod__config., (long)