/
umud/DOC/
umud/DOC/examples/
umud/DOC/internals/
umud/DOC/wizard/
umud/MISC/
umud/MISC/dbchk/
umud/RWHO/rwhod/
How to be an UnterMUD Wizard:
-----------------------------

	First off, things you will need:

	a) about a meg of disk space, bare minimum. if you plan to build
		anything complex, plan to have a few megs of storage for
		backup copies of objects and databases.
	b) a C compiler. UnterMUD is written in K&R C.
	c) some knowledge of how C works, since the MUD is capable of
		being tailored to your environment, and because of
		environmental differences, it may require it.

	UnterMUD is designed to require a minimum amount of resources
to run, but running a MUD is never something to be undertaken lightly.
There are useful facilities for storing and archiving objects in Unter
and those should be understood before you try to run a MUD. It is far
easier to recover a trashed database from backup, than by hand.


Building the server:
--------------------
	(See also the 'howtostart' file.)

	Edit the file "config.h", which contains all the various
software switches that UnterMUD can be compiled with. Comments around
each option describe its relevance. In most cases you should be able to
fairly easily understand what is going on. If not, you'll have to
figure it out, since it's really pretty basic stuff. Some options
and system environments may require modifications to the Makefiles
in the umud directory, or the DB directory.

	Type "make" and it should build a program called "mud". If it does
not compile, save a transcript of the error, in case you can't figure it,
and mail it to someone who maintains UnterMUD. Make a sincere try at
figuring it out, or you'll be likely to get told to get a clue.

	There is a macro in the Makefile called FLAGS that gets passed
in with the compiler flags in the main directory and the subdirectory.
this can be used to pass compiler flags without having to edit Makefiles.
on any decent UNIX, you should be able to type:

	make "FLAGS=-O"

and it'll do that compile thang. This is useful if you need to recompile
the MUD with profiling or debugging information.


Building your initial database:
-------------------------------
	Initially, there is no database provided with the MUD, since
there is no way of knowing what kind of database system you will be
running with. You need to build a database from scratch. This is
done using the utilities in umud/DB, namely loaddb and dumpdb, and
the minimal_db.oif file, which contains a very very small raw database.

	The first step is to make a decision as to what directory
the MUD will run out of. This is set with the

#set working directory someplace safe (looks for NEWS and HELP here)
_mudconfig chdir "/some/directory/or/other"

	option in the configfile. Inside that directory, can be two
subdirectories, named "HELP" and "NEWS", if you wish to have helpfiles
or news postings stored. The HELP directory is searched for files by
the "help" command, and the "NEWS" command stores news articles
in NEWS. Other files that are looked for in news are NEWS/welcome.txt,
which is automatically sent to a player when they connect to the MUD,
if it exists, and NEWS/connect.txt, which is automatically sent to a 
player when they first connect (before they log in), if the file exists.

	In the top-level directory of the distribution is a directory
called "HELP" which contains help files. Moving that directory to the
database directory will give a reasonable starting set of help files.
Or you can just leave it where it is, and make the NEWS directory
there. Either way, be sure you set the working directory correctly
with the _mudconfig chdir command.

	Once the directory is set up, create your initial database
from scratch, using one of the following techniques, depending on
the database layer you wish to use.

	Hashed directory databases:
	---------------------------
		First off, you must make the hash directories - ensuring
	that you have as many as are defined as the hash size you plan
	to use. IE: if the hash size is 15, you need to have 15 separate
	directories (all in the same parent directory) named: 0, 1, 2, 3
	and so forth, up to 14. Remember that you must *ALWAYS* use the
	same hash size, or the database will become corrupt. (unless
	you copy it out and back in again).

		Knowing the directory in which the hash directories
	reside, load the database, using loaddb:

loaddb -v -h -i minimal_db.oif -f /hash/directory/path

	and you should see the objects being copied in. If you used other
	then the default hash size, provide a parameter with the -b flag,
	indicating the value, EG:

loaddb -v -h -b 23 -i minimal_db.oif -f /hash/directory/path

		To make a backup of the entire database, use dumpdb to
	copy the objects back out in OIF format:

dumpdb -h -f /hash/directory/path | compress -v > backup.oif.Z


	Dbm/ndbm chunk databases:
	-------------------------
		Dbm/ndbm chunk databases are stored in a packed file of
	logical blocks, with a throw-away in-memory bitmap for managing
	storage allocation. This approach results in only 3 files for the
	MUD database, rather than the many produced by hashed directories.
	Access and update times are considerably faster, but it is harder
	to edit the database manually, or archive individual objects.

		Knowing where you want to store the database files, use
	loaddb to load the initial database:

