Maintaining the Database
Utility Objects - by Examples
In this section, we will use the following approach: BY EXAMPLE.
It's like physics: 200 words is nice to describe something, but a simple graph is much better. So we will summarize all Utility Objects, their verbs, what they do (information coming directly from the LambdaMOO database) and we will list several examples to show what can be done with it so that we have a better idea of what is going on and the potential of each verb.
The list of examples is not exhaustive. If you can think of some other that show and reveal deeper aspects, please contribute!!
help full-index (MOO commands).
Then you can narrow your search, by typing: help followed by either submenus (given to you by the help) or commands (given to you by help full-index).
You need 2 things:
- A server
- A database
Both of them can be found on this page, but you might want to check out the offical site (moo-cows). The server is called something like: LambdaMOO-X.X.X.tar.gz (where X correspond to the version number) while the database is usually named: LambdaCore.*.db.gz
If you download those packages in a compressed form (that is, they have a gz or Z at the end), you can download them as binary.
Everything that follows assumes that you are using a *nix flavor.
For the Database, use:
Make sure that you replace * by whatever you have on the file you downloaded.
For the server you have two options:
Once you uncompress your database, you will be left with a file called:
Once you uncompress and untar your server file, you will be left with a directory called:
This is where you will compile your server.
In other words: READ the README file.
everything is explained in details. All we will end up here is paraphrase it badly; and so we won't.
If someone has questions concerning parts of options.h, feel free to raise them up, and sections can be added on some aspects of the options.h parameters, their meaning, etc...
This is a good question to ask yourself BEFORE you compile the server...;)
This question is put here because adding prepositions requires a recompilation of the server.
If you would like to include prepositions in your own language or whatever, hack the file db_verbs.c by looking for static const char *prep_list somewhere near the second screen. Everything is explained there.
Please refer to the WINMOO documentation.
Some people have found a good alternative to use CYGWIN so they can stick to the *nix version of the MOO server (which is of course always nicer).
If anyone wants to share his/her cygwin experience, that would be great.
There exist many ways brothers and sisters...
The easiest way (at first) is through a telnet application.
A second way is to use a MOO client.
Please note that all the software listed below have not been
tested. If you use them, do it at your own risks.
A third way is through java applet (but most likely, you will not
use them to first connect to your MOO).
The first thing you should do is change your wizard password.
As you noticed, you did not need one the first time you have connected. If you do not change it, anyone can connect with this login name and this might cause trouble...
As a general rule for passwords, especially when it concerns wiz characters, choose one that is not a dictionnary word, and is at least eight characters long, using capital and characters such as !@#$%^&*() for instance. The security of your MOO depends a lot on the choice of your passwords.
Give a name to your MOO!
@set $network.MOO_name to "My_MOO"
Set the correct domain name or IP number from which your MOO is running from:
@set $network.site to "my_domain_name"
If you decided to use another port than 7777 (defined in your options.h file when compiling), it is a good idea to update the changes here as well.
@set $network.port to your_number
(do not use quotes for the above port setting).
It is a good time also to check:
Information will be useful, and contained in the following sections.
Edit the property $login.welcome_message:
@set $login.welcome_message to <your_message>
<your_message> must be a list:
If your message is quite long, and you feel that the above method is barbarian, use the note editor:
(Make sure you know how to use the @notedit! The first time I used it I got stuck in the editor for many hours...)
To create guests, use: @make-guest
As suggested in the help @make-guest, add the alias guest to your
first guest (or any other).
@add-alias guest to #95
The default is such that anyone can create a player from the login screen. The syntax being:
create <player_name> <password>
The problem with this option is that the property .email_address is left blank. I would suggest to turn off this option, and force guest players to either @request, or use any other system that you like and that you will set up on your MOO.
@set $login.create_enabled to 0
By turning this option off, the user will receive the content of $login.registration_string when attempting to create from the login screen. Hence, you might want to edit this string, indicating to the user the procedure you will choose to create an account:
@set $login.registration_enable to "whatever method is better, use it!"
It is possible to customize even more the $login.registration_enable message by setting $login.registration_address. This property will hold the email address to contact in order to get a player account (if you choose to use this option for player creation). Hence, edit it first:
@set $login.registration_address to "firstname.lastname@example.org"
And edit $login.registration_enable accordingly:
@set $login.registration_enable to "Please contact %e to obtain a player, or connect as guest and use @request (or else!)"
(%e will be replace by $login.registration_addrelogin.registration_address).
It is a good idea to define $login.registration_address anyway because this is the email that will be proposed by @request if problems occur during the process.
Now, @request is still an option for guests to ask for a player account.
This procedure will be using lots of properties on $network as well as the option of using a possible OUTBOUNDED feature.
Let's assume you did enable it (as many people usually do); if you did not, then there is nothing to worry about, and you are not concerned with what follows.
The first thing to turn ON is $network.active. By default, its value is 0. To turn it on, type:
@set $network.active to 1
At this point, the MOO will use the SMTP server of the machine at
which the server is running on. Hence, you have to make sure that the
user under which the MOO server is running is allowed to use this
@set $network.maildrop to "SMTP_server"
This property can contain either a domain name or an IP. However, you have to make sure that the SMTP relays emails coming from your machine. Nowdays, with all the business going on through emails, most of the SMTP servers do NOT relay by default.
It would now be a good idea to set up the emails used in case of
returning emails or other problems that might occur:
Now, that you can create players, you have to ask yourself how many of them will you accept at the same time? Do you want to set up a limit in the number of connections? The type of hardward you have (RAM) might dictate a limit.
The default limit is set to 99999. In other words, there is no limit. If you feel that you need one, edit:
To notify people who want to connect but will be booted due to this limit, edit:
Please note that wizard accounts are not subject to this limitation, and $login.lag_exemptions allow you to add non-wizard players to the list.
Several things you can check:
Have you taken out the /* and */ around
Have set $network.active correctly?
Have you checked that you have a running SMTP service on the server
your MOO is installed upon?
Upon compiling of the MOO server, there should be 2 executable files in the working directory:
They both can be used to launch the MOO database although moo is
really the executable and restart is just a script. I would strongly
suggest that you read the README that comes with the server package in
order to have a complete explanation of how those two executables can be
The port is optional, but I would suggest that you add it in anyway. If you do not provide it, the one in $network.port will be used (which is the one that you chose in your options.h before compilation). It is therefore obvious, that with this option, you can over ride the default port by putting a different port if the mood of it comes to you. If you do so, do not forget to modify #72.port accordingly upon connection, otherwise funny things might happen - I don't know...
./moo yourmoo.db yournewmoo.db
Same story here with the port.
Note, that when using ./restart you do NOT need the extention .db while you DO need it when using ./moo
Now, you surely would like to have a log file associated with it; to do so, add -l:
./moo -l logfile.log yourmoo.db yournewmoo.db port
-l can be used with ./moo and ./restart
It is STRONGLY suggested that you DO NOT use the same name for your
database when using ./moo!!!
Also note, that when you use ./restart the task is forked automatically and the task ID will be given to you as a present (eeeh..:). However, if you use ./moo your console will be stuck in there (yyyargh!). This is what you want if you are in emergency mode, usually (using -e), but most of the time we'd rather have our hands free after we launch the MOO server. To accomplish this add & to your command line.
./moo -l logfile.log yourmoo.db yournewmoo.db port &
Please see the following section about backing your database up for more information about checkpointing.
Please refer to the Programmer's manual on checkpointing for a complete description.
the main idea is the following:
Every so often, the MOO server will backup your database file and save it into another file.
If you used ./restart the new file will have the same name as your original database with an extension called .new added to it (same for the log file).
If you used ./moo the new file will be dumped into the one you
provided; in the case of the previous section, it was yournewmoo.db
How "every so often" does a dump occurs?
You can do it manually at any time (from wiz bit), type:
When you @shutdown the server, it's being done automatically.
The dump occurs at every 3600 seconds (meaning every hour) by default; but you can change this value, which is stored in #0.dump_interval
Note, that the process of dumping is being forked by default, which is a good thing if you have a large database (you can change this though in your options.h file).
There is also a nice little feature that you can enable in your options.h file called
/* #define LOG_COMMANDS */
If you uncomment it, it will log everything that is being typed since the last checkpoint. When a new checkpoint occurs and is being completed, this part of the log vanishes. this might be useful if your server crashes for unknown reasons.
Now, if you are a backup neurotic (which is a good thing....;) you can also use cron to automate more backups. Just make sure that the user you are running under is allowed to run crontab (some firewalls can restrict it to root)
A detail has been ommited in the documentation of the FUP package, which will cause an error during compilation of the MOO server. In case the FUP.README file has not been updated, here is the fix:
Edit the file version.h and add the following line:
Another version of FUP is now available (v 1.9). It allows
fileinsert() and filecut() options and can be found here.
One can find a MAC version of the server from the Fringe's MOO Resources
site if dealing with MAC OS 8 or 9.
Every time a player is created, the PCL (Player-Creation-Log) is updated, and will notify the wizard at connection.
Similarly, Site-Locks is updated every time a player is "@toaded" and works the same way as PCL to notify the wizard.
If you choose to restrict player creation to only wizards, then you might want to start a database on a spreadsheet to keep track of how many players exist. How to maintain the player database is really up you.
In any case, you can also use:
This command returns a list of all players in the database (or rather their objects); using this, it is easy to write several lines of codes to display this information in a more human-like way.
To get statistics on players's connections, use:
You can use the command:
This will give you the last connected time of every player in the database. This can be a long list...
There exist routines that people have written to check automatically the above, and if people have not connected for a certain amount of time, an email is sent to remind the user that the account is still valid. If no response is obtained, the account is either deleted automatically or the maintainer of the MOO is notified, and free to take action.
If anyone has written such codes and wants to put them available here, be welcome to do so.
It is recommanded that you create wizard characters from scratch, as existing programmers might have verbs that could create problems.
First, create a new player, make it programmer, then turn it into a wizard:
@make-player <player_name> for <email_address>
At this point, the server will assign an object number to your <player_name>. Let's consider that we are given the object number: #1234.
Do not send wizard passwords via email... and reset it to a new one as soon as the first connection is made.
Use the command:
If you use @chparent, New-Pr_name>
If you use @chparent, New-Prog-Log will not be updated, neither wizards, nor the player who has just been targeted as a programmer...
Of course, you can also revoke one's prog bit, by using:
When a player's parent has been switched to $programmer, a default quota of 7 is assigned. This means that the programmer can create up to 7 objects. This is saved as the last argument of the property size_quota saved on the player object.
Please note that this number of 7 does not include the player itself.
If the need starts to be felt and/or justified, you can increase the quota of the programmer, by using:
@quota <player_name> new_number
Your choice of increasing quota really depends on how big you want to restrict your database, which in turns depends on the amount of RAM on your system (one of the parameters influencing the lag).
Please note, that there is a limit on unmeasured objects. This limit is 10. Hence, it is possible that even if your quota limit is not met you will run into the above limit (10). To fix it, use the @measure command.
@measure new me
You can always look up:
for more information.
Use the command:
@new-password <player_name> is new_password
The new_password you just assigned will be sent to the player's .email_address after your confirmation. If you do not allow your MOO to send regular email, you will have to find other means to transmit the password to the concerned player. In any case, it is wise to choose a temporary password that the user can change after connection using:
@password <old_password> <new_password>
Again, as always with passwords, make it as long as possible (8 characters for UNIX based system - any character after the 8th will not be considered by the MOO server), include capital letters, one or several of those !@#$%^&* beasts and numbers. Anything that will increase the time to password cracks to operate, the better. Avoid also dictionary words; those can be cracked too easily...
* First, create the object:
@create $mail_recipient named <mailing-list's name>
* Then, move it inside the $mail_agent object:
It's ready to go. Now, you really have to decide what is it that you want to do with it: make it public, restricted, moderated, etc.... Depending on your needs, configure the object according to your liking.
The room where a player will connect is usually defined using @sethome and stored on the property called home (#obj_number.home). However, one can overide this setting for ALL players and guests if @sethome has not been used yet. In order to achieve this, use:
@set #0.player_start to #whatever
Where #whatever is the #object_number of the room you specified.
This is a bit of a problem, but hopefully there is a way out.
When this happens the server should tell you which verb has a problem. For the following discussion, let's assume #1234:verb is the one that creates the problem.
First thing, backup your database (cp moo.db moo-backp.db or something).
Then, launch the database in emergency mode (using -e). When you do this, do NOT use ./restart, nor use ./moo with & because you still want to be in control while it's loading.
./moo -e yourdb.db yournewdb.db yourport
You will see something like the following:
LambdaMOO Emergency Holographic Wizard Mode
** Now running emergency commands as #2 ...
Now, you are in command. You can type help to see what tools are available to you. This is what I suggest:
Retrieve the verb that creates the problem, copy and paste it into another application and save it, so that you still have the codes available somewhere.
Then, delete the verb. Let's pray that even though the problem is not resolved yet, you will be able to load the database completely.
We just reprogrammed the verb to an empty body. You can check by typing: list #1234:verb that the verb is cleared out.
Now, let's finish loading the bugger...
Hopefully now, the database is loaded completely; you can connect to it using your favorite MOO client, and troubleshoot the problem, having at hand the codes of #1234:verb.
I would suggest that as soon as you connect to your MOO, @dump-database, @shutdown and restart it with the new database (yournewdb.db) as regular. Now, you have work to do...;)
Another alternative is to use your favorite text editor, make sure
that wrap is not ON and edit by hand the .db file to fix the problem.
First, you have to shutdown the database with @shutdown.
Then, BACKUP your database.
Now, let's attempt to recover the password.
continue Now, you should be able to log in with: co wizard mynewpassword I would suggested that you @shutdown your server again, right away, and restart the MOO with the dumped database, juse to ease the mind.
When you modify a property, respect its type!
So, if it is a STRING, make sure you still have a STRING when you finished editing it. If you are dealing with a LIST, leave the property in a LIST format when your changes are over.
Properties are read by verbs that usually expect a particular type. According to it, it will process the property in a specific way. Altering the type might cause problems...
When changing owner permissions, it is encouraged to use @grant (or @chown), rather than using @set. Doing this will make sure that all properties and verbs of a @granted object have the correct permission.
To lock any object, the @lock command is appropriate for this purpose.
Let's look at the case where we want to lock a room with not only ourselves, but also with other players as well.
@lock here with me || you || him || her || Poirot
In some case, it might work better to use object numbers instead of names. So if the room number is #1234, I am #111, you are #222, he is #333 and she is #444, we'll have:
@lock #1234 with #111 || #222 || #333 || #444
A more complete description of this command is given by typing:
The brute force method to check the guts of an object is to use: (assuming #1234 is the target object)
The first one will give you all properties, and the second one will include the verbs as well.
I might be time when you just want a cheap and dirty way of accomplishing the same thing. In this case, @d is more appropriate. Here is how it goes:
Imagine you would like to re-use object number #1234, which corresponds to anobejct that has been recycled some time ago (or 2 seconds ago, woops..)
request #1234 from $recycler
You might need to replace $recycler by its actual object number in some cases.
There is actually another way:
@create parent_object named whatever with=#1234
where you will replace parent_object with the parent that you would like your object to have and whatever by the name you chose for it.
This will tell you that there is no existing object number higher than the one displayed upon this command.
Courtesy of Alexandre Borgia There are a lot of ways to add "text-based" help entries.
1) The "general-purpose" (ie: not related to a specific object) way to do it is to add a property to the $help object, which name will be the help topic.
The user will then get the help message whenever he types "help moo policy".
2) If you want the user to get help for a specific object, you can simply create & edit an "help_msg" property on the object.
3) For commands/actions/functions/etc, the comments (quoted text) put
above the first line of code are considered to be the help-message of
"Type: drive car to
... they will be printed to the user when he types: help car:drive
Note that for (1) and (2) you can also use a VERB instead of a property.
For those who may have bumped into random problems (as one of my
player did), I propose the following fix to regexpr.c.
REPLACE the following (near line 150):
Note that I didn't thoroughly tested this, and in no way I can
state this is a safe / stable replacment, but as for now it seems to work great
for me (with french accented-characters). Any suggestions or comments
about this would be appreciated:)
... they will be printed to the user when he types: help car:drive
Note that for (1) and (2) you can also use a VERB instead of a property.
For those who may have bumped into random problems (as one of my player did), I propose the following fix to regexpr.c.
REPLACE the following (near line 150):
Note that I didn't thoroughly tested this, and in no way I can state this is a safe / stable replacment, but as for now it seems to work great for me (with french accented-characters). Any suggestions or comments about this would be appreciated:)
This page has been viewed
Maintained by hErVe.
Last update: January 16, 2007.