Javelin's Guide for PennMUSH Gods by Alan Schwartz Javelin@Belgariad and elsewhere Paul@DuneMUSH and Dune II Note: This document is available as both a single document (suitable for printing) and a multi-part document (more appropriate to hypertext). These multiple views are automatically generated with a Perl script called multiview, by James "Eric" Tilton, 3/29/94 (jtilton@willamette.edu), heavily modified by me. This document is text-browser friendly. Copyright (c) 1994-1998, Alan Schwartz (alansz@pennmush.org / Javelin). This document may be distributed freely in whole or part so long as none of its text is changed, no profit is made from the distribution, and appropriate attribution is given to indicate the source of the text. While every effort is made to ensure accuracy, the author can not be responsible for the results of applying the ideas herein. The current edition of this document is available online at http://www.pennmush.org/~alansz/guide.html. Here are the diffs since the last revision of the Guide, and here's the guide's log of changes. You can search the Guide. Please leave your comments about this Guide! [recommendedsite.gif] ------------------------------------------------------------------- Introduction and Thanks This document is an attempt to set down the fruits of my experience as a PennMUSH God, site admin, and source code hack. It should be particularly useful to the new PennMUSH God who's having trouble or wants to get a handle on where to start hacking in new features. Documentation is never a solo project. I am indebted first and foremost to Amberyl (aka Lydia Leong) not only for maintaining, updating, and generally rewriting the PennMUSH code into the form I received it in, not only for teaching me a great deal about how to build, run, hack, and debug a MUSH, not only for writing an excellent MUSH user and coder manual herself, but for that first roybit which got me started on the path to MUSH administration! I also thank all the MUSH gods who've contributed questions, problems, suggestions, patches, and ideas to the various MUSH mailing lists and newsgroups. As well as the players and admin of the various MUSHes which I've been involved in as site/source hack or consultant (Pandemonium, Mua'kaar, Gohs, Dune II, Princess Bride, Dorsai, and especially DuneMUSH) for their patience. :) Finally, the other past and present members of the PennMUSH development team made PennMUSH what it is today: T. Alexander Popiel, Ralph Melton, Thorvald Natvig. ------------------------------------------------------------------- Table of Contents * Introduction and Thanks * Table of Contents * Choosing to use PennMUSH + MUSH servers + Gathering system info + Penn and Tiny compared * Compiling PennMUSH + Getting PennMUSH + Files explained + Options explained + Making PennMUSH + Troubleshooting * Starting up + The game directory + The .cnf file + The restart script + The txt/*.txt files, @readcache, and mkindx + Minimal.db and first startup + Troubleshooting * MUSH Management + Using #1 + Dumps, shutdowns, db corruption, and paranoia + Wizard commands in detail + File descriptors and login limits + MUSH crashes + Lagging + Security and Access Control + Making Guests + Everyday stuff + Upgrading to a new patchlevel (applying patches) + Useful globals + Miscellany * Hacking PennMUSH + When to hack + Source code control, patches, and #ifdef + How-to o Add flags o Add powers o Add attributes o Add locks o Add functions o Add commands o Add a new set of indexed text files + Upgrading to a new patchlevel + Miscellany * Running a Successful Game: Tips from Gods + Contributors + Design tips + Administration tips + MUSHcode tips + Server tips * Resources + Where to Report Bugs/Problems + The PennMUSH mailing list + Newsgroups + Ftp Sites + Other MUSHes * Appendix: Useful scripts and code ------------------------------------------------------------------- Choosing a MUSH server Contents * MUSH servers * Gathering system info * Penn and Tiny compared MUSH servers There are currently at least four actively developed MUSH server flavors: PennMUSH The subject of this guide, a memory-based MUSH server. PennMUSH tends to suffer from creeping featurism, which may be a good or bad thing depending on your outlook. :) A lot of the development lately has focused on applying principles of good programming and design to the internals. TinyMUSH 3.x A server that merged the features of TinyMUSH 2.2.4 and TinyMUX. It has a relatively conservative development cycle, focusing more on stability than features, historically. Typically disk-based. Mux2 The continued development of TinyMUX, a MUSH server that can be either disk- or memory-based. Like PennMUSH, tends to have lots of interesting features, including an advanced channel system. Rhost Based on TinyMUD, but heavily developed thereafter to include a lot of additional features and security and efficiency tweaks. This is the only actively developed MUSH server that has a closed codebase; you must license with the developers (for free) to use it. Which server you should choose depends primarily on the features of your site and secondarily on the features of the server. The big first decision is if you want a memory-based server (PennMUSH) or a disk-based server (the others). If you choose disk-based, you'll get to make other choices which are not covered in this document. A very good list of servers that's often more up-to-date than the one above is maintained by T. Alexander Popiel at http://www.pennmush.org/~talek/mushinfo.html. Another is maintained by Brazil (the mux2 maintainer) at http://www.tinymux.com/links.html. Gathering system info Ideally you'll want to know the following information about the computer system on which you're going to run your MUSH: 1. What is the brand and model of the hardware? For example: Sun Sparcstation 2, DEC Decstation 3100S, etc. The "uname -a" command often will give you this information. 2. What is the name and revision level of the operating system? For example, SunOS 4.1.3_u1, Ultrix 4.2, etc. "uname -a" gives this information. It may also be mentioned in the banner you see when you log into the system or in the file /etc/motd. It's useful to know if the operating system is basically BSD (SunOS 4, Ultrix, HP-UX, Linux, NeXT) or SysV (Solaris 2, Irix) 3. How much physical memory is in the machine? For example: 8Mb (typical of a 386/486 machine), 16Mb, 64Mb, etc. Physical memory is ram chips on the machine's motherboard. Figuring this out can be tricky. You can usually find this out if you reboot the machine, or can read its boot logs, which are /usr/adm/messages or /var/adm/messages on most BSD systems. 4. How much virtual memory (swap space) is the machine configured for? Unix systems can use disk space as virtual memory - it's slower than physical memory, but much cheaper and more available. Virtual memory is used when processes need to be paged (portions of their memory sent to swap space) or swapped (the whole process sent to swap space) to free more physical memory. The command /etc/pstat -s reports total memory space (physical + swap) on BSD systems. Solaris uses swap -l. For others, check the man pages for 'swap' or 'virtual'. Typically, machines have around twice as much swap as physical memory, but this varies. 5. How much disk space will the MUSH have available to it? If you're running the game on someone else's machine (and of course you have permission, right? Illegal MUSHes are easily detected and often result in nasty consequences and give MU*'s a bad name), how much disk space can your game account use without causing problems? The upper limit is usually the size of the disk partition on which the game account lives. The "df" command shows the size of disk partitions, and the directories which are housed by those partitions. 6. What is the typical user load of the machine, and what is important to the users? If you own the machine and it's the workstation on your desk that only you use, there's no problem. If the machine is used by others however, it's important to consider what kind of other software is likely to be run. If people use it for email, news, and word-processing, they'll want quick keyboard response, but won't be taking up much CPU or memory. If people use it to compile large software packages or run statistical analyses, you'll be sharing much more CPU and memory. 7. How is the machine connected to the internet? Most university sites don't have to worry about the bandwidth of their connections, but if you're connected via a 14.4k SLIP line, expect some trouble. :) Penn and Tiny compared The main difference between PennMUSH and TinyMUSH is where the database is stored while the game is running. In PennMUSH, the database is loaded entirely into memory while the game is running (text on objects and in mail messages is compressed), and a copy of the database is dumped onto disk periodically. In TinyMUSH, the database resides on the disk, and as portions are needed, they are loaded into memory and cached (kept around for a while in memory). Additional memory is required for player connections, so the more players the game typically has, the more memory is typically required. Typically, this means that you want to run PennMUSH when you have plenty of memory to spare, and TinyMUSH when memory is scarce but you have plenty of disk space (and fast disks). Actually, things are a bit more complicated on modern workstations, since parts of the PennMUSH process that aren't being used will generally be paged out of memory to disk by the operating system. In some cases, this can be more efficient than having the MUSH server do the paging, but generally, it results in more use of physical memory. Here are some typical usage statistics for an earlier version of PennMUSH (more recent versions use a bit less memory and disk). The "memory" column refers to the game's total size (SZ on ps listings). The "disk" column refers only to the uncompressed size of the database - not the source code, executables, backup databases, etc. (TinyMUSH entries include the size of the .gdbm.{db,pag,dir} and the .db file). Typically for PennMUSH, you have 2 databases: the database from which the process was started (indb) and the database which the process is currently using/writing (outdb). It's also possible to use compressed databases, which save considerable disk space at the cost of longer startup times and dumps. Recent versions of servers: Type OS Name # Objects Memory Disk Penn1.7.2 Sun4.1.3u1 M*U*S*H 6700 21Mb 7Mb uncompressed Old versions of servers: Type OS Name # Objects Memory Disk Penn1.6.0 Sun4.1.3u1 DuneMUSH 19000 28Mb 14Mb uncompressed Penn Ultrix4.2 DuneII 2200 8.7Mb 3.8Mb uncompressed Penn Linux1.0.8 Gohs 2500 5.5Mb 1.6Mb uncompressed Tiny2.0.10 Sun4.1.3 TwoMoons 9350 5.5Mb 30Mb (1) (1) Info from elfchief@lupine.org. TwoMoons is based on Tiny 2.0.10p6 If you still can't decide between PennMUSH and TinyMUSH, or are fortunate enough not to care about either disk or memory space, here are the primary differences in features between Penn and Tiny 2.x. Thanks to T. Alexander Popiel for some of these. What Penn has that Tiny does not: * The Royalty flag, and @powers * Multiple control and local master rooms via Zones * A built-in mail system * A built-in chat channel system * A built-in building/topology checking system * Object creation/modification times * More extensive help and other documentations systems (news, rules, events, index) What Tiny has that Penn does not: * The @robot command * The @forwardlist command, which makes creating puppets which report to multiple players a whole lot easier * Exits within things and players * The @list command * Exits are inherited from parent rooms Of course, if you use TinyMUX or AlloyMUSH, you get the Tiny 2.x memory setup with many Penn-like features. The advantage of using TinyMUSH 2.2, however, is that its a current standard, and being actively developed - you get excellent support. ------------------------------------------------------------------- Compiling PennMUSH Contents * Getting PennMUSH * Files explained * Options explained * Making PennMUSH * Troubleshooting Getting PennMUSH PennMUSH up to 1.50 pl10 was developed by Amberyl. PennMUSH since then is being maintained by Alan Schwartz , and developed by Alan Schwartz, T. Alexander Popiel, and Shawn Wagner. There are also people responsible for various ports to other operating systems (Win32, Mac, OS/2) and groups of translators. PennMUSH now uses the following version-numbering scheme: 1.7.2 patchlevel 30 | | | | Code base version -----/ | | | Major version -----------/ | | Minor version -------------/ | Patchlevel -----------------------------/ The patchlevel is updated when new bugs are fixed by patches. The minor version is updated when a new version of the tar file is posted; it may include bugfixes and new features. The latest odd-numbered minor version is undergoing active development; the latest even-numbered minor version is only receiving bugfixes. The major version is updated when major internals are changed. You can find the most recent PennMUSH code at pennmush.org in /pub/PennMUSH/Source. It will have a filename like "pennmush-1.7.2p3.tar.gz". Once you've got the file, you'll need to uncompress it (using gunzip or uncompress if the file ends in .gz or .Z, respectively), and untar it ("tar xvf pennmush-1.7.2p3.tar"). As of PennMUSH 1.7.2, the tar file will create a pennmush/ directory and unpack into that. There may also be patches on the FTP site, which should be applied to the code once you've uncompressed and untarred it. They have names like 1.7.2-patch04. Only apply patches that are later than the version of the tarfile. To apply a patch, use the 'patch' command, like this: % patch -p0 < 1.7.2-patch04 GNU patch users may want "-b -p0" instead of "-p0". PennMUSH releases are signed with Javelin's PGP public key, which is also available in the ftp directory. Older versions of the PennMUSH source code can be found in the "oldsrc" subdirectory. Prebuilt binaries PennMUSH can be compiled on Windows 95/98/ME/NT/2k, MacOS 7/8/9/X, and OS/2 as well as Unix. But if you'd rather not compile and you have one of these operating systems, you can get a pre-built binary that you can simply run. You won't be able to configure some of the options that are set at compile-time, but you'll save yourself the work of compiling. * Prebuilt binaries for Win32 systems can be found at ftp://ftp.pennmush.org/pub/PennMUSH/Win32Binaries. * Prebuilt binaries for OS/2 systems can be found at ftp://ftp.pennmush.org/pub/PennMUSH/OS2Binaries. * Binaries (and source code) for Mac systems are maintained by Dan Williams, at http://mac.pennmush.org. ------------------------------------------------------------------- Files explained The files below are listed as they appear in the most recent PennMUSH releases. The PennMUSH source includes the following files: BUGS A list of known bugs in the current release. If you fix one, let me know! CHANGES Changes in the most recent minor version of PennMUSH. Update with each patchlevel. CHANGES.OLD Past changes COPYRITE A discussion of hdrs/copyrite.h, the terms under which you can use PennMUSH. Configure A program which automatically configures MUSH for your system and builds you a Makefile and some other important files. FAQ Some frequently asked questions Makefile.SH, config_h.SH A template for a Makefile and config.h. Configure uses this to build the real Makefile and config.h files. Patchlevel A file which tracks official patches to prevent them from being applied out of order. Don't mess with it. README Compilation instructions. If you haven't read this, do it now. options.h.dist A file which contains compile-time options that you'll want to set. Copy this to options.h, and modify that. src/Makefile The Makefile that actually builds the MUSH server. src/SWITCHES A file that contains a list of all the switches used by any MUSH command. The program utils/mkcmds.sh uses this file to build src/switchinc.c and hdrs/switches.h, used by the command parser. src/access.c and hdrs/access.h Code for controlling access to the MUSH src/announce.c The source code for a standalone port announcer. You can use this code when your MUSH is down to provide a simple message when people try to connect. But it's a bit buggy, so consider using portmsg.c, instead, described in the Appendix on Programs and Scripts. hdrs/ansi.h The header file defining ANSI codes src/atr_tab.c and hdrs/atr_tab.h Attribute table stuff. This code handles the hashed attribute table, and contains the attribute alias table. atr_tab.h contains the table of standard attributes. All standard MUSH attribs are listed here. The format is described below. src/attrib.c and hdrs/attrib.h Attribute setting and getting. The header file which lays out the actual attribute (ATTR) structure src/boolexp.c Working out boolean expressions (like locks!) src/bsd.c The tcp/ip socket interface to the MUSH. Handles player connection to the game, low-level input/output from players, WHO and QUIT. This is where the main() function is and where the main input/output loop is. src/cmdlocal.dst This file is copied to src/cmdlocal.c if it doesn't exist. If you add your own commands to PennMUSH, add them to src/cmdlocal.c. src/cmds.c This file contains the cmd_ functions that are called when a command called is run. src/command.c and hdrs/command.h The command parser. This file also includes the list of all the MUSH commands, their switches, etc. The header file lays out the structure of a command. src/compress.c A wrapper for the routines to compress and uncompress the text of attributes. This keeps down MUSH memory requirements. It either defines things for no compress, or includes comp_h.c, comp_b.c, or comp_w.c depending on the setting of the COMPRESSION_TYPE option. src/comp_b.c MUSH before 1.50pl10 used a "bigram" compression method, which is simple and unlikely to go very wrong, but doesn't give very good memory savings. This file contains that algorithm. src/comp_h.c MUSH after 1.50pl10 introduced a Huffman compression method which should reduce memory requirements but be slightly slower. src/comp_w.c Nick Gammon's word-based compression, required for Win32 machines. Unix sites can also use this method, which is more efficient for large databases than Huffman, but is not 8-bit clean. src/conf.c and hdrs/conf.h Code to read your mush.cnf file and set up the MUSH's configuration. The header file also defines important MUSH configuration constants that are rarely changed. src/convdb.c Code which does db conversions for db's which don't contain a Powers field and the like. hdrs/copyrite.h The copyright statement src/cque.c Code to maintain the MUSH queue src/create.c Object creation code src/csrimalloc.c and hdrs/csrimalloc.h An adapted version of the CSRI malloc package, a very efficient memory allocation system. src/db.c and hdrs/mushdb.h Code to implement the MUSH database, let you access objects, etc. hdrs/dbdefs.h Definitions of macros about db objects src/destroy.c Object destruction code src/extchat.c and hdrs/extchat.h Source code for the extended chat system. src/extmail.c and hdrs/extmail.h The source code for the PennMUSH @mail system. src/flags.c and hdrs/flags.h Code for setting, checking, and using MUSH flags is here. Also, the flag table and powers table are here. Constants representing MUSH flags and powers are defined in the header file. src/function.c and hdrs/function.h The function table and code for dealing with it. src/fun*.c The src/fun*.c files (src/funlist.c, src/funmath.c, etc.) contain the definitions of PennMUSH functions of various types. src/funlocal.dst This file is copied to src/funlocal.c if it doesn't exist. If you add your own functions to PennMUSH, add them to src/funlocal.c. src/game.c and hdrs/game.h The main MUSH command loop is here. hdrs/getpgsiz.h Header file to simulate the getpagesize() system call if your system doesn't have it. This is used only with the gmalloc package, and in fact behaves incorrectly on at least Ultrix 4.2. hdrs/globals.h Global macros. A very small file. src/gmalloc.c The source code for the GNU malloc package, one of the basic malloc packages. Discussed below. hdrs/help.h Header containing the structure of a help index entry. src/htab.c and hdrs/htab.h Code for implementing hash tables, taken with permission from TinyMUSH 2.2, but since modified. src/ident.c and hdrs/ident.h Source code for the ident (RFC1143) client routines. Discussed below. src/info_slave.c Source code for the info_slave process, a separate program which the server can use to do DNS and ident lookups so the main server doesn't have to wait around for these things. Discussed below. src/intrface.c and hdrs/intrface.h This file really doesn't do much more than #include bsd.c. If more kinds of interfaces were written (or if the port concentrator worked), this file would include the appropriate code. src/local.dst This file is copied to src/local.c if it doesn't exist. It contains hooks for adding your own local hacks to PennMUSH without disrupting the distributed source code. If you want to extend the db object structure, this is where you can do it. src/lock.c and hdrs/lock.h Code for the extended @lock system introduced in pl13. To add new locks, you'll modify the top of lock.c and the bottom of lock.h src/log.c Code to do logging of things to the logfiles src/look.c Code for look and examine src/match.c and hdrs/match.h Code to determine if an object matches a name, with various constraints. This is where the MUSH figures out if, say, there's an exit in the room called 'out'. The header file contains the match.c prototypes; it's included in other modules which intend to use matching functions. src/memcheck.c and hdrs/memcheck.h Code to do some simple checking on the allocation and deallocation of memory src/mkindx.c The mkindx program, which creates indexes for the help.txt, news.txt, and events.txt files. When building on Win32 systems, this code is incorporated directly into the server. src/move.c Code to move objects from place to place. Commands like @tel, enter, and moving through exits. src/mycrypt.c A wrapper file that defines the mush_crypt() function, which is used for encrypting player passwords. Depending on the setting of CRYPT_SYSTEM in options.h, encryption may use the standard UNIX crypt(3) routines, SHS, or no encryption at all. src/mymalloc.c and hdrs/mymalloc.h A wrapper file that includes one of the malloc packages (nmalloc, smalloc, gmalloc, csrimalloc, or nothing) depending on the setting of MALLOC_PACKAGE in options.h. The header file must be included in any source code that calls mush_malloc(). src/nmalloc.c Nick Gammon's nmalloc package, for win32 systems. hdrs/oldattrb.h The old header file attrib.h, used in some db conversions src/parse.c and hdrs/parse.h The function parser src/player.c Code to handle players, including creation, password-checking, names and aliases, etc. src/plyrlist.c This maintains the list of connected players and aliases. src/portmsg.c Code for the portmsg program, a standalone program that simply listens for connections on a port, spits back a message, and closes the connection. Useful when your MUSH is down. See also src/announce.c, which does the same thing differently. src/predicat.c A bunch of standard functions to check various conditions. One of the most important source code functions, controls(), is here (which determines when one thing controls another!) src/privtab.c and hdrs/privtab.h Code for privilege tables, a data structure used by the MUSH. src/rob.c Code to manage MUSH money, include give and rob. src/rpage.c Code for remote-paging of other MUSHes src/rwho.c Code for reporting MUSH connection and disconnection information to an RWHO server. Discussed below. src/services.c Code for the win32 versions to allow pennmush to run as a service. src/set.c Code for setting object attributes. src/shs.c and hdrs/shs.h Code for the SHS password encryption algorithm. src/smalloc.c The Satoria malloc package, one of the 3 standard ones. src/speech.c Code for messages, including say, pose, page, whisper, @emit, etc. (Doesn't include @mail or @chat) src/strutil.c Utility functions for doing string comparisons and similar kinds of things. src/SWITCHES The master list of all switches taken by any command. src/switchinc.c and hdrs/switches.h C versions of SWITCHES, automatically built during compiling. src/timer.c The game timer, which determines when a dump should take place, when objects from the wait queue should be triggered, etc. src/unparse.c Unparsing an object is correctly displaying its brief examine information (flags, locks, etc.) Some routines for that are here. src/utils.c Various utility functions. src/version.c Source file which implements the @version command, reporting build time, date, flags, and MUSH version. This file is rebuilt at every compile. hdrs/version.h Header telling you the version of the code src/warnings.c and hdrs/warnings.h Code which implements the building warning system if USE_WARNINGS is defined in options.h. src/wild.c Code for wildcard matching src/wiz.c Wizard functions and commands are defined here patches/ If you plan to apply user-contributed PennMUSH patches, create a subdirectory called patches and store applied patchfiles there. The server will try to incorporate the patch names and versions into the @version output. game/ The directory for run-time game stuff, including: game/access.README The access.cnf file controls which sites can access the MUSH in a various ways. You can prevent sites from connecting, creating players, and connecting to guests. You can also enforce registration and automatically SUSPECT players from certain sites. access.README explains how to create access.cnf. Details about access.cnf can be found in the section on Security. game/mushcnf.dst game/mushcnf.dst is a template for game/mush.cnf, the run-time configuration file for the MUSH, discussed below. game/names.cnf A list of names which players aren't allowed to use. Obscenities typically, and/or out-of-theme names. game/restart The MUSH startup/restart shell script. You'll want to edit this to reflect your setup. Discussed below. game/data The directory for game databases in use game/data/minimal.db The minimal database, containing 3 objects: #0 (Limbo, the start room), #1 (One aka God, the SuperWizard), and #2 (the Master Room) game/log The directory where MUSH log files are created game/save The directory where backup databases are usually kept game/txt The directory for text files used by the MUSH game/txt/connect.txt and game/txt/connect.html Text file shown when a player connects to the MUSH. The html version is shown if a player connects using Pueblo. game/txt/create_reg.txt and game/txt/create_reg.html Text file shown when a player tries to create a character from a site where creation is not allowed. game/txt/down.txt and game/txt/down.html Text file shown when the MUSH is set to disallow non-admin logins and any player tries to connect game/txt/events.txt Text file containing 'events' entries. This file is built for you from files in the game/txt/evt directory. See game/txt/README for information. game/txt/full.txt and game/txt/full.html Text file shown when a player tries to connect to the MUSH and the MUSH is full (at the player login limit) game/txt/guest.txt and game/txt/guest.html Text file shown to guests that log in. game/txt/help.txt Text file containing 'help' entries. This file is built for you from files in the game/txt/hlp directory. See game/txt/README for information. game/txt/motd.txt and game/txt/motd.html Text file shown to all players on connection. game/txt/news.txt Text file containing 'news' entries. This file is built for you from files in the game/txt/nws directory. See game/txt/README for information. game/txt/newuser.txt and game/txt/newuser.html Text file shown when a player successfully creates a new character game/txt/quit.txt and game/txt/quit.html Text file shown when a player quits game/txt/wizmotd.txt and game/txt/wizmotd.html Text file shown when an admin connects ------------------------------------------------------------------- Options explained The options.h file lists the compile-time options which can be turned on or off. Whenever you change one of these files, you should recompile the MUSH. Options which are unclear or which deserve special mention are discussed in this section, in order of their appearance in options.h. CRYPT_SYSTEM determines how player passwords are encrypted. Because Win32 PennMUSH must use SHS encryption (CRYPT_SYSTEM 2), and because some Unixes vary in their implementation of DES encryption, consider using SHS encryption if you expect to need to move your database to another site running a different operating system in the future. Defining MEM_CHECK allows you to test for memory leaks if you know what you're doing. When MEM_CHECK is defined, a count is kept of each memory allocation of various types which is incremented when more memory is allocated and decremented when memory is freed. You can see the list of active (allocated) memory counters by logging in as #1 and typing @stat. If an allocation from a certain function builds up and never decreases, the function may be leaking memory and you can examine it. Rhyanna provides more detailed information about how to use MEM_CHECK. Leave MEM_CHECK undefined for a normally running MUSH, as it's more efficient without. LOCAL_DATA adds a pointer to the db object structure from which you can add your own extensions to the db. A boon for serious hackers. See src/local.dst for some information. If INFO_SLAVE is defined, a program called info_slave will be compiled and will run alongside the MUSH server. The MUSH will ask info_slave to do DNS and ident lookups on new player connections, so the MUSH doesn't have to wait around for answers to these lookups. FUNCTION_SIDE_EFFECTS are nifty, and make possible some very queue-light (albeit often CPU-intensive) code. They also make possible a lot of security problems. In general, if your coders aren't demanding these, avoid them. While the SINGLE_LOGFILE option can save some file descriptors and possibly allow more players to log in to your MUSH, it should be avoided in general as it makes dealing with your MUSH's error, warning, and other output more difficult. However, if you do want to use it, you can often separate out the individual components by using the 'grep' command and searching for NET, RPT, ERR, WIZ, or LOG. Making PennMUSH Always read the README file for detailed instructions. Let me say that again. Always read the README file for detailed instructions. Here's the quickstart version: 1. Win32 users should get and install the Cygnus gnu-win32 tools. This provides a very good unix-like environment on your win32 system, including the free gcc compiler. Find the tools at http://www.cygnus.com/misc/gnu-win32 and be sure you get the full development kit and follow its installation instructions. Win32 users can build with gnu-win32 alone, or with gnu-win32 and Microsoft Visual C++; the latter builds an executable that can be used on systems that don't have gnu-win32. If you want to use MSVC++, the command-line compiler "cl" should be in your path. Run 'bash' and perform all following steps from within a bash shell. 2. Type 'sh Configure' to autobuild a Makefile. Advanced users: If you need to force Configure to do something (for example, add a special compiler flag automatically), you can create a config.over file that overrides values of Configure variables (much the way the hint/* files work). Don't expect compile help from Javelin if you do this. 3. Do one and only one of the following. Either: + Copy options.h.dist to options.h and edit it, or + Do a 'make update' which will walk you interactively through all the options, or + If you're upgrading to a new patchlevel, copy your old options.h and dune.h to your new directory, and then 'make update' - your old settings will be read and incorporated into a new options.h. You'll be prompted for new options. 4. Do a 'make install' to build the files and set up symbolic links. Symbolic links don't work on win32, and info_slave.exe won't build - follow the README instructions about this. 5. Do a 'make customize' if you want to customize a directory for your mush (very handy if you run multiple MUSHes). This requires perl. For example, if you customize for 'mymush', a duplicate game/ subdirectory called mymush/ will be created, containing mymush.restart and mymush.cnf already set up correctly. The databases will be named indb.mymush.Z, outdb.mymush.Z, and maildb.mymush.Z, and will live in mymush/data. Troubleshooting If you have trouble compiling, you can get help from Javelin (dunemush@pennmush.org). Don't ask the mailing list for help on compiling! When you email Javelin, be sure you include complete information about the hardware, operating system, compiler used, any weird problems, etc. It's a good idea to include a copy of the make error. You can save a copy of your make output by using a command like: make |& tee make.log (csh, tcsh, etc) make 2>&1 | tee make.log (sh, ksh, bash, etc) Or you can use the UNIX 'script' command, which makes a copy of everything you type or see: script make.log make (type 'exit' or ctrl-D to stop logging to the file) ------------------------------------------------------------------- Starting up Contents: * The game directory * The .cnf file * The restart script * The txt/*.txt files, @readcache, and mkindx * Minimal.db and first startup * Troubleshooting The game directory The game/ subdirectory houses the files that the MUSH uses when it's running, including database, text files, and logs. If you use the 'make customize' feature, your "game" directory will have a customized name instead of "game", and your mush.cnf, restart, and database files may have different names as well. The MUSH game subdirectory contains the following files and directories: mushcnf.dst The distributed template for mush.cnf. Your mush.cnf file is built or updated from this file when you upgrade your PennMUSH to a new version. Don't mess with it. mush.cnf The config file for your mush (make a copy of this using the name of your mush, e.g., dune.cnf, unless you're using win32, in which case you must use mush.cnf as the name) access.README An explanation of how to create and use the access.cnf file. restart The restart script for starting up the MUSH data/ Directory containing your game's database(s) save/ Directory for old game databases txt/ Directory for .txt files (help, events, news, and various message files) log/ Directory for MUSH log files The .cnf file The mush.cnf file lists a set of run-time options that can be changed without having to recompile the MUSH. Changes to the .cnf file can be made while the MUSH is running. You must send a signal 1 (HUP) to the MUSH process for the changes to take effect. Use ps to find the PID# of the MUSH process (netmush or netmud) and then kill -1 PID#. mush.cnf includes comments about all of its options. Read them carefully. Here are a few extra notes: player_start This is the room number where newly created players connect to. It defaults to 0, but you will probably want to change it for a non-social MUSH, since #0 is always a good building nexus (because rooms which can be reached from #0 are "connected" and don't give the owner the disconnected room message). master_room If this is defined (as the db number of the master room), then the Master Room's exits are global throughout the MUSH, and any $commands on objects in the Master Room are global. By default, this is room 2, which comes with minimal.db. max_channels, max_player_chans, chan_cost These refer to @chat channels under the extended chat system. max_channels sets the maximum total number of chat channels that can be created. max_player_chans sets the number of channels that each mortal player can create ("0" means only admin may create channels). If mortals can create channels, chan_cost specifies the cost in mush coins to create a channel. Setting this to a high number can prevent rank newbies from creating a bunch of channels. dump_interval The time in seconds between MUSH checkpoint dumps. For reference, 3600 seconds is an hour, 7200 = 2 hours, 10800 = 3 hours, 14400 = 4 hours, 21600 = 6 hours, 28800 = 8 hours, and 43200 = 12 hours. If you don't do dumps at least every 12 hours, you're playing with fire. If you do any kind of development or hacking on your MUSH, dump at least every 3 hours. max_logins This is where you set the maximum number of players who can log in, if you have LOGIN_LIMITS defined. See the section on file descriptors and login limits for more information. player_queue_limit Mess with the default of 100 at your risk. If this number is too low, players won't be able to queue enough commands to make some of their objects work. If it's too high, runaway objects may eat up too much queue space and lag your MUSH. This makes you vulnerable to a denial of service attack by a twink as well as to coder mistakes. queue_chunk When the MUSH is not processing input from the net, it takes some commands off the queue and runs them. This parameter controls how many commands are run. The higher the number, the less your queue will build up, but the slower the game's net response will be. The default of 3 is usually fine, since by the time the queue's a serious issue, there's often nearly constant net activity anyway. See below. active_queue_chunk When there is net activity, the MUSH still can take some commands off the queue for processing. By default, it takes off a single command, giving the queue the same priority as a single player. If you get a lot of players and find your queue building up unacceptable, raising this (start by raising it to 2) can reduce queue build-up (and therefore queue lag) at the expense of slower command response. It's a tradeoff, but it often pays when there's a slew of players and queued commands. function_recursion_limit Mucking with this can allow code to waste CPU by recursing (calling itself) too many times. Encourage your coders not to write recursive code, and keep this at the default of 50. function_invocation_limit The maximum number of functions that can be invoked in a single command. This can be a hassle if you try to do some kind of @dolist on all the objects in your database, but it pays to keep it down to the default of 2500. log_wipe_passwd The @log/wipe command is a God-only command that erases one of the MUSH logs. Because this can be used to hide a hacker's tracks, the log_wipe_passwd in mush.cnf must be given in the @log/wipe command. Set this password to something other than the default value! rwho_* The values for the rwho parameters can be obtained by emailing jds@moebius.math.okstate.edu and asking for an RWHO password, as discussed in the README file. ident_timeout The timeout value here applies to the MUSH if info_slave isn't being used. log_* These parameters control what the MUSH will log. log_commands and log_huhs will both produce huge spammy logs - don't use them unless you're trying to identify what command is causing a crash or something. I recommend log_forces for security reasons unless you have a global which does a lot of @forcing (like some versions of Dynamic Space). I don't use log_walls, myself, but if you like to watch your wizards, you could. These can also be turned on and off with @enable/@disable, as can logins and daytime. player_creation When set to "no", the create and register commands at the connection screen are disabled. Another option is to to leave this as "yes" and disable creation for specific sites (or all sites) by using access.cnf. daytime The "computationally expensive" commands are: @find, @entrances, @mail/stats, @search, and the lsearch() function. room_flags, player_flags, exit_flags, thing_flags These very handle parameters allow you to set up flags which should be automatically set on any object of a given type that's created on the MUSH. Having rooms and players (and possibly things) start out no_command is a good way to save CPU time that would be spent searching things for $commands. Starting players enter_ok makes a lot of sense. Some MUSHes may want to start exits transparent or players opaque or whatever. On DuneMUSH, we had a flag called "unregistered", and players started with this flag set, allowing us to do on-line registration. restrict_command restrict_command allows you to disable commands or restrict their usage to certain classes of players. If multiple restrict_commands refer to the same command, they *all* apply. If a command is disabled (restricted to "nobody"), you can implement it in MUSHcode as a $command instead. The restart script When you run the restart script, here's what it does: 1. Sets some variables to use later. You must define GAMEDIR to point to your game directory, CONF_FILE to point to your .cnf filename, and LOG to point to where your server error log file should be kept. If you've used 'make customize' these will be set for you. 2. Scans your .cnf file and figures out the name of your incoming and outgoing databases, and the compression scheme you use. 3. The "mush" variable is set to 1 (or higher) if there's already a MUSH running with your .cnf file, or 0 otherwise, by using a tricky little ps/egrep thing. If the MUSH is already running, restart reports that, and quits. 4. The help.txt, news.txt, and events.txt files are re-mkindx'd by running 'make' in the txt directory. 5. If there's a PANIC.db, and it's complete (i.e., the game was able to finish the whole panic dump), we turn it into an outdb. 6. All the log files are erased. You may want to change the script to preserve some of these. 7. Tries to find a database to start up, in this order: + If there's an outdb, indb is moved to save/indb.old, and outdb is moved to indb. + If not, and if there's an indb, we use that. + If not, and if there's a save/indb.old, copy that to indb and use that. + Finally, if we can find minimal.db, we'll use that. 8. If a reboot.db file exists, it is removed. This file is used to preserve information when @shutdown/reboot is run, and shouldn't exist when restarting from the shell. 9. The MUSH is run. The txt/*.txt files, @readcache, and mkindx PennMUSH uses two kinds of text files, both of which live in the game/txt subdirectory: cached text files and indexed text files. Cached text files The cached text files contain various messages which are displayed to players under different circumstances. The MUSH reads these (typically short) files into memory when it starts up ("caching" them), and when you change these files, you must use the @readcache command on the MUSH to update the memory versions. These files include: connect.txt and connect.html The connection screen. This file should give the name of the MUSH (and usually the source code version), an email address for the God or contact person, and character connection/creation information. It should also include the "Type WHO to see who is currently connected" line that's in the default connect.txt - MUSH clients like tinyfugue use this line to detect when to start displaying text when they're doing quiet logins. If you're supporting Pueblo clients, the connect.html file is an HTML-format connection message for Pueblo clients. quit.txt and quit.html Shown to players when they QUIT or LOGOUT down.txt and down.html Shown to players when logins are @disabled (i.e., when only admin can log in). Often unused in favor of @motd/nologin, which doesn't require site access. newuser.txt and newuser.html Shown to players when they create a new character. motd.txt and motd.html Shown to players after they've connected to their character. Often unused in favor of @motd, which doesn't require site access. guest.txt and guest.html Shown to Guests when they connect. wizmotd.txt and wizmotd.html Shown to admin when they connect. Often unused in favor of @motd/wiz, which doesn't require site access. Sending a signal 1 (SIGHUP) to the MUSH process (see .cnf file above) also causes the MUSH to re-cache the cached .txt files, just like using @readcache. On Unix, one does this using the command 'kill -1 '. Indexed text files The indexed text files are help.txt, news.txt, events.txt, rules.txt, and index.txt, depending on what you've got defined in mush.cnf. These files are often long, so to speed up access, the MUSH uses indexes which help it quickly find where in the file a given topic is. Before 1.7.3p9, these indexes were kept in index files, help.idx, news.idx, and events.idx, built with the mkindx program (e.g., mkindx news.txt news.idx), and had to be rebuilt whenever you changed one of these files. From 1.7.3p9, the indexes are kept in memory, so there are no index files or mkindx program. They still need to be rebuilt when you change a help file, but @readcache does that. The help.txt, news.txt, and events.txt files themselves should not be edited, because they are built from files residing in the txt/hlp, txt/nws, and txt/evt directories. This allows you to keep your local help files separate from those distributed with PennMUSH, and to manage them as a set of files rather than a single large file. Here's how it works: 1. The source files for help.txt, news.txt, and events.txt are kept in directories called hlp, nws, and evt respectively. 2. Files in those directories which end in . are considered to be part of the text. That is, files in hlp/ which end in .hlp, and files in nws/ which end in .nws will be merged into the final help.txt, news.txt, or whatever. 3. When the MUSH is restarted, a 'make' is run in this directory. If any file in hlp/ is newer than help.txt, it calls compose.csh to rebuild help.txt. If you've got perl on your system, compose.csh will also call index-files.pl to make a 'help index' entry which lists all your help entries. So, if you want to add your own news entries, make a file called nws/local.nws and put 'em there. Or maybe organize it into parts: nws/theme.nws, nws/code.nws, etc. Then run 'make' in the game/txt directory. The directions which follow about formatting these files still applies to the files in the hlp/, nws/, etc. subdirectories. The format for the indexed text files is a topic line (or set of lines) followed by the text of the topic. Topic lines begin with "&". The topic "& help" (usually first in each file) is shown if the player types "help", "news", or "events" without any topic. Topic names with themselves beging with an & denote admin help or news topics, accessible with the ahelp or anews commands. Here's what a piece of a news file might look like: & rpg <-- note that both topics will work for this entry & game You've typed 'news rpg' or 'news game'. This is the player information for the role-playing game... & &rpg You've typed 'anews rpg', and you must be an admin. This is the admin information for the role-playing game. Caution: Only topic lines should start with &'s. Lines of the help entry which need to start with &'s (like programming examples of the form: &test me=....) should have at least 1 space before the & so that it's not the first character on the line. Minimal.db and first startup Now you're ready for that first startup. Go to the game directory and type 'restart' (or './restart' if "." isn't in your path). To monitor the restart, type: "tail -f log/netmush.log", which will show you the progress of the startup. When it reaches "MUSH startup completed" (or an error message!), hit ctrl-C to kill the tail process. (If you got an error, see Troubleshooting, below). In general, you can check to see if the mush is running by using "ps -ux" (on BSD systems) or "ps -lf" (on SysV systems), and looking for the process named "netmush" or "netmud". If you've got INFO_SLAVE defined, there should also be a process called "info_slave" running. Assuming you've succeeded in getting the MUSH up and running on your chosen port, here are some things you should do immediately: 1. Log in as One (no password) and change One's password. (Many people also rename One to God or some other appropriate name). This is very important, as #1 is the only player which can confer wizbits on other players, and needs to be protected. @dig a floating room for God to live in, and @tel and @link #1 there. 2. Make a wizard character for yourself. You can do it while logged into #1 by using @pcreate name=password, @set *name=wizard. Once you've done this, you can log out of #1 and into your wizard character. You'll need #1 later, but it's best not to use God unless necessary. 3. Create some guest characters, if you like. You can do this with @pcreate as above, and @power *name=guest. I typically use the following kind of code: @dol Guest Guest2 Guest3 = {@pcreate ##=guest; @power *##=guest; @desc *##=A guest. Be kind. } One of your Guest characters should be either named Guest or have an alias of Guest. Troubleshooting The MUSH crashes If the MUSH actually crashes (leaving behind a file called "core" in the game directory), see the section on MUSH crashes. The problems addressed here result from the MUSH failing to load the db, and exiting cleanly. Problems loading minimal.db Most problems loading minimal.db are caused by misconfiguring the compression options in mush.cnf or databases with funny end-of-line characters. The symptoms of these problems are messages like: Bad character 0 on object 0 Bad attribute list object 0 Problems loading your db "Bad character on object xxx" - the bane of all MUSH Gods. If you've had this db working before, and you haven't modified the source code, this indicates there is some corruption of your database. To recover, you'll want to locate the corruption by hand-editing the db. Here are the steps: 1. MAKE A BACKUP OF THE DB! Do this every time. It's very very easy to make a mistake. I put mine in game/save, with names like indb.(date).corrupt 2. If your db is compressed, uncompress it. 3. Load your db into your favorite editor. Some editors can not handle some db's, usually because the lines of text in the db are too long for the editor's buffer (Sun's vi can have this problem), and sometimes because the db itself is too large (20Mb is a big file :). GNU emacs version 19 works pretty reliably. If the problem is the size of the file as a whole (not line length), you can use the unix 'split' (split indb) command to split up the db into 5000-line chunks which you can paste back together when you're done using 'cat x?? > indb.new'. 4. Find the offending object. The beginnings of objects are indicated by lines which start with !object# (for example, "!512"). The next set of lines which contain numbers represent the object's type, flags, powers, chat channels, locks, etc. 5. If you're lucky enough to know the attribute on the object that's causing your trouble, you can find it. Attributes start with a "]" symbol (for example: "]STARTUP"). If you just know the bad character, start searching for that character in the object. The attribute name is followed by some owner and flag information (separated by ^'s) and then on the next line, the text of the attribute itself, which is a single line but may contain literal carriage returns (^M's). 6. When you find the problem character, try to fix it. The most reliable fix tends to be deleting that attribute (the ]attrib line, and the line following it which contains the character), but if you see something strange (control characters besides ^M, hard returns in attributes, etc.) you could try just fixing that and see if it helps. 7. Quit the editor, saving the new db, recompress it if necessary, and try starting up under it. Repeat as above until it works. :P ------------------------------------------------------------------- MUSH Management Contents * Using #1 * Dumps, shutdowns, db corruption, and paranoia * File descriptors and login limits * Wizard commands in detail * MUSH crashes * Lagging * Security * Making Guests * Everyday stuff * Upgrading to a new patchlevel (applying patches) * Useful globals * Miscellany Using #1 God, player #1, is a very special Wizard, and a very useful tool. God can do some things that no other Wizard can, and some commands function differently for God. Because of these powers, it's wise to safegaurd God's password at least as well as you would the MUSH account's password. While the same can be said about any Wizard password, it goes doubly for God. Making wizards God is the only thing in the game which can set a WIZARD bit on a player. When you recruit Wizards for your MUSH, you'll have to log in as God to grant them the bit. For that matter, only God can remove a wizard bit or @nuke a wizard player, a definite safety feature. Malloc stats If you have MEM_CHECK defined, or are using smalloc.c with debugging, running @stat as God will give you a dump of memory allocation information internal to the game. This can be useful in debugging memory leaks and the like. @startup for @functions When the MUSH starts up, the @startup attribs on all objects are triggered, in ascending order of db#. This means that God's @startup is the first one triggered, which makes it ideal for doing @function commands, since later @startup's may rely on your @functions being installed. Schmidt@Dune (and elsewhere) developed this code for #1's startup to make automatic @function setup easier: @STARTUP #1=@dolist lattr(#191/FN_*)=@function [after(##,FN_)]=#191,## (In this case, object #191 had all the global functions on attribs call FN_FOOFUNC, FN_BARFUNC, etc.) Miscellany * Only God can use the @poor and @allquota commands. * Only God can use @log/wipe to erase a game log, and this additionally requires the password given in mush.cnf. * God may @chown a player, which should only be used if, due to some corruption, a player ends up not owning themselves. God can also @boot players who the game lists as not connected. Don't do it. * God can @wipe wizard-only attributes on things. Even wizards can not (using @wipe - they can clear them manually). * Only God may @set, @edit, @tel, @force, or @trigger God. * Only God can do @mail/nuke and wipe all @mail. And only God may use the mail() function to read other players' @mail. * God may change a player's name (using @name) without giving the player's password. Shutdowns, dumps, and paranoia What's a dump? A database dump is the process of making a copy of the MUSH's database (which is in memory when the MUSH is running) on the machine's disk. This is absolutely necessary when the MUSH is shut down, so that it can be restarted in the same state it was in when it was shut down. In addition, "checkpoint dumps" are performed by the MUSH at regular intervals (e.g. every hour, every 3 hours, every day, or however you configure it in mush.cnf). If the MUSH should crash, it can be restarted from a checkpoint dump, and data loss will be restricted to changes made in the last interval. Finally, a dump can be performed by a wizard using the @dump command. What's a forking dump? In mush.cnf, you can decide if your MUSH should fork when it dumps. "Forking" means that the MUSH makes an identical copy of itself in memory, and that copy runs the dump and then exits, while the original copy continues doing MUSH things. This means that players won't even notice when your MUSH dumps, which is nice. Forking doesn't work on Win32. There's a downside, however. When the MUSH forks, there are basically two MUSH processes running. That means durnig the dump, your MUSH is using twice the CPU (roughly) and twice the memory that it normally would. Unless your machine has a lot of memory (or your MUSH is very small), this can cause the MUSH to swap, and lag everyone badly. The alternative is to dump without forking. While the MUSH is dumping, it can do nothing else in this case, so the game will pause until the dump is complete. It gives the players a message to let them know that there will be a pause. What happens on a shutdown dump? A shutdown dump is just like any other dump, but it occurs at shutdown. :) What's a paranoid dump? A paranoid dump is performed by a Wizard typing @dump/paranoid. A paranoid dump differs from a normal dump in that it automatically corrects certain kinds of database corruption, writing out a non-corrupt database to disk. This is often useful when your database is corrupted in such a way that normal dumps cause a crash. You can @dump/paranoid, kill -9 the MUSH process (DON'T @shutdown, which will overwrite the paranoid dump with a corrupt one), and then restart from the paranoid dump. What exactly does a paranoid dump try to fix? * Bad attribute names: Unprintable characters or spaces in names of attributes will be replaced with a '!' character. * Bad attribute owners: If the attribute is owned by an invalid db#, its owner will be set to God. * Bad attribute text: If the attribute's text contains unprintable characters or hard newlines (\r's and \n's), they will be replaced with '!' characters. The fixing of hard newlines used to be important, but is actually now more of a hassle since MUSH can now deal with \r\n's in dbs. What's a debug dump? A debug dump is performed by a Wizard typing @dump/debug. It's a paranoid dump that also tries to repair some of the problems it finds on the in-memory (running) copy of the database, as well as writing out a clean database. It only corrects bad attribute owners like this (but these are the most common corruptions that cause crashing on dump). What's a panic dump? A panic dump occurs when the MUSH process is terminated with a signal 15 (SIGTERM). This is a pretty unusual thing, but if someone accidentally kills your MUSH process somehow, it'll attempt to save a copy of the database before it dies. The copy will be stored in game/data/PANIC.db, and will be uncompressed. You can tell if the dump was successful by examining the last line of that file. If it's ***END OF DUMP***, it was successful. The restart script knows about panic dumps, and will try to restart from a panic dump if it can find a successful one. File descriptors and login limits How many players can be connected to a MUSH at once? There are 3 factors which affect the answer to this question. The operating system Each player connection comes in over a TCP/IP socket, and each socket require that the operating system allocate it a "file descriptor", a number which refers to that socket. In addition, each file which is opened by the MUSH process (standard input, standard output, standard error, one for each log file, one reserved for reading help/news/events files, one to accept connections) requires a file descriptor. Most operating systems have limits on how many file descriptors a user's process can open. Some typical limits are 64, 128, or 256. Sometimes there will be a 'soft limit', which is lower than the maximum, and which you can increase (via the 'unlimit' command in the csh) up to the 'hard limit', or system maximum. The hard limit can only be raised by the system adminstrator recompiling the system's kernel. This is not too bad to do under SunOS 4.1.x (NOFILE in sys/param.h), Ultrix 4.2 and later (NOFILE in h/param.h and max_nofile in conf/{mips,vax}/param.c), and Linux, where you always have kernel source. Note: SunOS 4.1.x systems have (by default) a limit of 256 descriptors, but there's a bug in the stdio code which prevents descriptors after the first 128 from working correctly. :( When you run out of descriptors and the MUSH tries to open another one, it will likely either crash or hang. Since the MUSH requires about 10 descriptors for itself (6 if you define SINGLE_LOGFILE), subtract that from the hard limit to figure out how many players you can support. CPU/memory/network bandwidth There's also a practical limit. The more players you have connected, the more work the CPU has to do to service the process, the more memory will be used (for player objects and for all those queued commands), and the more load will be placed on your network connection. At some point, your game will begin to lag increasingly. Once again, little can be done unless you have a budget for better hardware. Setting login limits Finally, you can set a limit on how many players your MUSH will accept in your mush.cnf file. Usually, you just want to set your login limit at the highest practical value, taking the above things into consideration. So, if you've got a max of 64 file descriptors, and you don't define SINGLE_LOGFILE, figure you can have 54 players connected, and set login_limit accordingly. Remember, however, that your admin and players with the login @power can connect even over your login_limit, and if they run out your file descriptors, expect bad things to happen. Wizard commands in detail Most of the Wizard commands are covered in the Wizard's supplement to Amberyl's MUSH Manual, but I though I'd mention a few that deserve special notice. @attribute In PennMUSH, changes made by the @attribute command are not preserved when the MUSH is shut down. If you always want to, say, have a mortal_dark, wizard-only STATS attribute, have God's @startup include the appropriate @attribute/access command. @command In addition to its ability to disable commands, @command can also show you all the switches that a command recognizes and other interesting info about the way it's parsed. @comment The COMMENT attrib can't be seen by mortals, so using @comment to set comments on suspicious players is a common thing to do. To maximize usefulness, consider a policy whereby whenever a player is set suspect, they must be commented, and comments must include the name of the commenting Wizard. If you let any admin set SUSPECT, consider a +suspect player=comment command which sets the flag and the comment at the same time. @disable/@enable The options which you can enable and disable are: logins (when disabled, only admin/login-@power can log in), daytime (when enabled, cpu-intensive commands can't be used), command_log (when enabled, all commands are logged), force_log (when enabled, all @forces are logged), huh_log (when enabled, all commands resulting in Huh? are logged), wall_log (when enabled, all @walls and @wizwalls are logged). @fixdb This very dangerous command allows you to directly set the contents, location, exits, and next elements of a database object. No error-checking is performed, so be sure you know what you're doing. To learn more about these elements, read the source code and play around with the examine/debug command which displays values from a db object's structure which are not normally accessible in raw form. @kick As the help says, @kick causes the immediate execution of a specified number of commands from the queue. The real question is when to use it. It can help if your queue is clogged with a non-infinite loop, like a large @dolist. But what often happens is that while the game is busy executing the @kicked commands, commands from connected players are building up, resulting in a large queue clog even after the @kick. I use it as a last resort, and rarely when many players are connected. @log This works just like the help says it does, and is really handy if you want to keep track of things (like when players die by your combat system or use certain commands). The alternative, logging such things to some db object, has all sorts of problems as the log gets bigger and bigger. If you use @log, classify everything you log with some unique KEYWORD so you can get it from your logs with a simple grep. I used to have an object which would @log the number of connected players and admin, and how many were IC, every 30 minutes, and I'd make histograms out of the data in the log. :) @pcreate This is how you create characters for people from sites on registration status. @readcache Don't forget to run this command if you change the cached .txt files and want to update them (or, you can kill -HUP the MUSH process from the account it runs under). @sitelock site-pattern[= options] Adds the site-pattern directly to the access.cnf file with the specified options. Wizards can use this to lock out sites. Later uses of @sitelock override earlier ones. @squota You can @squota player=+number or -number, to adjust their quota up or down from its current level. @uptime On some operating systems, this command's functionality is limited. On others, the command works, but seriously lags the MUSH while it's working. Test it once and see. @toad I'm a fan of disabling this. Wizards shouldn't nuke players, they should boot and newpassword (and maybe sitelock), all of which are reversible. Only God should nuke players, and God should be secure enough to do it with the simple @nuke, not the flashy @toad (which leaves a slimy toad you often nuke anyway). Rhyanna@Castle D'Image notes, however, that @toad can be a convenient way for RP MUSHes to make corpses after IC deaths. MUSH crashes Ok, your MUSH crashed. It happens. The good news is that if you compiled with debugging enabled (-g), you can usually figure out *where* in the code it crashed and *why*. Even if you personally can't correct the problem, such information is exactly what you'd want to post/mail if you were asking for help. In order to get debugging information, your MUSH crash must have produced a core dump, which is a file called 'core' in your game directory. This file is usually quite large. On some systems, you must be sure that your MUSH restart script does an 'unlimit coredumpsize' or you won't get complete core files. You also need a debugger. Most systems have one of the following debugging programs: gdb (ideal), dbx (a good second choice), sdb (ick), adb (very ick). You (or your sysadmin) can ftp the source code for gdb from the GNU ftp site. Using the gdb or dbx debugger gdb and dbx are similar, so in the following examples I'll use them interchangably. If you'll be needing a copy of your debugging session to mail out, use the unix 'script' command to log everything ('script buglog', do your debugger stuff, then 'exit'). To run the debugger, go into your MUSH game directory and type: gdb netmush core The debugger will tell you how the process died, and what function it was executing at the time. Getting and using a stack trace That alone can be useful, but far more useful is a stack trace, which shows not only the function it was executing that caused it to crash, but which function called that fatal function (and with what parameters), which function called that, and so forth, back up to the very top function, main(). The command 'where' will print out a stack trace. The commands 'up' and 'down' will walk you up and down through the stack, showing the values of parameters that are being passed. You can also use the 'p' (print) command to print the values of other variables in each function. Running the MUSH under gdb If the crash occurs during the MUSH startup process (when analyzing or loading the db, for example), and doesn't leave a core dump, you have another option if you have gdb. You can actually run the MUSH from within the gdb debugger by going to the game directory and doing: gdb netmush run mush.cnf (According to Rhyanna, on some operating systems, typing 'handle SIGPIPE nostop' before running the mud will prevent the debugger from reporting SIGPIPE signals when players connect.) When the MUSH crashes, you'll be told how and where, and be returned to gdb to analyze the crash. Gdb and dbx can do much more - you can tell them to run the MUSH until they hit a certain function and then wait for further instructions, step through code one line at a time, etc. Read the manual pages if you need to do these things. Trashed stacks Some crashes, alas, overwrite the memory containing the function stack, and produce a totally unhelpful core file. The only help I've found for this is to cross my fingers and run the MUSH again, hoping that the next crash will pick a different memory location to overwrite. In some cases, 'touch'ing all the MUSH source files (touch *.c) and recompiling can help, as can using 'make clean; make', but it's mostly superstition. Lagging One of the most pernicious problems common to MUSHes is lag, the condition in which the MUSH feels slow in responding to player input. There are a number of things which contribute to lag, and once you identify the culprit, you can decide if you can improve the situation. Network lag Network lag is caused by difficulties in the network connection between the player and the MUSH host machine. For example, a router on the internet between the two might be dropping packets, or a segment of the network might be overloaded with packets. The characteristic property of netlag is that you won't experience it if you're connecting to the MUSH from the MUSH machine itself. If you can get a lagless connection by doing a 'telnet localhost ', netlag is responsible. If your host has the ping command (most do), you can test how long it takes a packet to travel between your host and another machine, and try to identify how slow things are going to be. If you happen to have the traceroute command, you can see exactly where (between which routers) the network is lagged. Unless you happen to be a network administrator of the problem stretch of network (or if it's just the local connection to your machine), there's not much you can do. If the problem is your particular net connection, you can probably spend more money and get one with a higher bandwidth, or reduce other things your machine does that requires the net (email, etc.), but neither of these are really worth it for a MUSH, usually. :( DNS and IDENT lag Another network-related source of lag involves domain name service lookups. When a player connects to the MUSH, the MUSH knows the player's IP address, and queries the DNS to get the player's hostname. This is called a "reverse hostname lookup". Some hosts, however, have very slow nameservers. Sometimes this is because the nameservers are behind slow internet connections with heavy traffic. The MUSH stops while a reverse hostname lookup is going on, so if it takes more than a second, you will feel lag. If you've got your MUSH configured to use IDENT lookups, the same kind of problem applies. In addition, IDENT lookups of non-unix systems can hang until the lookup times out. There are a few ways you might deal with this problem: * #define INFO_SLAVE in options.h. This creates a separate process that handles lookups, so your MUSH won't have to. This doesn't work well on win32 systems. * Turn off ident or reduce the ident_timeout value in mush.cnf * If you don't need hostnames, set use_dns to "no" in mush.cnf and no reverse hostname lookups will be performed. * If there are particular sites that are causing you trouble, and if you have access to your system's hosts file (/etc/hosts on most Unix systems), you could try making an entry for the troublesome system in the hosts file. Many DNS setups will check the hosts file before asking the nameserver. CPU lag CPU lag is caused when the MUSH machine is having to split its time doing many tasks or tasks which require a lot of running time spent in the CPU. If your MUSH is on a machine which has a lot of users, this is more likely. If the users are programmers who run things like compilers regularly, this becomes much more likely. You can examine the CPU load in a few ways. The uptime command will display an interesting, if non-objective statistic called "load average", measured over the last minute, 5 minutes, and 15 minutes. If you know what typical load average looks like, you'll be able to recognize abnormally high load. Loads over 3, especially in the 5/15 minute entries, tend to make for a slow game. But what's causing the load? Here you can use ps -aux (BSD) or ps -elf (SysV) to see all the running processes and how much CPU time they're getting at that moment. This static picture can be deceiving, but is a good start. Read the man page for details. If you're responsible for the load due to your own compiling and such (or if you need to decrease the CPU load your MUSH puts on the machine), read the man page for the nice and renice commands, which let you tell the system that your compilation (or MUSH process) should be nice about using CPU, and the CPU should give it lower priority. Disk swapping Unix systems have a limited amount of memory in which to run their programs. Memory is also expensive. So unix systems use a part of the disk as "virtual memory" or "swap space". Processes send parts of their memory that haven't been accessed in a while off to virtual memory, a process called paging. Paging helps make all the programs work together gracefully. MUSHes can be pretty big programs, though, and sometimes another program (some compilers and editors, as well as statistical software and other such things, for example) has to be granted more memory than can be recovered even with paging. In these situations, the whole MUSH process may be "swapped out" to the disk, temporarily put on hold until it can be swapped back into memory. While the MUSH is swapped out, the game is frozen, and if it stays swapped long enough and often enough, you experience lag. Dealing with swapping and paging is beyond the scope of this guide. Read the man pages for ps, vmstat, pstat, and iostat, or pick up a book on Unix System Administration or Performance Tuning (say, the O'Reilly Handbooks, which are great) if you're the system administrator of your MUSH machine. If not, purge unused objects from your database and hope. Queue lag Queue lag occurs when the MUSH's queue becomes clogged, and the MUSH can no longer keep up with servicing the queue and player input. Players get priority, so keyboard response will be good, but if they try to use $commands, which go on the object queue, they won't get response for some time. @kick can be used as a temporary fix for this, though see the concerns above in the section on Wizcommands. A more permanent solution might be to adjust the values of queue_chunk and (especially) active_queue_chunk in the mush.cnf file. This will make keyboard response slighly worse, but will usually fix the queue clogging. Security Security on a MUSH (which many feel is an oxymoron already) addresses the needs of the game to provide four or five crucial factors: Stable service Players should be able to play the game - it should be up reliably. Database control Players should not be able to modify objects belonging to other players. Privacy Private player information (email addresses, sites, private conversations) should be inaccessible by unprivileged players. Freedom from harassment Players should be free of harassment from other players (gross spamming, for example.) A fair game Players should not be able to use MUSH knowledge to cheat in any game run on the MUSH, particularly if the game is the point of the MUSH. Unwelcome players can generally be broken down into two major categories: crackers, who threaten stable service and database control, and twinks, who threaten privacy, freedom from harassment, and game fairness. A cracker seeks to destroy the integrity of the game by making it unusable. A twink seeks to destroy the integrity of the game by making it unenjoyable or unfair. A cracker philosophy Some people who try to compromise MUSH security claim that they're doing you a service, by showing you where you MUSH needs shoring up. As Amberyl once put it, this is akin to someone breaking into your house (unasked, of course) to show you that your locks should be repaired. These folks not only put your game and database at risk, not only might become privy to sensitive information (player email addresses, etc), but destroy the trust which generally exists within the internet and MUSH community. It's no service. Unfortunately, the crackers usually win, because they have a lot of time to spend trying to compromise your security, while you and your Wizards have more to do than just continually improve it. The goal here, therefore, is to emphasis some easy measures that you can take to deal with attacks on your MUSH. A twink philosophy While the goal in dealing with crackers is to keep them away from your MUSH or minimize the damage they can do, twinks come in many flavors and require individual response. Many twinks are misguided newbies who, once set straight, become valuable players. Others merely seek to disrupt the game, creating dozens of characters and paging regular players with annoying messages. As Gilbert and Sullivan put it, with twinks it's often best to "let the punishment fit the crime." SUSPECTs The suspect flag makes an excellent first line of defense against suspected problem players. In addition to allowing you to tell when a SUSPECT player connects, disconnects, or changes their name, all actions by SUSPECT players are logged in the MUSH's command.log file, so you can decide if they really pose a threat. There's a script by Talek in the Appendix which I've used to process command.log and create individual suspect files, one per player (by db#), which can be read or searched for keywords like "hack" or whatnot. By the way, I think it's good policy for every MUSH to place a statement in news ('news policy' perhaps) noting that while every attempt is made to preserve privacy, you reserve the right to log commands executed in order to maintain MUSH security and/or to fix bugs. Registration and lockout Site registration, and site lockout, are strong measures which can be very effective in preventing twink invasions. The key to site-based access control is the access.cnf file. You can control the following aspects of access: * Whether or not a site can connect to guests * Whether or not a site can connect to non-guest characters * Whether or not a site can create characters at the login screen * Whether or not a site can use the "register" command at the login screen, to request that a character be created and its password be emailed to the player. * Whether or not a site is suspect. Players who connect from suspect sites are automatically set SUSPECT. * Which of the above your Wizards can override using @sitelock, and which are set in stone. access.cnf (in the game directory) is a list of sites and their access control options. When someone connects, the file is read through in order, and the first line which matches their site is used to determine their access options. Order of the file is thus critical. A line in the file looks like this: [