loaddb -v -d -f /database/file/base/name -i minimal_db.oif

	and three files will be created: filename.db, filename.dir, and
	filename.pag. The filename.db contains chunks of the objects,
	stored in ascii, with garbage between them (the file is a binary
	file, do NOT EVER try to edit it with vi!) The filename.dir and
	filename.pag files are a dbm database of object name/size/offset
	values. Do not ever try to modify any of these files manually.

		Dbm/ndbm based databases use a logical block structure
	which defaults automatically to a "reasonable" value. You can
	modify this or select another block size, and if you do so,
	make sure you ALWAYS use the same block size. The use of
	different blocksizes is discouraged, but for some large databases
	with a lot of disk space to waste, using a larger block size
	will result in performance improvements, at a cost in space.
	If you do not understand these issues, do not change the block
	size.

		To make a backup of the dbm chunk database, use dumpdb
	to copy objects back out into OIF format:

dumpdb -d -f /database/file/name | compress -v > backup.oif.Z


	Gdbm chunk databases:
	---------------------
		If you have gdbm on your machine, you can use a gdbm
	database, which takes advantage of gdbm's ability to store
	large records, and stores the entire object in the database.
	Load the database with loaddb:

loaddb -v -g -f /database/file/base/name -i minimal_db.oif

		The gdbm and dbm databases are not interchangable.


	A word about loaddb/dumpdb:
	---------------------------
		There are additional options to loaddb and dumpdb to
	specify expressions to match objects against, input, output,
	and so forth, which are left to the wizard to discover.
	Roughly, the options are as follows:

	flag:		meaning:
	-----		--------
	[one of these MUST be defined]
	-d		(flag) Database is a dbm chunk database.
	-g		(flag) Database is a gdbm chunk database.
	-h		(flag) Database is a hashed directory database.
	-x		Extract to standard output (loaddb only). This permits
				loaddb to be used as a filter.

	-c expression	Apply given expression as a selection criterion for
				all objects in the database or input.
	-l		List objects only, do not extract them in OIF.
				This is useful when testing selection criteria.
	-v		Verbosity.
	-b #		Block/hash size. (If relevant to db-layer)
	-i filename	Input filename.
	-o filename	Output filename.
	-f filename	Database filename.
	-C [i|o]	Compression on input or output, if compression is
				compiled into your MUD. IE, to decompress
				a database, use:

loaddb -i olddb.compressed.oif -x -C i -o newdb.uncompressed.oif

				to compress a database, use:

loaddb -i olddb.uncompressed.oif -x -C o -o newdb.compressed.oif

		Boolean expressions for the selection criteria are similar
	in syntax to locks, with the exception of the following constructs:

	attribute = value		- Look for named attribute with the
					exact value given (EG: _own = 23@HELL)
	type.attribute = value		- Look for named atttribute of the
					provided type, with the exact value
					given (EG: cmd.fail = @do BONK)
	attribute = [regexp]		- As above, but do a regular
					expression pattern match on the
					attribute. (EG: desc = [.*fuzzy.*])

Compressed Databases:
---------------------
	If your database is having problems with size, you may need to
consider compressing the database, which can save in the area of 25% of
the size of the chunk file. This will entail some additional administrative
burden, since your MUD server will ONLY read and write compressed OIF
databases, and you will need to rely on external code (like loaddb) to
handle compression and decompression of backups. Compressed databases
will also take up less space for backups, if that is an issue. Be aware
of the fact that compressed databases will be a lot more of a chore to
manipulate and edit. See DB/comp.c for a simple compress/uncompress
routine.


Booting the server:
-------------------
	There are two critical files used to initialize the server.
The first is the "config" file, which performs configuration that
is needed BEFORE the MUD is initialized. Typically, this is going
to consist of fairly simple stuff like setting the database name
or hash/blocksize, or changing directories, etc. The second file is
the "startup" file, which contains startup commands that are run
after the databases have been initialized and the MUD is ready
to run. At the point where the startup file is being run, any
arbitrary UnterMUD commands can be executed, including setting
attributes, etc. These commands execute as the object named "wizard".
With the distribution kit there are samples of the two startup
files "config" and "startup" in the DB directory. You may wish
to copy them and tailor them to your site.

	There are a variety of options available at boot time
that you may wish to have set. Most of these will have to do with the
directory the MUD should run in, etc. Some of these options will depend
on the type of database routines you are running the MUD with, since
different database layers accept different options.

	The server recognizes the two startup files with the "-c"
