Introduction ------------ TeenyMUD is a disk-based clone of the TinyMUD server. It is completely new code, and is not based on the original TinyMUD code at all. It is NOT written in ANSI C. What follows is somewhat technical, but I frankly think you really need to read and understand all of it to run TeenyMUD with any degree of success. Bringing the server up ---------------------- First you have to make the thing. There is a Makefile supplied, typing 'make teeny' at the shell prompt should do it. In order to bring the server up coherently, you need to understand vaguely how the server works, so here we go: The database is stored in two files, an index file and a chunks file. We'll get to the index file shortly. The chunks file is where most of the data lives, scattered about more or less at random in the file. When data is required, it is read in from this file and 'cached' in memory, subsequent accesses to the same data can use the cached data and avoid referencing the disk. The cache size is limited, however, so when too much data is read in, the least recently referenced data is tossed out of the cache, and written back to the chunks file if it has been changed since it was read (or is data for a completely new object). Subsequent references to that data will then, of course, force the data to be read back in from the chunks file. The index file is used to store data about where in the chunks file the data for any particular object can be found. In general, this data is read in when the server is brought up, and kept in memory permanently. Along with this data is stored the flags and name of each object in the database -- these are referenced rather frequently, and so are stored with the permanently-in-memory data. Incidentally, back of the envelope computations suggest that the permanent memory usage of each object will be about 50 to 60 bytes, roughly one fifth of what a TinyMUD uses per object. This does not include the cached data, of course. The upshot of all this is that the index file on disk holds the locations of everything in the chunks file at server startup time. Since things are constantly being read from, and written back to the chunks file (at possibly different places), the index file rapidly becomes wildly inaccurate. The correct data is, of course, always available in memory. Furthermore, the data in the chunk file is not completely up to date, since a recently changed object may well be in the cache and not written back to the chunks file. Thus, the server does periodic dumps to write everything back to the chunks file, and rewrite the index file to correctly reference all this data -- i.e. 'bring the db into synch'. The server then immediately copies the index file to 'old.index' and the chunks file to 'old.chunks'. If the server crashes, the active index and chunk files are rubbish, but the 'old.index' and 'old.chunk' form, as a pair, a database correct and complete up to the last dump. Suitable use of the cp command should let you bring the server back up as of the most recent dump. The server accepts several command line flags: -l specifies that an existing database (index/chunkfile pair) is to used. This flag cannot be used with the -t or -s flags. -s specifies that a small initial database -- Limbo and Wizard -- should be built and used. -t <text database> loads a text dump database, instead of an indexfile/chunkfile pair. See below for more on this type of database. This flag cannot be used with the -l or -s flags. NOTE: You MUST use exactly one of the -l, -s, -t flags to tell the server where to get its database. The following flags are optional. -C n specifies that a cache of size n kilobytes is to be used. -c <name> specifies the name to use for the chunkfile (defaults to chunky.bits if this flag is absent). -i <name> specifies the name to use for the index file (defaults to chunky.index if this flag is absent). -P <port> specifies the port number to run the server on (defaults to 4201, or whatever is specified in includes/config.h) Typically, you will first start the server with the -s flag, to force it to build an initial database into chunky.bits and chunky.index. Then you may shut the server down, and use the supplied startserver script to bring it back up with a log file named 'logfile' and load this database. The text dump and load facilities are useful for portability and de-fragmenting your database. Attempting to move an existing index file/ chunks file pair to a new machine is probably a bad idea, and bad things may well result. To move to a new machine, use the @textdump command to create a text dump, move the text dump file to the new hardware, and load it into the server with the -t flag on the command line. Doing an immediate dump (or shutdown) will create an index file/chunks file pair that can be used on the new machine. In addition, each time a dump occurs, fragmentation data is written to the log file (i.e. on standard error). This consists of 4 numbers, each counting the number of free chunks (holes) in your chunkfile in a certain range of sizes. The first number is the number of free chunks of size zero or less, and should *always* be a zero. The second is the number of non-empty free chunks too small to be used for anything, the next is the number of chunks of useful size less than 512 bytes, and the last number is the number of free chunks of size greater than 512 bytes. All these numbers should be 'small', whatever that means. If they indicate that an unsatisfactory percentage of your chunkfile is taken up by unusably small chunks, your database is said to be 'fragmented'. To de-fragment, you can bring the server up, do a text dump (@textdump), shut the server down, and immediately restart with the -t flag to re-load the text dump. This simply rebuilds a new copy of the old database, but does so in a 'sequential' fashion, which leaves no holes in the chunks file. If you dump immediately, you should get Fragmentation data of '0 0 0 0'. Configuring the server ---------------------- The configuration file for TeenyMUD 1.2 is includes/config.h, and this file contains many #defines that may be changed to suite one's taste. TIME_SLICE and SLICE_QUOTA are probably fine as distributed. These two define, roughly, how spammable your MUD is. Each player is allowed SLICE_QUOTA commands in each TIME_SLICE interval. DUMP_INTERVAL is, of course, the frequency at which to dump the database as described above (NOT text dump -- this can only be done with the @textdump command). Other defines that are probably ok as distributed are the SLACK and GROWTH_INCREMENT constants defined in includes/db.h. You may want to tweak these in, say, a fast growing MUD. SLACK is the amount of free space added to the index above and beyond the number of objects currently in the database. If this is greater than the number of objects created between the time the server is started, and the time it is shut down, then the index will never have to be re-sized. This is good, because re-sizing the index tends to waste memory. The GROWTH_INCREMENT constant is the number of index entries to be added to the index in the even that it should become necessary to re-size it. Lastly, you will need to select a cache size for your game -- this is slightly tricky and depends on several factors. I see two reasonable approaches to this problem: a) determine how much real memory you will typically have to run the server with, and tune the cache so that the virtual memory size is roughly equal to this. You should NEVER run the server with a cache so large that the virtual size is routinely greater than the real size -- if the operating system starts to page your cache in and out of its own paging/swapping files, performance will drop sharply. See your local man page on ps, and ask around if you don't understand all this. b) determine how many players will be active during fairly busy periods, and make the cache large enough to hold the data associated with them, and any 'social' rooms that will usually have players in them. Roughly, multiply the number of players plus the number of rooms by, say, 2K and double that for a fudge factor. This will allow the commonly referenced things to be usually in cache, and you will just have to accept that exploring players, will cause a fair amount of disk activity. The first option will give you a the maximum size cache you should be using, the second will be the minimum. Note that you should periodically re-tune your cache, since as your database grows, the amount of permanently resident data (the flags and names) will grow. If you have your cache tuned with a small database to approximately fill available real memory, when the database grows so will your process size, your server will start to page and performance will drop. Also, keep an eye on the load your machine is under, and re-tune appropriately. As I have not run any benchmarks, the above remarks on cache tuning are merely educated guesses on my part. Cache tuning is well known to be a black art. The Wiz Password ---------------- Ok, you made it this far, so I'll tell you what how to log in as the Wiz in the minimal db you get at the beginning. The name is 'Wizard', the password is 'foo'. CHANGE THIS PASSWORD. Wizard privilages work much the same way as in TinyMUD. Flags ----- Some flags in TeenyMUD work differently than in TinyMUD. Here are detailed descriptions of each. Internal flags are marked with an asterisk. L LINK_OK Means you can link to this object. On rooms, you can link exits to that room. On things and players, it doesn't mean much. J JUMP_OK Controls the teleport rules. On rooms, you can teleport out of and into this room. On things, you can teleport that object, if it's in a legal room and the destination is also legal. On players, it means you can teleport that player, with the legal requirements as per things. W WIZARD On players, grants them extra commands and abilites. On rooms, exits, things, it doesn't mean much. This flag may only be set or unset by a wizard. T TEMPLE/TEMPORAL On rooms, it sends objects home. (Obsolete, as a dropto linked to -3 should do the same). On players, makes them immune to time-slicing cutoffs. Also typically marks the player as a robot. Allows the player to spew out buckets of commands and spam the server. On exits, it disallows players marked T. Except for exits, this flag may only be set or unset by a wizard. B BUILDER On rooms, you can open exits there. On players, it means they can build. On other things, it doesn't mean much. This flag may only be set on players by a wizard. D DARK On rooms, the contents list doesn't appear. On players, their actions are not shown, and they are invisible. On things, it doesn't appear in a contents list, also invisible. Except for rooms, only a wizard may set or unset this flag. A ABODE On rooms, you can set your home there, and set objects home's there too. On other things, people can examine the objects, if this is allowed in config.h. H HAVEN On rooms, no killing is allowed. On exits, players marked H may not pass. On players, they may not kill. M MUCKER There is no such thing as a mucker bit. S STICKY On players, they are immune to pages. On rooms, objects don't flush down the drop-to till everyone leaves. On objects, they go home when dropped. X X_OK On players, it allows the server to send X datagrams. On rooms, hey, wait a minute! That's TeenyMud 2.0. Nevermind.... * FREE_CHUNK Denotes that this points to an available chunk in the database file. * IN_MEMORY Denotes that this object is currently available "in memory", i.e. is loaded into the cache. * DIRTY Denotes that this object has been modified in the cache, and must be updated on disk. * ALIVE Marks a logged in player. NOTE: Some flag information may change depending on which #defines you have in your config.h file. The Future ---------- We're going to let TeenyMud 1.2 play around for a while, and gather in all the bug reports. Then work will commence on 1.3, which will feature odd things like oarrive and oleave, lastsite, and a couple other toys. And maybe someone will dream up a real penny system, or simply "score", which will differentiate players.