Next Previous Contents

1. Server Related

1.1 What is a MOO?

MOO stands for MUD, Object Oriented. The Programmer's Manual introduction describes the LambdaMOO server, which is the most commonly used program to run MOOs. The MUD FAQ has a definition of MUD.

1.2 Who invented MOO?

Stephen White (ghond) wrote the first MOO server. Pavel Curtis took the basic design, language, and code, fixed bugs and added features to release the first LambdaMOO version. He maintained the server for several years. Erik Ostrom maintained the server for several years. The server is now maintained by Ben Jackson and Jay Carlson and has a LambdaMOO SourceForge project.

1.3 What are the minimum requirements for running a MOO?

The LambdaCore database is approximately 2 megabytes in size. The source and executable for MOO will likely occupy another 1-2 Megs. In its current state, MOO resides entirely in resident memory when running. The process size is going to be roughly 2-3 times the size of the database file on disk. Your mileage will vary from system to system.

1.4 Location of LambdaMOO server source.

The current LambdaMOO server source is at

The file LambdaMOO-X.Y.Z.tar.{Z,gz} (for a current server version of X.Y.Z) is a compressed tar file containing the complete source code, installation instructions, and a copy of the `Minimal' LambdaMOO database.

MOO has been compiled and run successfully on several different operating systems including AIX, BSD UNIX, SunOS 4.x, Linux, Sys V R4, Ultrix, OSF, FreeBSD, Solaris, and NeXT. Major MOOs are currently running on almost all of them.

In addition to the server, you will need a core database. A core database provides functionality augmenting that of the server. Every MOO needs to start from some kind of core database.

1.5 Location of core databases.

For a long time, the only core database available was LambdaCore. LambdaCore is still what most people use.

Core databases available:


The original. Retrieve it from To contact the maintainers, send mail to *core-db-issues (if you have a character) or *wizard-list (as a guest) on LambdaMOO 8888.


A LambdaCore based db that adds significant enhancements. It features a hypertext help system, administration groups, MCP fancy client support, enhanced English presentation tools, and lots of other features. See the JHCore home page for more information about the enhancements and to download it.


enCore is "a constructivist virtual reality environment designed for educational use". More information about it and a place to get it is at the High Wired enCore home page.

1.6 Non-UNIX MOO ports.

There are some non-UNIX ports of MOO, including ports to MacOS and Win32 (Win95/WinNT). See the resources section for the latest list.

1.7 What kind of security risk is running a MOO server?

(Most of the facts for the below answer come from thread on MOO-Cows about this subject. Most of the text, too. Thanks to Jay Carlson ( and Ian Macintosh (

Disclaimer: Everything said here is an identification of a risk I am aware of. I am not a security expert. There may be other risks or the risks I mention below may be of other forms. As with any other answer in this FAQ, I welcome submissions on this subject.

One of the first things to keep in mind with computer security is ``what are we trying to protect from whom?''. The threat that the unmodified MOO server poses to the server machine is limited to denial of service attacks. A MOO programmer could use all the memory, CPU, or disk on the partition that MOO is dumping to. The server itself provides no access to the filesystem (though there are patches that do) or other operating system services.

If you have OUTBOUND_NETWORK turned on, there are a few threats to machines on your local net if they use some sort of ill-configured IP-address-based trust mechanism. Only sites that rely on the dubious security of address-based trust will need to worry about this. Your network admins will know if they have such an assumption built into your network, and can remedy this by taking your server machine out of the trust list. Now that MOO can speak binary data, the number of services you could potentially attack through it has increased. I still do not think it is a problem unless you use address-based authentication for things.

If you have OUTBOUND_NETWORK turned on, your machine could be a threat to the Internet as a whole by laundering connections---an attacker connects to your server, and then connects through it to the machine they're really after, to make tracing their connections more difficult. The chance of this is vanishingly small; there are far more convenient anonymous sites out there that are perfectly able to launder connections for the cracker community.

By running any sort of visible and popular network service, you become more of a target for conventional cracking attacks. This risk is not exclusive to MOO; hosting a popular web page will make it more attractive for people to attack you. Depending on your level of visibility, you may want to tighten up general security on your machine or site.

Some organizations have other concerns. A MOO server may allow organizational mapping, or accidental disclosure of proprietary information, or whatever. If you're a company that has issues like this, you already understand these things or have people at your site that do. Go talk to them. Feel free to ask them how the MOO server is more dangerous than existing communications mechanisms such as electronic mail or the telephone.

1.8 I am having problems with my passwords on FreeBSD. What is wrong?

Modern versions of FreeBSD use a modified version of the UNIX crypt() function to encrypt player passwords in the MOO database.  This interferes with assumptions made by MOO and by MOO databases when determining the 'salt' component of an encrypted password.

A long-term solution requires modifications to the server and to the database, but there is a short cut available while we await changes to the server itself.

Systems affected:


When you start up MOO with a fresh database you can connect as Wizard without needing a password.  It's possible to use @make-player to create new players but you can't then connect as the new player.  This is because MOO is is uncorrectly decoding the stored encrypted password when testing the password offered by the new connection.

What's happening:

The crypt() function needs a special sequece of characters called 'salt' in order to correctly decrypt an encrypted password.  The salt used to encrypt a password is stored as part of the encrypted password.

On an uneffected system you can type the following eval:

  => "FdaYZdZMmz1fo"

The 'salt' in this encrypted password is in the first 2 characters 'Fd'.

On a FreeBSD system the same command returns the following value:

 => "$1$Fd$ka83QFBdh28db22oi3if8"

The 'salt' in this encrypted password is in positions 4..5.


You need to make sure that the correct salt string is passed to calls you make to crypt.

You'll need to change some of the existing database which controls setting and testing passwords, by extracting the correct substring from an encrypted password.

At least two verbs need to be changed:


 elseif (player.password != crypt(tostr(args[1]), player.password))
 elseif (player.password != crypt(tostr(args[1]), player.password[4..5]))


 ... crypt({@args, ""}[2], candidate.password[1..2]) ...
 ... crypt({@args, ""}[2], candidate.password[4..5]) ...

Redefining bf_crypt to do the right thing and changing all calls to crypt to pass the complete encrypted password as the 2nd parameter is also a good solution.

Andrew Wilson (

1.9 When is the next release due out?

It is unpredictable when each new version of the server will be released. The latest version of the server is 1.8.1. It is available from the SourceForge site (see below).

1.10 Is diskbased MOO going to be part of the next release?

No. No diskbased version of MOO is planned.

(The following from a post to MOO-Cows from Roger Crew (

Since most machines these days use virtual memory and disk I/O caches, the line between "running off the disk" and "running entirely in RAM" is rather severely blurred. It is the fundamental nature of virtual memory that, once you request more memory than you physically have, you are, to some extent, running off the disk whether you like it or (more likely) not. Conversely, a program that "runs entirely off the disk" may yet be running mostly in memory if its pattern of disk accesses is suffiently I/O-cache-friendly (i.e., not trying to touch so much of the disk at once that it blows out the cache).

The real issues as I see them are:

(1) performance

That is, what performance win is to be had by having the server take more explicit control over the disk

One would think that since the server has some concept of how often various objects/slots are used, it could implement its own swapping with somewhat more intelligence.

Then again, given how generic the MOO language is and how much work has gone in over the years into OS paging algorithms and the fact that the OS-level stuff has a fair amount of hardware support, even having a server that will do as good a swapping job as the OS would have done will be something of a challenge. It may be that the effort would be better spent restructuring the memory layout of MOO code/data so as to be more paging-friendly, thus working with what the OS has already provided rather than trying to reinvent/duplicate it.

(2) how best to achieve persistence

The ideal here is that the state of the world should be continually saved in as low-overhead a manner as possible and that restoring this state (i.e., when your server crashes) should go as quickly as possible.

I think there's a fairly strong consensus that forking every n hours to do a disk dump is not really the best way to do a checkpoint. I also suspect that this, fast incremental checkpointing and fast restore/startup, is really what people are concerned about when they say they want a "disk-based" server. The actual implementation that achieves this is immaterial.

1.11 Why won't my MOO send email with new character's passwords?

Using outbound mail requires that the moo be able to open up network connections. This is a compile time option in the options.h file. There is a line that looks like this:

  /* #define OUTBOUND_NETWORK */

/* and */ are C comment markers so define is commented out. If the MOO server is compiled without OUTBOUND_NETWORK being defined, then calls to open_network_connection() will fail with E_PERM. Since outbound mail depends on open_network_connection(), outbound mail doesn't work without OUTBOUND_NETWORK.

To enable outbound network connections, recompile the MOO server after editing options.h so it includes the line:


See also help open_network_connection() in LambdaCore for more information on open_network_connection and the README file in the MOO distribution for more info on compiling the MOO. It is a good idea to look over options.h as there are several important options set there.

Andy Bakun (

1.12 How does the MOO pass arguments to builtin functions?

The argument list is represented in the same way as all MOO values; in this case, it is a MOO list containing all of the arguments passed to the built-in function by the MOO programmer. First, I'll describe MOO value representation in general; after that I'll get back to built-in function argument lists in particular.

MOO values are represented by C structures of type `Var'. There are two members of such a structure, the `type' and the value, `v'. The `type' member is one of TYPE_NUM, TYPE_OBJ, TYPE_ERR, TYPE_STR, or TYPE_LIST.