and "-s" options. The "-c" option defines the configuration file
name, and the "-s" defines the startup. Note that the configuration
file is not strictly necessary, if you start your server in the
database directory, with the default database names and all default
values.


Logging into the server:
------------------------
	In the minimal_db.oif there is one player object in the db and one
room. To connect to the game you must telnet/tinytalk/whatever to
the player port, then type "c wizard" - which will log you in to the
wizard object. At this point, you can start creating players with the
"build player" command, and away you go.



Maintenance Events:
-------------------
	Some events need to be run every so often, such as syncing dirty
objects from the cache, or updating RWHO information. This is done by
entering commands in the cron table, to run as the wizard. The sample
startup file has some examples of this admittedly roundabout (but very
extensible!) way of doing things. For example:

_cronconfig defevent 300 "@_cachconfig sync" wizard
_cronconfig defevent 400 "@_mudconfig rwhoupdate" wizard

	The first entry set a cron trigger to do a "@_cacheconfig sync"
as the wizard every 5 minutes. The second will cause an RWHO update about
every 400 seconds. UnterMUD's cron service is DELIBERATELY not tailored
to provide extreme accuracy in submitting cron jobs, since the more you
demand in precision, the more time you waste examining the cron table. 

	There are "backup" modes defined in the database layers, for
online backups. The format of the backup command is:

_mudconfig backup "/backup/file/path"

	where the backup file pathname is the OIF output from the backup,
with a sequence number appended to the file name. The backup sequence
number is stored in the system object, for uniqueness. There's an optional
modulus parameter that can be passed, and the sequence number is calculated
modulo the given number. Therefore:

_mudconfig backup "/backup/file/path" 5

	means that the MUD will cycle through its backups, producing files
named backup.0 backup.1... backup.4, to prevent effectively limitless disk
usage. The backup operation has some subtle distinctions from dumpdb and
loaddb, namely that the output is copied in raw mode - no error checking
on the format of objects is attempted. Backup of a damaged database will
not attempt any form of recovery. This is actually useful, since at the
very least an attempt to copy each object out will be made. The intent of
the backup command is to place it where it is called by cron:

# bi-hourly backups
_cronconfig defevent 7200 "@_mudconfig backup backupfile 5" wizard

	To preserve database integrity, backups are performed in one
shot, by syncing the cache and writing the backup file. If your database
is large, the backup will take some fraction more time to perform than
would copying the database file. Performing frequent backups is probably
pointless, since the database is pretty crash resistant to begin with.


Talking RWHO:
-------------
	UnterMUD is designed to pass datagrams to an RWHO server, that
in turns keeps an idea of who is logged in in the various MUDs out there.
In order to pass RWHO datagrams to the server, you must first arrange
with the keeper of the nearest (or most reliable) RWHO server to get a
password and MUD entry, so that your RWHO packets will be accepted. This
should not be a Big Deal to arrange. Since the RWHO packets sent from
your MUD to the server are UDP packets written asynchronously, running
RWHO doesn't cost a jot, performance-wise.

	To configure RWHO, you need a few lines in your server's startup
file:

_mudconfig rwhoserver server.host.name serverpassword
_cronconfig defevent 301 "@_mudconfig rwhoupdate" wizard

	Where the first line defines your RWHO server's IP name, and the
password you want to use when communicating with it. This command MUST
be issued after your MUD's name is set, since the RWHO server expects
the MUD name to be passed to it. The second line runs out of cron, and
propagates the RWHO information every so often. Note that this is only
a "group" propagation, and does NOT need to be run very often - it only
needs to be run a little more often than the time period that the RWHO
server bases information expiration on. You'll be given that by the
owner of the RWHO server in question.


Setting up InterMUD links:
--------------------------
	First off, you have to realize the implications of what you are
doing. When you set up an link to another MUD, that means that people
with player objects on that MUD can wander into yours and have a look
about. If you don't like that idea, don't do it. It also means that your
players can wander into the other MUD as well, and from there onto other
MUDs, so you have to be courteous. If you think you've got players who
are clueless newbies, make sure that they realize that they're being
unleashed on the UnterVerse as a whole, and that in other MUDs they
may get fried quickly if they annoy someone.

	The first step is to locate a MUD that will let you link to it.
This might take a while, because the other MUD's owner might be polite
enough to check with the people (s)he shares links with before allowing
a new MUD into their group. Once you've reached an accord, you should
exchange a pair of passwords, and the player and server port #s, as well
as MUD-names, host names and addresses of the MUDs. Then make an entry
in your startup script to define the remote MUD locally:

