MOO-cows Mailing List Archive


LPMOO FAQ 9/17/95

Due to recent increased interest in LPMOO, I decided compiling a FAQ might
be a good idea.  So here it is :)
This is my first attempt at creating a FAQ, so if you have any suggestions
or additions, please feel free to send them to me.

Matt Pauker

                                          LPMOO FAQ
                                   Compiled by Matt Pauker
                                    Last updated 9/17/95


Q: What is LPMOO?

LPMOO is an implementation of MOO built on top of a server called DGD.  It
is completely compatible with LambdaMOO 1.7.8, although some differences do
exist (See LPMOO vs. LambdaMOO).

Q: What is DGD?

DGD, which stands for Dworkin's Generic Driver, is a portable, small,
efficient network server.  LPMOO runs on top of DGD.

Q: Where can I get LPMOO?

The most recent version of LPMOO, 1.2, is available at:

In addition to the LPMOO server, you will need a LambdaMOO-format DB.  If
you're starting fresh, you'll probably want:

That is a fresh copy of the Oct '94 LambdaCore, with the exception of
$spell, which is missing from the DB.  $spell was removed because it
significantly increases bootstrap time, and is not often used.  If you
really need spell, FTP it from

Q: Who wrote LPMOO?

LPMOO is written and supported by Robert Leslie (  You can
often find him on MirrorMOO ( 8889) as Verement.

LPMOO vs. LambdaMOO

Q: What are the differences between LPMOO and LambdaMOO?

>From the LPMOO docs:

Important differences between LambdaMOO 1.7.8 and LPMOO 1.2:

 - LPMOO supports three additional datatypes: floats, tables, and buffers.

 - Task execution limits are in DGD terms; no attempt is made to simulate
   tick or seconds counting. {ticks,seconds}_left() are approximate.

 - Background tasks receive equal "tick store" as foreground tasks.

 - fork (0) and suspend(0) are always translated into fork (1) and suspend(1).

 - clear_property() returns E_INVARG for all builtin properties.

 - ob.wizard = x will only affect future tasks, not any existing (suspended
   or forked) ones.

 - Suspended tasks are not saved across cold restarts (bootstrapping from
   a LambdaMOO-format DB file).

 - Suspended tasks _are_ saved across warm restarts (using a binary state
   dump), however their starting times will be relative to the time of the
   state dump.

 - open_network_connection() will suspend until the connection either
   succeeds or fails.

 - It is not illegal to use a string value for `obj' in obj:verb(@args); this
   is interpreted as a function call in the LPC object named by `obj'.

 - Strings and lists are not unlimited in size. Strings and lists are limited
   to approximately 64K characters and elements, respectively. Attempts to
   exceed these limits will result in a run-time traceback error.

 - The number of pending forked (or suspended) tasks is not unlimited. The
   limit is determined by the value of the `call_outs' setting in the
   configuration file. Attempts to exceed the limit will yield a traceback.

 - $server_options is not (yet) supported.

 - disassemble() is functional, but does not return any useful information.

 - The .program builtin verb is not functional.

 - Esoteric expressions such as:  a = {1, 2}; a[1] = (a = 0);  do not behave
   as they do in LambdaMOO. Expressions such as:  a[1] = a[2] = 3;  behave
   as you would expect. These are technically incorrect simulations of MOO,
   but are more intuitive and actually simpler to implement.

 - If $dump_interval is negative, automatic checkpoints are never made (under
   the assumption the db is handling them.)

Q: What are some advantages of LPMOO over LambdaMOO?

 - Disk-based operation.  Objects which have not been used recently are swapped
   out, and therefore do not use RAM.

 - Table, buffer, and floating point support.  (See below for descriptions of
   tables and buffers.)

 - Access to LPC, a low-level language.  LPC can be used to implement very
   efficient code that can be called from MOO.

 - Binary dump files allow for quick checkpoints.

 - Multi-port listening.

Q: What are some disadvantages of LPMOO as compared to LambdaMOO?

 - Binary dump files are much larger than text dump files.

 - With a small DB, LPMOO experiences a bit more lag than LambdaMOO, although it
   uses less RAM.  Larger DBs have not been tested.

New Datatypes

Q: How do I use floats?

Floats (Floating-point numbers) are used exactly like integers.  If you
want to have a float returned by an operator (e.g. +,-,*,/), one or both of
the numbers on which you are operating must be a float.  For more specific
information, see doc/floats in the LPMOO distribution.

Q: What are tables?

Tables are lists which can be indexed by any MOO value.  Tables are also
sometimes called associative arrays, mappings, or dictionaries in other
languages.  For more specific information, see doc/tables in the LPMOO

Q: How would I use tables?

Tables are useful for a wide variety of tasks.  Once you start using
tables, you'll see hundreds of possibilities for using them.  Also, they're
more efficient than using lists.
One of the best uses of tables is for the replacement of synchronized lists
- In other words, a group of properties which each contain lists, with each
element corresponding to every other element with that same index.  For
example, if I have:

#100.people == {"Bob", "Joe", "Ann", "Fred"}
#100.ages   == {25, 39, 19, 32}

(Where Bob's age is 25, Joe's age is 39, etc.)

I could replace that with a table:

#100.people == {"Bob" ~ 25, "Joe" ~ 39, "Ann" ~ 19, "Fred" ~ 32}

This table makes the ages much easier to access.  Rather than having to do:

age = #100.ages["Joe" in #100.people];

I can do:

age = #100.people["Joe"];

Not only is this easier to type, but it is much more intuitive.

Also, if you wanted to see if you could get Joe's age (i.e. "Joe' is in the
table), you would check:

if ("Joe" in #100.people)

This is very similar to the use of the 'in' operator in checking for an
element in a list; however, using the 'in' operator with a table only
returns 1 if the element exists in the table, and 0 if it doesn't (Since an
element in a table doesn't have a numerical index as a list element does.)

This is only one possible use of tables.  Experiment and you'll find many more.

Q: What are buffers?

Buffers are containers for arbitrary blocks of binary data - In other
words, a series of ASCII values.  For example, the word "Hello" could be
represented as:

[72, 101, 108, 108, 111]

For more specific information on buffers, see doc/buffers in the LPMOO

Q: How would I use buffers?

Buffers are most useful for sending ASCII control codes (Characters with
ASCII values < 32) to users.  The most common example is sending ANSI codes
to users to display color.  For example, to display the word "Hello" in
bold, you might send the following buffer (Using notify()) to the user:

[27, 91, 49, 109, 72, 101, 108, 108, 111]

Remember, though, that when you send a buffer to the user using notify(), a
newline is *not* appended.  Therefore, you would want to send this buffer
to the user like this:

notify(this, [27, 91, 49, 109, 72, 101, 108, 108, 111]);
notify(this, "");

The second notify() will send the newline to the user.

Multi-Port Listening (MPL)

Q: What is Multi-Port Listening and what does it do?

Multi-Port Listening allows your LPMOO to accept connections on multiple
ports.  By default, LPMOO listenings to two ports: A telnet port and a
binary port.

Q: How do I activate Multi-Port listening?

In etc/, set mport_listening to YES.  However, before you do this,
you must start up the server without Multi-Port listening, and set the last
three lines of #0:server_started to:

status = dgd_status();

That will make LPMOO listen to the telnet and binary ports (As specified in
etc/ when it starts up.

After adding those lines, shutdown the MOO, set mport_listening to YES, and
start it back up.

Q: How do I use Multi-Port listening to listen to an extra port?

To listen() to a port, you must have a verb called :do_login_command() that
will handle connections on that port.  So to listen to port 6789 and have
its input handled by #100:do_login_command, you would execute:


For most purposes, you will want the port to handle binary connections.  If
you don't specify a third argument, it is automatically assumed to handle
binary connections.  If you specify "telnet" as the third argument, the
port will only handle telnet connections.

Q: What are some uses of MPL?

MPL could be used for a variety of reasons, but probably the most common
function for which it would be useful is for creating a WWW interface for a
MOO.  Using MPL, you can specify a port that is solely used for WWW
accesses, and handle all input/output through one object.
Other possible uses might be setting up a gateway between two MOOs,
creating a gopher server, or making an interface for a specialized client.


Q: What is LPC?

LPC is a low-level language used by DGD.  It is very similar to C, although
some differences exist.  Explaining the specifics of LPC would be far
beyond the scope of this FAQ.  Unfortunately, there is no complete
documentation written for LPC.  The best way to learn is probably to take a
look at the LPC files distributed with LPMOO, in the mudlib/lpc/ directory.

Q: Why use LPC?

Writing code in LPC is more efficient than writing it in MOO, as the
LPC->MOO converter, like all converters, doesn't do as good a job as a
human.  Also, because LPC is a lower-level language than MOO (In the LPMOO
sense), it opens many more possibilities.

Q: How do I write LPC code to use in MOO?

Writing LPC code for use in MOO involves a number of steps.  You first need
to write the LPC code in a textfile (Which must have a name ending in .c),
and place that textfile in the mudlib/ directory.  Then, from MOO, type:

;"/lpc/utils":update(<DGD path to object>)

Where <DGD path to object> is the path to the textfile within the mudlib
directory, minus the ".c".  For example, if your file's path is
mudlib/lpc/test.c, then the DGD path to that object is "/lpc/test".

If you think this is complicated and a lot of work, you're right.
Fortunately, Rob Leslie has created a File Editor (A slightly modified
Generic Editor) which makes it very easy to create LPC code.  If you'd like
to get the File Editor, along with some other similar commands, go to
MirrorMOO ( 8889) and ask Verement to help you get them.

Once you've written the LPC code, you can call a function in that file as
if it were a verb.  For example, if you have a function called "hello" in
test.c, you would call it like this:


(Passing the appropriate arguments within the parenthesis.)


Problem: The server isn't responding to user commands quickly enough.

>From the LPMOO docs:

You can increase response time by reducing the number of objects being
swapped out every second. The `swap_fragment' option in the etc/
configuration file specifies what fraction of all objects to swap out. For
example, a value of 32 means that 1/32 of all objects are swapped out every

By making this value larger, you decrease the number of objects forced to
be swapped out each second, and therefore increase normal response time.
Good values to try would be 64 or 128. Note, however, that fewer objects
swapped out means the process will use more memory.

Problem: The server is using too much RAM.

>From the LPMOO docs:

You can change DGD to be more aggressive at swapping out unused objects to
disk, thereby reducing the overall process size. The `swap_fragment' option
in the etc/ configuration file specifies what fraction of all objects
to swap out each second. For example, a value of 32 means that 1/32 of all
objects are swapped out every second.

By making this value smaller, you force more objects to be swapped out each
second. Note, however, that the more time DGD spends swapping objects out
to disk (and later back in), the slower its perceived response time will

Problem: The server isn't accepting incoming connections.

>From the LPMOO docs:

If you've enabled the `mport_listening' option in, the server will
NOT automatically open and listen on any network ports. Your database is
expected to do this itself via the listen() builtin, typically from the
#0:server_started verb.

To use the mport_listening feature, first disable it and start the server.
Connect and modify #0:server_started as described in the documentation for
the listen() function. Shutdown, re-enable mport_listening, and restart.

Problem: Evaluating an expression that returns a table returns "{table}".

This occurs because $string_utils:print() doesn't know what a table is, so
it turns it into a string, using tostr(), which gives you "{table}".

The easy way to fix this is to set the first line of $string_utils:print() to:

return toliteral(args[1]);

The toliteral() builtin will return a string form of its argument that is
more readable.

These are some more common problems you may encounter with LPMOO.  Other,
more obscure problems are listed in doc/troubleshooting.  Also realize that
these are only LPMOO-specific problems - For general MOO problems, you
might want to check the MOO-Cows FAQ.

List of LPMOO's

MOO Name     Site                  Telnet   Binary   Comments

MirrorMOO    8889     9990     Home of LPMOO
HoloMOO       1701     6666     Star Trek Role-Playing

If you have any additions to this list, please send them to  Include your MOO's name, site, telnet & binary ports,
and a *short* comment.


The LPMOO FAQ is maintained by Matt Pauker (  If you
have any comments, questions, suggestions, or additions, please mail him.
This FAQ will be updated as changes warrant.
Matt Pauker makes no warranty as to the validity of this information.

Home | Subject Index | Thread Index