This type corresponds exactly to the MOO programmer's idea of the standard five MOO data types. The particular `type' value used in each instance determines the form of the `v' or value member of the structure; `v' is a union of a number of different representations, one for each type.

If x.type == TYPE_NUM, then x represents a MOO number, the value of which is found in x.v.num (a C integer). The TYPE_OBJ and TYPE_ERR cases are handled similarly, representing MOO object numbers and error codes; their respective values are found in x.v.obj (a C integer) and x.v.err (an element of the C enumeration type `enum error').

If x.type == TYPE_STR, then x represents a MOO string, the characters of which are found in x.v.str (a C `const char *' value). NOTE the use of `const' here. You should never modify a MOO string value, since all MOO values are immutable and you can't easily tell if maybe some other part of the MOO is also holding onto a pointer to that string. Instead, use `str_dup()' to make a copy of the string and modify that instead.

If x.type == TYPE_LIST, then x represents a MOO list value, the most complicated case; the value part of x is found in x.v.list (a C `Var *' value, a pointer to an array of Var structures). The first (zeroth) element of x.v.list always has type TYPE_NUM (i.e., x.v.list[0].type == TYPE_NUM); its value (i.e., x.v.list[0].v.num) is the length of the list (and also one less than the length of the x.v.list array). The rest of the elements of the list are in the succeeding elements of the x.v.list array, in the same order as in the MOO list. For example, if x represented the MOO list value {17, #3}, then all of the following would be true:

        x.type == TYPE_LIST             /* x represents a list */
        x.v.list[0].type == TYPE_NUM    /* the zeroth elt is the list length */
        x.v.list[0].v.num == 2
        x.v.list[1].type == TYPE_NUM    /* the first elt of the MOO list: 17 */
        x.v.list[1].v.num == 17
        x.v.list[2].type == TYPE_OBJ    /* the second elt of the list: #3 */
        x.v.list[2].v.obj == 3

Brand new list values are *always* allocated using the C function `new_list()'. The other kinds are always created manually, using a local C variable of type Var and filling in the members one by one. Even for lists, only the actual allocation and setting up of the length field are done by `new_list()'; filling in the elements is done manually.

A new reference to any existing MOO value can be created with `var_ref()' and a top-level copy can be made with `var_dup()'; an existing reference can be discarded by calling `free_var()'.

Getting back to built-in function argument lists now, they are simply normal MOO lists, containing just exactly the arguments passed by the MOO programmer.

Pavel Curtis (

1.13 Why does MOO compilation fail on Linux with an ``undefined reference to sqrt''?

Because it can't find sqrt.

You need to edit the MOO Makefile so you link with -lm. Add -lm to the LIBRARIES line in the Makefile.

1.14 How does the MOO pick a verb to run when someone types a command?

See the LambdaMOO Programmer's Manual: The Built-in Command Parser.

Next Previous Contents