#config defmud mudname IP-addr IP-host locpass rempass srvport playport [timo]
_mudconfig defmud SomeMUD 6.66.66.6 host.site.dom mypass theirpass 6566 6565 8

	They need to make a similar entry for you as well, for their MUD
to recognize yours as legitimate. "mypass" is the password I will send to
the remote MUD to prove it's me, and "theirpass" is the password they
will send me to prove it's them. These are actually passed encrypted, so
don't bother dumping them. The "SomeMUD" is the NAME of the MUD, and MUST
match exactly what the other MUD calls itself (since the name is used as
the seed for the encryption). The IP octets and host addresses should be
pretty straight forward. The "srvport" value (6566 in the example) is
the IP port # their server accepts server-to-server connections on, and
the "playport" value (6565 in the example) is the port number they accept
players on. The last value is an optional transaction timeout value, and
can be set to something high if you have a terrible network connection.
Be careful with the timeout (seconds) because that value is *also* how
long your MUD server will hang, while trying to talk to the remote MUD.

	After you have the mud entries defined, the next step is to make
exits. Courtesy implies you should ask the wizard of the remote MUD if
there is a particular place he thinks you should make an exit to, rather
than just slamming an exit down and having people wander through it. As
the wizard on your MUD, you can create exits to remote MUDs without having
to check to see if the remote room is link-ok, but don't abuse it. To
make an exit, though, is easy:

	build exit exitname 426@SomeMUD

	Where you know 426 is a room on SomeMUD. Then when people try to
walk through it, presto, off they go.

	If an ordinary player builds an exit to the remote MUD, your
server will contact the remote and request permission first. This is the
more civilized way of doing things.

	There is an option in the code known as the "known mud" option.
What this means is that you must define every mud that you wish to allow
a connection to your mud as a "known mud". This is not quite the same thing
as just making a link to that mud -- if you use this option you have to
define a mud both as a "known mud" and also exchange passwords if you want
the link to work. The "known mud" option is simply a way of regulating
who walks onto your mud. If you do not have a mud defined as a known mud,
no one from that mud can walk onto yours, regardless of if they have a 
direct link or they walked over via another mud. The syntax for this is:
	
	_mudconfig defknownmud mudname

	where 'mudname' is the exact name the other mud uses to identify
itself. If you decide to use this option, be sure to "defknownmud" every
mud you have a "defmud" entry for.

	Remember - your link to a remote MUD is a privilege and a courtesy.
Do not abuse it. UnterMUD literally makes MUDs a community, with all the
privileges, pleasures, and responsibilities that result.


System Macros:
--------------
	There are some system macros that come with the UnterMUD distribution.
You don't have to use them, of course, but here are explanations for them
anyway.

_mudconfig defmac male 'pronouns $1 he him his'
_mudconfig defmac female 'pronouns $1 she her her'
_mudconfig defmac neuter 'pronouns $1 it it its'
_mudconfig defmac many 'pronouns $1 they them their'
_mudconfig defmac pronouns 'set $1 subv $2;set $1 objv $3;set $1 posv $4'

	These all set a player's pronouns. $1 is the player to set (should be
"me" for non-wizards), $2 is the subjective pronoun (he, her, it), $3 is
the objective pronoun (him, her, it), and $4 is the possessive pronoun
(his, her, its). You can set these individually by using the set command,
but using the system macro is faster.

_mudconfig defmac sex '$2 $1'

	This does the same thing as the above macros, only slightly
different.  The syntax is "set me male" (or female or neuter or many).

_mudconfig defmac BONK =@do "BONKs $1"

	The old familiar. The = sign is used here so everything after it
will be passed as one string to the @do command, so the double quotes will
come out correctly.

_mudconfig defmac BOOT '_force $1 @QUIT'

	Wizard only. Forces the named player to quit the game.

_mudconfig defmac TOAD '_force $1 @QUIT;@unset $1 pass;@unset $1 _pl;\
	@set $1 name "a slimy toad named $1"'

	Wizard only. Forces the named player to quit, unsets their password
and player flag so they can no longer log in, and changes their name to
"a slimy toad named $1", where $1 is their old name. To untoad, the wizard
will have to rename the toad back correctly, add the player flag with
"@set player _pl", and give it a new password with "@_newpassword player
password" (where 'player' is the name of the untoaded player).

_mudconfig defmac pcreate '@build player $1 $2;@set $1 home 0;\
	@which $1;@teleport $1 home'

	Wizard only. This creates a player with the given name and password,
sets their home to #0 (limbo in most cases), tells the wizard what the new
player's object id is, and teleports the new player home, to limbo.