Faq-o-matic javelin Sun, 2012-02-12 21:58

This collaborative book contains the content that used to be housed in the PennMUSH Faq-o-Matic. Of course, like the Faq-o-Matic, you should extend the book by adding comments and replies!


  1. The code and answers in the Faq-o-Matic are pretty old (like 2000-2006, mostly), and many of the solutions/workarounds have been superseded by improved features in PennMUSH! Someone should update each page to modern best practice.
  2. The cpo drupal site seems to be escaping all ' and \ characters (maybe there\'s some kind of anti-XSS filter running in drupal or apache?) So a lot of regex-related code that might use \ is probably wrong. Someone should clean this up, either by ditching the filter or manually replacing all the quotes with ' and the backslashes with \

General commands

General commands javelin Mon, 2012-02-13 20:08

Questions about mush commands that usually aren't used much in softcode (@mail, @channel, look, etc.)

@channel recall explained

@channel recall explained javelin Mon, 2012-02-13 20:09

You can use @channel/recall channel=N to return the last N stored messages sent over the channel. However, you can't recall any lines unless the channel has been configured to actually store stuff. This is done with @channel/buffer channel=X, where X is the maximum number of 8k blocks to use to store lines. Within this space, as many lines as possible are stored, so that if there's a lot of short messages on the channel, you'll have a history going further back than when there's lots of long messages. @channel/what displays the amount of memory used in the recall buffer, and how many actual lines are being held at the moment.

2003-Jun-29 8:27pm shawnw

@mail number=message doesn't work right?

@mail number=message doesn't work right? javelin Mon, 2012-02-13 20:09

@mail number=message doesn't work right?

As help @mail explains, @mailing to a number sends the @mail to the author of the Nth message in your mailbox, and not to a player with a name or alias of the number. If both their name and alias are numbers, you can use their dbref, or *number.

2001-Sep-23 2:04pm shawnw

Penn-Specific things you can do for Myrddin's BBS

Penn-Specific things you can do for Myrddin's BBS javelin Mon, 2012-02-13 20:10

Myrddin's BBS assigns each post in it a unique id, which is stored as a base-36 number instead of the normal base 10. This is done because the ids of all posts someone has read are stored in an attribute on the player, and numbers in base 36 take fewer characters than base 10, so more can fit into the attribute before hitting the buffer limit.
In Penn 1.7.7p23, the baseconv() function was added for converting numbers between different bases. To use that function instead of the entirely softcoded conversion routines that come with the BBS, do the following:
Inside the Global BBS object should be an object named bbpocket. It has two attributes you need to change. The first, FN_B36-TO-B10, should be set to 'baseconv(%0, 36, 10)'. The second, FN_B10-TO-B36, should be set to 'ucstr(baseconv(%0, 10, 36))'. That's it.

2004-Jan-16 1:14pm shawnw


Hardcode javelin Mon, 2012-02-13 19:43

Herein find answers to frequently asked questions about hacking the PennMUSH hardcode.

1.7.7 + Redhat 9 - krb5.h not found

1.7.7 + Redhat 9 - krb5.h not found javelin Mon, 2012-02-13 19:50

When compiling PennMUSH 1.7.7 with RH9, you may get errors that begin with:

In file included from /usr/include/openssl/ssl.h:179,
                 from ../hdrs/mushtype.h:10,
                 from ../hdrs/conf.h:13,
                 from access.c:74:
/usr/include/openssl/kssl.h:72:18: krb5.h: No such file or directory

In RH9, RedHat built OpenSSL to use Kerberos, and put the Kerberos include
files in /usr/kerberos/include.

To fix this problem, you need to add -I/usr/kerberos/include to the CCFLAGS in the top-level Makefile. You can do it every time the Makefile is generated by Configure, you can tell Configure about it every time you run Configure, or you can try creating the file 'config.over' in the pennmush/ directory, containing the following line:


2003-Aug-18 9:53am dunemush

Adding a new lock type

Adding a new lock type javelin Mon, 2012-02-13 19:51

Adding a new lock type

In lock.c, you will see something like this:

const lock_type Basic_Lock = "Basic";     /**< Name of basic lock */
const lock_type Enter_Lock = "Enter";     /**< Name of enter lock */
const lock_type Use_Lock = "Use";         /**< Name of use lock */

You will also see:

const lock_list lock_types[] = {

And in lock.h you will see:

extern const lock_type Basic_Lock;
extern const lock_type Enter_Lock;
extern const lock_type Use_Lock;

Just add your lock to these three places in the same fashion.
Of course, your lock will have no effect unless you add code to handle it.

How Do I Report a Bug or Suggest a New Feature to Penn?

How Do I Report a Bug or Suggest a New Feature to Penn? MrWigggles Fri, 2012-05-11 15:14

If you think you've found a bug or want to suggest a new feature to Penn, then you'll want to go the Google Code for Pennmush.


From there, you'll want to clink on the Issues tab, where you'll be brought to a list of the current open ticket for PennMush. You'll notice a mix of bug reports and new features.

Then you'll want to click on the New Issue button, and select on the pull down menu, Feature Request or Bug Report and fill out the form.

How can I hide a attribute?

How can I hide a attribute? javelin Mon, 2012-02-13 19:49

How can I hide a attribute?

I am a wizard on a mush. I have set up in the hard code to add a few attributes to the player on player creation. That is working fine but I do not know what flags to use to hide the attribute so mortal players can not see the attributes that I have set. Thank you for any help that you can give me.

2002-Dec-31 6:05pm ctempleton3

The mortal_dark attribute flag. It's AF_MDARK in the hardcode. If you're using atr_add() to set the attributes without adding the attribute to the main table in hdrs/atr_tab.h, it should be the last argument to atr_add(), instead of NOTHING.
It's usually easier, btw, to do this sort of thing in softcode. I usually have an @aconnect in player_start (Set wizard, of course, so it can modify players) to set up initial attributes.

2003-Jan-12 1:58am shawnw

How do I apply a patch?

How do I apply a patch? javelin Mon, 2012-02-13 19:46

How do I apply a patch?

The instructions for PennMUSH patches are at the top of each file, but here's a summary.

From a unix shell prompt in the pennmush directory (Represented by the %):
% patch -p1 < 1.7.4-patch06
% make

The name of the patch file will vary, of course. If anything else needs to be done, like re-running Configure, make will tell you. After make recompiles the mush, do a @shutdown/reboot from in the mush. Some patches require a full @shutdown -- if so, the instructions in the patch file will mention this.

2001-Jun-11 7:58pm shawnw

How do I change @sex into a wizard only command?

How do I change @sex into a wizard only command? javelin Mon, 2012-02-13 19:54

How do I change @sex into a wizard only command?

I don't want players to be able to change their sex once they get out of character generation. I figure the best way to do this is make it a wizard only command, create a wizard object in character generation and create commands on it that set gender (i.e. &command_male gender=@male:@sex *%#=Male). But how do I turn @sex into a wizard only command?

@sex isn't actually a command, it's an attribute. See help @attribute for how to make it a 'wizard' attribute, which will prevent mortals from setting or changing it.

2012-02-13 javelin

I'm getting compile errors in command.c about case values or a parse error before '.'

I'm getting compile errors in command.c about case values or a parse error before '.' javelin Mon, 2012-02-13 19:47

I'm getting compile errors in command.c about case values or a parse error before '.'

You probably have the chat system turned on in options.h. You probably have the CHAT_ALIAS_TOKEN option defined. You probably didn't read the explanation about this option that's right above it in the file or when running a make update.
To reiterate what it says: CHAT_ALIAS_TOKEN, if defined, should be set to a single character within single quotes. That character should not be +. '.' is good. '=' is good. . is bad. = is bad. '+' is bad.

2001-Jul-19 12:50am shawnw

What do I have to do after changing something in options.h?

What do I have to do after changing something in options.h? javelin Mon, 2012-02-13 19:44

What do I have to do after changing something in options.h?

Recompile the mush (By running 'make' in the pennmush directory), and then do a @shutdown/reboot from inside the mush.

2001-Mar-28 10:51am shawnw

What files should I put custom hardcoded functions and commands in?

What files should I put custom hardcoded functions and commands in? javelin Mon, 2012-02-13 19:46

What files should I put custom hardcoded functions and commands in?

Normally, any custom hardcoded functions you add should go in src/funlocal.c, and new commands in src/cmdlocal.c. These two files are not altered by new patch levels, which greatly reduces the chance of a conflict when upgrading patchlevels.
There are a few exceptions, of course, for cases when you need to have access to information that's not normally available outside of specific files. See the Guide for Gods for more information on this.

2001-Jun-11 8:02pm shawnw

Where can I get the latest PennMUSH version?

Where can I get the latest PennMUSH version? javelin Mon, 2012-02-13 19:45

Where can I get the latest PennMUSH version?

See the 'Download PennMUSH' link at the top right of this site (http://community.pennmush.org)

ansi color in connect.txt

ansi color in connect.txt javelin Mon, 2012-02-13 19:52

Note: Since after 1.8.3 or so, ANSI and ACCENTS were enabled by default. The suggested method is now to use a message object instead of straight textfiles. That allows you to simply use [ansi()] softcode etc.

// Considerations //
1) This worked on 181p9 - I don't know if it will work on older versions
2) If someone connects to your mush with a client which can't grok ansi codes, your connect.txt will look like regurgitated potato salad.
// HOW TO //
1) in pennmush/src note notify.c around line 690:

  if (!d->connected) {
    /* These are the settings used at, e.g., the connect screen,
     * when there's no connected player yet. If you want to use
     * ansified connect screens, you'd probably change NA_NPASCII
     * to NA_NCOLOR (for no accents) or NA_COLOR (for accents).
     * We don't recommend it. If you want to use accented characters,
     * respectively. That's not so bad.
    return (d->conn_flags & CONN_HTML) ? NA_NPUEBLO : NA_NPASCII;

2) Not so bad, huh?

2006-Jul-28 2:40pm bill

MUSH management

MUSH management javelin Mon, 2012-02-13 19:55

Questions and answers about running a MUSH.

Can I restrict a command to objects without a flag?

Can I restrict a command to objects without a flag? javelin Mon, 2012-02-13 20:03

Can I restrict a command to objects without a flag?

'restrict_command foo !FLAG' removes FLAG from the list of required flags to be able to use that command, and doesn't restrict the command to just objects without that flag. Just add a new flag with @flag and restrict the command to it, and set it on all objects but the ones you don't want using the command.

2003-Jun-16 6:58pm shawnw

How do I change some of the messages generated by the mush?

How do I change some of the messages generated by the mush? javelin Mon, 2012-02-13 19:59

How do I change some of the messages generated by the mush?

Two ways. If you don't mind changing the source code, you can find the line that generats the message you want to change, edit it, re-compile, and reboot the mush.
If you'd rather avoid doing that, you can take advantage of the support for translating messages into other languages to just customize a few. The directions below assume you're running the mush on a unix server and are logged into the mush account's shell in the base pennmush directory. If you're using Windows or Macintosh, you'll probably have to resort to the first option.
First, create an index of all the strings marked for translation by running 'make pennmush.pot'. That will create a file named pennmush.pot in the po/ subdirectory. cd to that directory, and 'cp pennmush.pot en.po'.
Then, using your favorite text editor, open the file en.po, and look for a line like 'msgid "The message you want to change"'. The next line will be 'msgstr ""'. Put the customized message in the double quotes. Save the file and exit the editor.
Next, you need to compile the translation file. Do this with 'LANG=mine make localized'. That done, you need to edit the restart script in the pennmush/game directory. A few lines into the file is a commented section titled Internationalization stuff. Below the comments (The lines starting with #'s), add this line: 'export LC_MESSAGES=en'.
Finally, @shutdown the mush (A full @shutdown, not a /reboot), and start it back up again with the restart script. If all goes well, you should see something in game/log/netmush.log about 'Setting messages locale to mine'. and will get the custom messages. If not, you probably have to fiddle more with your environment variables a bit. Try LANG or LC_ALL instead of LC_MESSAGES, for example. See the gettext documentation on the account for more information.

2002-Apr-25 7:37pm shawnw

A slight variation on the above is to create po/en.pox instead of po/en.po. In this approach, en.pox contains only those entries that you're changing from the default (so it may be a very short file).

After you've got en.pox, you can build en.po from it automatically by running "make en.po" in the po/ subdirectory. This will combine en.pox with the pennmush.pot template and produce en.po. Thereafter, follow Raev's instructions.

This is the approach that's used by Javelin to build the translation files that are actually distributed on the ftp site. Advantages of this approach are than when pennmush.pot gets updated, you can quickly rebuild a matching en.po, and you get to easily see which entries you've changed. A disadvantage is that you have to copy and paste the untranslated entries from pennmush.pot into en.pox and edit them, rather than having the whole file copied in one fell swoop.

2002-Dec-02 12:03pm dunemush

How do I get a pennmush.org hostname?

How do I get a pennmush.org hostname? javelin Mon, 2012-02-13 20:07

How do I get a pennmush.org hostname?

Follow the instructions given here: http://services.pennmush.org/faq.html#SEC9

2005-Mar-03 12:14pm shawnw

How do I make an actual game using Penn?

How do I make an actual game using Penn? javelin Mon, 2012-02-13 20:04

How do I make an actual game using Penn?

Sorry, I am new here, just trying to figure out how to post a question. I downloaded PennMUSH, and I read the Guide for Gods, however, I didn't find information on how to CREATE a game? How do I create rooms, objects and NPC's? How do I make them talk and perform actions? How do I place objects in certain rooms and how do I bind them? I googled, but couldn't find a step-by-step manual, but I'd be pleased if anybody could point me towards some kind of manual that covers creating of a MUSH. Thanks, and sorry if I did something wrong while trying to post my question.

2003-Jun-09 2:32am zeitenflug

Ok, I DID somehow screw up while posting, I admit it, but I found an answer - isn't that amazing? To all people new to MUSHing in general and specifically to PennMUSH: My very short (and probably not all accurate answer) as to HOW DO I CREATE A GAME with PennMUSH:
It IS complicated, a lot more than, let's say, with MORDOR, but on the other hand it gives you a whole lot more opportunities, and if you aren't afraid to learn something new, it's an all powerful...errr... thingy.
MUSH seems to be some kinda "standard" - not really, since you can sometimes find things like "on TinyMush you have to type that-and-that and on PennMUSH this-and-that", but there's some kind of overall logic to all MUSHes and the language used to write games is generally the same.
It is called mushcode, and that's a vital information, since it took me some days to figure that one out (could somebody please put it into the manual?) and once you know it, it's easy to find tutorials and stuff on the internet. You could go to mushcode.com, e.g., or to http://moosh.net/mush/mushcode.shtml. Both are good starting points.
The problem is, with all things that are powerful, PennMUSH isn't something you just can download, use and enjoy as easily as MORDOR. You have to go through lots of tutorials first, learn about security issues and so on. Once you did it, there's a complicated programming language waiting to be explored, and so on. But wait - just go looking for the URLs. I'll open a BLOG at pennmush.org and I'll put down my way towards using PennMUSH. In case you're new to all this stuff, I'd be happy to hear from you and your efforts. Perhaps I can find out useful stuff, that helps getting you the hang of it.

2003-Jun-15 6:58am zeitenflug

How do I set up guest characters?

How do I set up guest characters? javelin Mon, 2012-02-13 19:58

How do I set up guest characters?

You can have as many guest characters as you want, with whatever names you wish. They all must have the guest @power, and at least one of them must be named or aliased Guest (Passwords don't matter).
If that character is already logged in when someone tries to connect as a guest, the first disconnected guest-@powered player is used instead. If all guest-@powered players are logged in and more people tr to connect as guests, they will double up on some of the guest players (Two or more people connected using the same character, from different sites). If this happens frequently, you should create some more guest characters.

2001-Jul-05 8:50am shawnw

I accidently deleted some directories including the one where Penn saves databases to

I accidently deleted some directories including the one where Penn saves databases to javelin Mon, 2012-02-13 20:02

Oops. This means that saves don't work. Well, the database gets saved, but where it's saved to is no longer accessible outside of the mush process, so you can't get it from a shell.
Here's an (untested) possible approach to fixing it:
If you've lost the netmush binary, grab a new tarball and recompile using all the same options as theo original.
Attach to the running mush process using gdb (gdb netmush PID). At the gdb prompt, try 'p options.output_database = "/full/path/to/someplace/outdb"'. Do the same for options.chat_database and options.mail_database. Quit gdb, do a @dump, and look for the database files. Hopefully they're there.

2003-Apr-29 8:20pm shawnw

I have an error from info_slave in netmush.log!

I have an error from info_slave in netmush.log! javelin Mon, 2012-02-13 20:05

Messages like 'info_slave reading remote size: Invalid argument' and similar errors indicate that the mush stopped running without politely telling the info_slave to shut down (Usually due to a crash). It can usually be ignored; errors from the mush itself right above it in the log file are likely to be important, however.
The info_slave process itself is used to look up the hostnames associated with IP addresses. This can be a slow procedure, so it's done by another program instead of having the mush tied up with it and unusable for anything else during that time.

2003-Jun-24 7:47pm shawnw

Listening on alternate ports

Listening on alternate ports javelin Mon, 2012-02-13 20:01

Some people on the internet are behind a firewall which disallows outgoing connections to non-standard ports. So, for example, they may not be able to connect to your MUSH on port 6969.

A solution is to make the MUSH also listen on a standard port (in this example, I use 443, which is usually used for secure HTTP connections). This assumes you have iptables installed on the system, and are logged on as root. It should probably be put in /etc/rc.d/rc.local so that it will be re-executed upon machine boot.

/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -d --dport
443 -j DNAT --to

In the above, is my MUSH's IP address. 6969 is the normal port of the MUSH. 443 is the port I've setup especially for people who can't reach port 6969.

This port forwarding does not obfuscate the LASTSITE of players who connect through the alternate port, since it is done at the kernel level.

2002-Dec-01 2:02am pmak

Old DB, much garbage

Old DB, much garbage javelin Mon, 2012-02-13 19:56

OK. I have been trying to make an argument against using an old DB on a game. I'd much rather start fresh. The old DB is 3-4 years old, 15,000 objects. Already, 10,000 objects have been destroyed, leaving about 5,000 actual objects.
This just seems wrong to me. I'd much rather start anew. Is there any technical reasons as to why one doesn't want 10,000 garbage holes in a DB? Possible corruption problems in the future?

2001-Apr-16 10:44am krey

No corruption. But although garbage objects don't take much memory, they do take some, and a game with 10,000 garbage and 5,000 real will be measurable larger, memory-wise, than a game with only 5,000 real.
In fact, because of the way PennMUSH allocates room in the array for objects,
you pay an even worse penalty. PennMUSH preallocates large chunks of this array to make things faster (so it doesn't have to grow the array by one object every time the db goes up by one). By default, any time the db array needs to grow, it doubles. So initially, this game will have 15000 db array slots. If you ever actually reuse all that garbage, the next object created will cause the game to have 30,000 array slots. Contrast this with a game with 5000 non-garbage objects. The next object created brings you to 10,000 array slots, which is still less than the 15,000 you'd start with using the old db.
That said, there are also advantages to reusing old dbs that often outweigh the above for small dbs (such as reusing code that depends on dbrefs, etc.) But for a 15,000 object db, you'll have to decide if your memory is sufficient to make it worthwhile.

2001-Apr-16 8:06pm dunemush

Uppercase to Lowercase commands

Uppercase to Lowercase commands javelin Mon, 2012-02-13 20:05

Is there any way to alias the uppercase commands like WHO to who and QUIT to quit? I'm moving over from TinyMUX where we're all used to just typing them lowercase and my players are requesting I figure this out.

2004-May-07 3:39pm kelvin

Not without modifying those bits of the source (In bsd.c) to do case-insensitive string comparisions.

2004-Jul-24 10:39am shawnw

UPPERCASE means something by convention in Penn. An uppercase command is one that's associated with the player's socket, rather than the player object. That's why you can QUIT a single connection, and not have all your connections logged out (and why you can't run WHO when you're disconnected).

2012-02-13 javelin

What can I do to the MUSH from the shell account?

What can I do to the MUSH from the shell account? javelin Mon, 2012-02-13 20:01

What can I do to the MUSH from the shell account?

On UNIX systems, there is a command called kill which will send a signal to a specific process, like the mush. Signals are a way of letting a program know that some external event happened that it needs to know about, and Penn gives special meaning to several.
The kill program is usually invoked with 'kill -SIGNAL PID', where PID is the process ID of the mush. It's found at the top of pennmush/game/log/netmush.log,
or in the wizard version of @uptime in the mush itself.
The signals understood by Penn and what they do:
kill -HUP: Re-read all the config files, cached text files like the connect screen, sitelock file, re-build help indexes.
kill -USR1: Same as @shutdown/reboot
kill -USR2: Same as @dump
kill -INT: Same as @shutdown
kill -TERM: Same as @shutdown/panic

2002-Nov-04 3:40pm shawnw

Why do IP addresses on my mush look funny?

Why do IP addresses on my mush look funny? javelin Mon, 2012-02-13 19:56

Why do IP addresses on my mush look funny?

If your mush shows IP address in a format like ::ffff:NNN.NNN.NNN.NNN instead of NNN.NNN.NNN.NNN, it's the result of an IPv4 address being mapped into an IPv6 one. This usually happens when the mush is running on a server that supports the newer IPv6 standard, with connecting clients that use IPv4. It's perfectly normal.

2001-Apr-21 2:09am shawnw

It's possible to tell the mush to use only IPv4 networking even when IPv6 networking is available, and this will cause IP addresses to be the 'normal' IPv4 ones without the funny characters. This isn't recommended, as it's good to do everything possible to promote the use of IPv6 over IPv4, but it can be done.
In the mush config file, set the ip_addr directive to "", so the line looks
Alternatively, you can set it to a specific IP address. The means "All IPv4 addresses being used". It requires a full @shutdown and restart to take effect, as @shutdown/reboot won't open new sockets for listening.

2002-Dec-01 1:13am shawnw


Softcode javelin Sun, 2012-02-12 22:02

Herein find answers to frequently-asked questions about softcode on PennMUSH.


$commands javelin Sun, 2012-02-12 22:21


How can I make +who, who, and wh all run the same code?

How can I make +who, who, and wh all run the same code? javelin Sun, 2012-02-12 22:26

How can I make +who, who, and wh all run the same code?

Regular expression (regexp) command matching is a very efficient way to do this. One can write code like this:

  &DO_WHO obj = $^\\+?who?$: @pemit %#=...who code here...
  @set obj/DO_WHO=regexp

The regular expression "\\+?who?$" means "an optional + sign", a "w", an "h", and an optional "o", which nicely describes +who, who, wh (and also +wh)

More detail about regexps is available in the Penn help or the book Mastering Regular Expressions, published by O\'Reilly. (Note that Penn\'s regexps are essentially the same as perl 5, but often require extra \\ escapes when used in contexts where they\'ll be evaluated by the Penn parser first (like regmatch))

2001-Apr-01 5:01pm dunemush

Note that the pattern part of attributes with $-commands on them aren\'t evaluated, so the only thing that needs extra escaping here is any colons (:)\'s in the pattern, so they aren\'t taken as the end of the pattern. It\'s only in functions that the extra escapes are needed. The + is escaped in the regexp above because + is a special regexp character. The backslash turns it into something matching a literal +.

2001-Jun-11 8:12pm shawnw

How do I lock the commands on an object to only things inside it?

How do I lock the commands on an object to only things inside it? javelin Sun, 2012-02-12 22:38

How do I lock the commands on an object to only things inside it?

&location <object>=%L
@lock/use <object>=location/<object\'s dbref>

How this works: %L is a substitution that evaluates to the location of %#. So, when the use lock is checked, the location attribute on <object> is evaluated, returning the location of %# (The object trying to pass the use lock). If that matches the second part of the eval-lock, %# is in the object, and it passes the lock. Otherwise, it fails.

2001-Jul-27 7:16pm shawnw

What good are global exits in the master room?

What good are global exits in the master room? javelin Sun, 2012-02-12 22:36

What good are global exits in the master room?

Exits in the master room can be used from any place in the mush, if not overridden by something else. See HELP EVALUATION for details on the order commands are checked against things.

These global exits are good for use as commands that move their user to another location -- for example, a +ooc command that takes people to an OOC area of the mush. Using a global exit for this is simpler than writing a command that displays the needed messages and does a @teleport, because it acts in all respects like a normal exit.

Globals exits can\'t, of course, be used to emulate commands that take arguments, and as a matter of style and efficiency, shouldn\'t really be used for things that don\'t involve moving objects around.

2001-Jun-11 8:09pm shawnw

Global locked exits are also useful in the master room if you have a lot of cardinal directions on your MUSH and don\'t want people to see \"Huh?\" when they try to go east in a room with no east exit:

In the master room:

@open East;e;north;n;west;w;south;s;up;u;down;d=here
@lock east=#0
@fail east=You can\'t go that way.

produces a nicer error message.

2001-Aug-01 8:38pm dunemush

What\'s the best way to have a vehicle moved by someone inside it?

What\'s the best way to have a vehicle moved by someone inside it? javelin Sun, 2012-02-12 22:37

What\'s the best way to have a vehicle moved by someone inside it?

Something along the lines of

&drive_cmd car=$drive *:go %0

In particular, you do not need to use @force, nor do you want to.
Both of these

&drive_cmd car=$drive *:@force me=%0
&drive_cmd car=$drive *:@force me=go %0

will allow anyone to effectively control the car. They can make it do anything at all with the drive command.

Imagine someone typing: \'drive @nuke me\'.

2001-Jul-26 8:27pm shawnw

What\'s wrong with &DO_IT obj=$do_it: [pemit(%#,You did it)]

What\'s wrong with &DO_IT obj=$do_it: [pemit(%#,You did it)] javelin Sun, 2012-02-12 22:24

What\'s wrong with &DO_IT obj=$do_it: [pemit(%#,You did it)]

MUSHcode makes a distinction between commands and functions. @pemit, for example, is a command that notifies a player with a message. pemit() is a function that, as a side effect, notifies a player with a message.

There are some places where commands are expected, and others where functions are expected. The code triggered by a $command, a ^pattern, or @trigger must be a command (or set of commands). So this is ok:

  $do_it: @pemit %#=You did it

And this is ok, if (to my mind) uglier:

  $do_it: think [pemit(%#,You did it)]

But this is wrong:

  $do_it: [pemit(%#,You did it)]

because there is no command to run. If this code works, you\'re just lucky - there is no assurance it will work in the future -- it is simply wrong code.

Similarly, only functions can be called from within functions. This code doesn\'t do what a naive coder might expect:

  $do_it: think [switch(%#,#7,@emit hi,@emit hello)]

The object will think "@emit hi" or "@emit hello", but it won\'t do the emit. This is what\'s probably meant:

  $do_it: @switch %#=#7, { @emit hi }, { @emit hello }

or (usually best):

  $do_it: @emit [switch(%#,#7,hi,hello)]

or, if you must, one of these:

  $do_it: think [switch(%#,#7,emit(hi),emit(hello))]
  $do_it: think [emit(switch(%#,#7,hi,hello))]

2001-Mar-29 6:17pm dunemush

Why aren\'t exits matched for $commands?

Why aren\'t exits matched for $commands? javelin Sun, 2012-02-12 22:22

Why aren\'t exits matched for $commands?

For largely historical reasons, exits are considered to have their \'home\' in the room in which they originate, but their \'location\' is their destination room. So while it wouldn\'t be hard to have $command checking performed on all exits in the player\'s location, when the exit ran the command, it would do so as if it were located in the destination room, rather than where the player is.

There used to be some sense to this; the current structure for objects in the db tries to be highly memory-efficient by overloading fields like \'location\', and back in the day of low RAM, that was a good thing. Nowadays, it\'s less sensible, and this may change one day if the database internals are rewritten.

2001-Mar-28 1:58pm dunemush

Working with lists

Working with lists javelin Sun, 2012-02-12 22:03

Working with lists

How can I explode a string into a list of characters?

How can I explode a string into a list of characters? javelin Sun, 2012-02-12 22:12

How can I explode a string into a list of characters?


2001-Apr-01 4:54pm dunemush

How can I get every other item of a list (Or every 3rd, 4th, etc.)?

How can I get every other item of a list (Or every 3rd, 4th, etc.)? javelin Sun, 2012-02-12 22:17

How can I get every other item of a list (Or every 3rd, 4th, etc.)?

Up to every 10th item can be gotten very easily, with the help of step().

For example:

&every_other foo=%1

think step(foo/every_other, a b c d e f, 2) 

=> b d f

If you want every other element starting with the first, use
%0 instead of %1.

Alternatively, you can use elements() and build the list of
positions using lnum() and vmul().

For example:

think elements(a b c d e f, vmul(lnum(0, 6), 2))

2001-Nov-13 6:44pm shawnw

How can I remove all spaces from a list?

How can I remove all spaces from a list? javelin Sun, 2012-02-12 22:11

How can I remove all spaces from a list?

edit(list of elements,%b,)

2001-Apr-01 4:52pm dunemush

How do I convert a list into a list of arguments?

How do I convert a list into a list of arguments? javelin Sun, 2012-02-12 22:20

How can I convert a standard space-separated list of integer values into a list of arguments that can be passed to a function that accepts an indeterminate number arguments, such as add() or max()?

2006-Jun-29 12:29pm misfit815

The answer is in Section 14.5 of Amberyl\'s MUSH manual. The use of fold() is necessary.

2006-Jun-29 1:23pm misfit815

If you want to pass a space-separated list of numbers to a math function, lmath() can be used instead of fold().

2007-Jan-29 12:05pm shawnw

How do I get a list of all the characters/letters the mush accepts?

How do I get a list of all the characters/letters the mush accepts? javelin Sun, 2012-02-12 22:19

How do I get a list of all the characters/letters the mush accepts?

Many mushes can work with non-ASCII accented letters and other special characters. The @nameaccent attribute, and the accent(), chr() and ord() functions can be used to generate some of them in softcode, and you can send others through your client if you can type them, or cut&paste. But what about seeing exactly what characters the mush will handle in a better way than trial and error?

With the regraball() function, you can generate lists of every character the mush considers "printable" and thus accepts, or the characters that meet stricter restrictions, like "every lower-case letter".

To do this, call regraball() like so:

regraball(iter(lnum(1, 255), chr(##)), ^\\[\\[:FOO:\\]\\]$)

FOO is one of the following classes:

 upper, for upper-case letters,
 lower, for lower-case letters,
 alpha, for letters,
 digit, for digits,
 alnum, for letters and digits,
 word, for letters, digits and _,
 xdigit, for digits in base-16 numbers,
 ascii, for characters in the ASCII set only,
 punct, for punctuation characters,
 space, for white-space characters
 graph, for non-white-space characters,
 print, for all characters

There\'s also cntrl, but none of the characters that can match it can be
generated by chr().

If you want to get just characters that also fall into a certain range (Like, from A to Z), you can fiddle with the lnum() bit as needed.

2004-Jul-24 10:50am shawnw

Here\'s a line of code you can just paste to make it list all the printable characters:

th edit(iter(lnum(1,255), switch(chr(##), #-1*,,#$)),%b,)

2003-Apr-23 7:28am pmak

I have a list of attributes named FOO1, FOO2,...FOO100. How do I sort them so the numbers are in the right order?

I have a list of attributes named FOO1, FOO2,...FOO100. How do I sort them so the numbers are in the right order? javelin Sun, 2012-02-12 22:09

I have a list of attributes named FOO1, FOO2,...FOO100. How do I sort them so the numbers are in the right order?

The default PennMUSH sort() is lexicographic, which means that FOO2 will be sorted after FOO100.
For simple lists of numbers, you could do sort(1 2 ... 100,n) and get a numeric sort, but that won\'t work for attribute names with text before the numbers. Here\'s a few things that will:

&HELPER obj=[sub(after(%0,FOO),after(%1,FOO))]

sortby(obj/HELPER,FOO1 FOO2 ... FOO100)

&NUMSORT obj=[sort(%0,n)]

munge(obj/numsort, edit(FOO1 FOO2 ...,FOO,), FOO1 FOO2 ...)

The first version works by comparing the numbers after "FOO" in a given pair of attribute names, and returns a negative number when %0 should be before %1, a positive number when %1 should be before %0, and 0 when they\'re the same. This is exactly what sortby() needs to sort the list.
The second version uses edit() to build a list of just the numerical parts of the attributes, and munge sorts this list numerically and then returns the corresponding elements out of the original list.

2001-Mar-28 10:02am dunemush

Or, you could have named them as FOO001, FOO002, ..., FOO100 in the first place, thus allowing you to sort lexographically. You can generate zero-padded numbers this way:

> think iter(lnum(1, 100), rjust(##, 3, 0))

001 002 003 ... 100

2003-Apr-23 7:32am pmak

List X contains element W. How do I get the corresponding element from list Y of the same length?

List X contains element W. How do I get the corresponding element from list Y of the same length? javelin Sun, 2012-02-12 22:05

List X contains element W. How do I get the corresponding element from list Y of the same length?

Take your pick:


2001-Mar-28 9:55am dunemush

This also works:


This can be useful when W is produced by a u() call w/o arguments (you can get rid of the set() and just use the name of the u()\\\\\\\\\\\\\\\'d attribute in place of uh_temp).

2001-Mar-28 11:05am popiel

What\\\'s the difference between match(), member() and strmatch()?

What\\\'s the difference between match(), member() and strmatch()? javelin Sun, 2012-02-12 22:15

What\\\'s the difference between match(), member() and strmatch()?

match(list, wildcard pattern[, delimiter])
member(list, element[, delimiter])
strmatch(string, wildcardpattern)

match() and member() are list functions that look for a matching element in a list and return its position in the list, or 0 if it\\\'s not found. member() does case-sensitive exact matches, which makes it good for things like dbrefs. match() is case-insensitive, and does wildcard matching (* and ?), so it can be used to find things like the first element of the list starting with the letter F (or f).

strmatch(), on the other hand, is a string function. Instead of treating its first argument as a list to be broken up into individual elements to look at, it compares the entire argument at once against the wildcard pattern, and returns 1 if it matches, 0 if not.

2001-Oct-22 6:52pm shawnw

Why is this code that uses iter() adding spaces I don\\\'t want?

Why is this code that uses iter() adding spaces I don\\\'t want? javelin Sun, 2012-02-12 22:13

Why is this code that uses iter() adding spaces I don\\\'t want?

The spaces are probably coming from the default output seperator of iter(), which happens to be a space. An empty fourth argument to iter() will eliminate the output seperator.

For example:

iter(#1 #2 #3, complex formatting code, %b, )

2001-Jun-11 8:16pm shawnw

Does an object have to be set PUPPET to be @forced?

Does an object have to be set PUPPET to be @forced? javelin Sun, 2012-02-12 22:54

Does an object have to be set PUPPET to be @forced?

No. Any thing or player-type object can be @forced by other objects that control it. The puppet flag is not involved.

2001-Jul-26 8:21pm shawnw

How can I make a room display objects and exits in two side-by-side columns?

How can I make a room display objects and exits in two side-by-side columns? javelin Sun, 2012-02-12 22:41

How can I make a room display objects and exits in two side-by-side columns?

By default, rooms display their contents list and then their exit list. The @conformat and @exitformat attributes on the room control the appearance of these lists. The easiest way to get a side-by-side display is to have @conformat do nothing but store the list of objects the player can see, and to have @exitformat display both contents and exits in two columns:

  &CONFORMAT here=[set(me,VISIBLE:%0)]
     [ljust(Contents:,40)] Exits: [iter(lnum(1,max(words(v(VISIBLE)),words(%0))),
      %r[ljust(name(extract(v(VISIBLE),#@,1)),40)] [name(extract(%0,#@,1))])]

The CONFORMAT, which is evaluated first, stores the list of contents visible to the looker in the VISIBLE attribute. The EXITFORMAT iterates through the elements of VISIBLE and its %0 (the list of visible exits) and displays them in two columns.

(You may want to truncate the names at 40 chars, etc., as well)

2001-Mar-28 10:44am dunemush

Instead of using extract() to get at the elements of one of the lists, you can also use the mix() function to pass the corresponding elements of two (Or more) lists to an attribute. For example:

 &format_line object=[ljust(name(%0), 30)][name(%1)]
 @conformat object=
 @exitformat object=[ljust(Contents, 30)]
     Exits%r[mix(format_lines, lvcon(me), %0, %b, %r)]

This code also uses the lvcon() function to get the list of visible contents, rather than saving the list in the @conformat. An empty @conformat is needed so you don\\\\\\\'t get the default contents list and your custom one generated in the @exitformat.
2004-Jul-24 10:47am shawnw

In recent versions of Penn(), align() allows for separation of code logic for either columns.

@conformat  here=
@exitformat here=align(<30 >30,Exits:%r[iter(%0,name(##),%b,%r)],

Note that the >30 in align will right-align the Things list. This can easily be changed to <30 to left-align it.

2004-Jul-24 10:57am walker

How can you tell if a player is hidden by @hide?

How can you tell if a player is hidden by @hide? javelin Sun, 2012-02-12 23:03

In the help, it says to use @hide over the dark flag, but how do you tell via code that a player is using it?

Examining myself, I could not figure out any means to detect if a player is hidden.

2004-Jan-04 5:59pm strolfey

The hidden() function is used to tell if a player is hidden or not.

2004-Jan-16 1:02pm shawnw

How do I automatically add new players to an in-game channel such as \'help\' or \'newbie\'?

How do I automatically add new players to an in-game channel such as \'help\' or \'newbie\'? javelin Sun, 2012-02-12 23:06

How do I automatically add new players to an in-game channel such as \'help\' or \'newbie\'?

I\'m only asking about this because I keep misplacing the documentation that I get from the helpful folks on the M*U*S*H +softcode channel.
From what I remember though, I had to:
1. create an object and set it in the room where new players connect,
2. set that object wizard,
3. set a command on that object to add the new player to \'help\' or \'newbie\',
3. set the @aconnect on the room to trigger the command on the object.
Is this correct because I can\'t seem to get it to work. Any help would be appreciated.

You\'re on the right track.
The easiest way is to @set the room new players are created in (#0 by default) Wizard and add an @aconnect to it that does a \'@channel/on Newbie=%#\'.
If the room isn\'t Wizard, I don\'t think it can trigger anything on an object that is.


How do I colorize exit names?

How do I colorize exit names? javelin Sun, 2012-02-12 23:00

As an example, here\'s a parent object that will, given exits following the common naming
pattern of : Name <Alias>;Alias, highlight the <Alias> bit. (It requires Penn 1.7.5).

 @create Color Exit Parent
 @exitformat Color Exit Parent=Obvious Exits:%r[map(format_exit, %0, %b, %r)]
 &format_exit Color Exit Parent=regedit(name(%0), <\\\\w+>$, setq(E, $0)[ansi(h, %qE)])

It\'s easy to extend the format_exit attribute to do transparent-room checks and any other features

2004-Jul-24 10:55am shawnw

I have done this, though I don\'t understand how to use the color exit parent once created. Please help.

2007-Jan-20 2:49am violetallure

How do I create an attribute on a player, when they pass through an exit?

How do I create an attribute on a player, when they pass through an exit? javelin Sun, 2012-02-12 22:56

How do I create an attribute on a player, when they pass through an exit?

  @asuccess exit=&attr %#=value

The exit also has to be set WIZARD, so it has permission to set attributes on players.
2001-Sep-09 3:34pm shawnw

How do I destroy an object immediately?

How do I destroy an object immediately? javelin Sun, 2012-02-12 23:02

How do I destroy an object immediately?

Normally, when you @recycle an object, it doesn\'t get destroyed for a while. This is handy for those times when you realize just after you do it that you really wanted to keep it, and can safely @unrecycle it. But what if you really do want it gone at once? Just use @recycle on it twice in a row.

2003-Jun-23 7:49pm shawnw

How do I find all objects @parented to a given object?

How do I find all objects @parented to a given object? javelin Sun, 2012-02-12 22:51

How do I find all objects @parented to a given object?

The easiest way to find all children of a given object is to use @search:

  @search all parent=#1234

If you want to find all descendants of an object (including objects
which are @parented to the object\'s children, or its children\'s
children, etc.), then you can use:

  @search all eval=member(lparent(##), #1234)

Of course, you can also use the lsearch() function similarly.

In future, PennMUSH may add a children(X) function as syntactic
sugar for lsearch(all, parent, X), but it will cost the same and
be subject to exactly the same restrictions as the lsearch().

2001-Apr-16 11:58am popiel

children() was added in 1.7.7p13

2003-Apr-29 8:23pm shawnw

How do I get a list of all the connected players in a room or object?

How do I get a list of all the connected players in a room or object? javelin Sun, 2012-02-12 22:57

How do I get a list of all the connected players in a room or object?

&is_connected room=gte(conn(%0), 0)
&list_players room=filter(is_connected, lcon(me))

... or something along similar lines. 

2001-Oct-22 7:16pm shawnw

In Penn 1.7.5, you can use lvplayers() instead. There\'s also lplayers(), which doesn\'t check for connection status.

2001-Nov-13 6:49pm shawnw

How do I get around &quot;I don\'t know which you mean&quot;?

How do I get around &quot;I don\'t know which you mean&quot;? javelin Sun, 2012-02-12 22:52

How do I get around "I don\'t know which you mean"?

In versions of PennMUSH before 1.7.4p2 or so, when you have multiple objects with the same name, and you try to match one (by using \'get thing\', \'look thing\' or any other command), the command will work, but on an arbitrarily chosen one of the objects (sometimes randomly chosen, sometimes the first one in the room\'s contents).
As of 1.7.2p2, the parser correctly interprets this situation as one of ambiguity, and instead of choosing for you, reports "I don\'t know which you mean" or similar, functions return #-2, etc.
But what do you do if you need to write code that acts on one of the objects? How can you choose a particular one?
The solution is English matching. Since 1.7.3, PennMUSH has supported the following adjectives before object names:

  1st/2nd/3rd/4th/etc.  -- to specify the xth object visible to you
  my 1st/2nd/3rd/etc.   -- the xth object in your inventory
  this here 1st/2nd/etc. - the xth object in the room with you

(\'this here\' may be abbreviated \'here\')
So if you write a vendor that creates identical objects and gives them away, rather than have it \'give %#=object\', use \'give %#=my 1st object\' and you can be sure it will work, even if your vendor somehow comes to contain multiple \'object\' objects.
Of course, if you know dbrefs, you can always work by dbrefs as well.
(And if you have side-effect functions, write your vendors to use create(),
and keep the dbref, and operate that way!) You can often get dbrefs using the locate() function, which can be instructed to treat ambiguous cases in the old style (returning an arbitrary matching object), as well as to use english matching.

2001-May-19 12:33pm dunemush

In recent versions, there is also "toward" for exits. For example, if there\'s two exits going east, "toward 1st east" will reference the first east exit.

2003-Apr-23 7:22am pmak

How do I get the dbref of a room dug by a hotel vendor?

How do I get the dbref of a room dug by a hotel vendor? javelin Sun, 2012-02-12 23:11

How do I get the dbref of a room dug by a hotel vendor?

I have a wizard device that digs rooms for rental. The rented rooms are connected to the room in which the device sits.
How do I programmatically find out the dbref of the newly created room so that the device can either set descriptive text for the new room (desc, succ, osucc, ofail; etc) from its remote location, or [guarantee to] teleport the user to the room and force him/her to set these things? Room names are "1", "2" and so on.
Thanks in advance.

2008-May-09 9:52am eric.twose

>The main issue is that the vendor needs to be able to transfer ownership of the new room to the new tenant so that when we programmatically get him/her to move to the new room and set up desc, etc, we don\'t get permission denied errors. But without a dbref, the vendor cannot see the new room.

2008-May-09 10:35am eric.twose

Of course, the function dig() returns a dbref unlike @dig.
2008-May-09 2:12pm eric.twose

How do I lock an object for one person at a time?

How do I lock an object for one person at a time? javelin Sun, 2012-02-12 23:16

How do I lock an object for one person at a time?

The following prevents a second user coming along and being built a room by a vendor whilst still processing a previous user request:
&INUSE Room Digger<rd>=0
In the Room Digger object\'s dig command:
@switch v(INUSE)=<1,{v(INUSE)=1;{build the room};v(INUSE)=0},{@pemit %#=Sorry but the clerk is busy dealing with another client. Wait a few seconds.}

2008-May-09 3:51pm eric.twose

Actually, that code\'s wrong in several ways. v(INUSE)=.. should probably be &INUSE me=..., because commands are expected there, not function. But the more serious problem is that there\'s a race condition. @switch queues its action lists, so you\'ll find that you can very quickly trigger that command twice. For real protection, you could use a semaphore, but the easiest modern approach involves @break:

$build: @break [v(INUSE)]=@pemit%#=Sorry but the clerk is busy; 
   &INUSE me=1; 
   @@ Build the room;
   &INUSE me=0

This assumes your room-building commands don\'t use the queue (that is, don\'t involve @wait, @force, @trigger, @switch). If they do, semaphores are your friend:

&build vendor=
    $build: @wait me={ @@ Room building commands; 
        @notify me }
@drain vendor
@notify vendor

2012-Feb-10 javelin

How do I send guests home to room 0 when they QUIT?

How do I send guests home to room 0 when they QUIT? javelin Sun, 2012-02-12 23:10

How do I send guests home to room 0 when they QUIT?

Q: When guests are used, the user very rarely returns the guest to the start room 0, so the next time someone comes along, they may find their guest character at the bottom of a dark pit. How can I automatically send them home when they QUIT?

2008-Apr-29 10:17am eric.twose

@aconnect #1234=home

2008-May-01 5:22am eric.twose

The @aconnect will send them home when they next connect (and will show the new guest a message as they are sent home right after connecting). You might prefer to send the guest player object home after its user disconnects. Just use @adisconnect in place of @aconnect.

2012-Feb-10 javelin

How do I tell if a player is connected?

How do I tell if a player is connected? javelin Sun, 2012-02-12 22:55

How do I tell if a player is connected?

With something like this:
gte(conn(*player), 0)

You shouldn\'t use hasflag(*player, connected). That will only work for see_all objects, because the connected flag is hidden to mortals. This might change in the future, but don\'t depend on it. Stick to conn().

2001-Jul-27 8:37pm shawnw

I am having trouble using Zones

I am having trouble using Zones javelin Sun, 2012-02-12 23:01

I wish to use zones in the Mush that i am creating, but am instead having terrible difficulty.
I am trying to make it so that each empire has it\'s own zone, and in turn all rooms and exits and objects become apart of it. The main usage that i want to use an exit with a zone is so that only people with authorisation and/or is apart of that empire can enter through it.
I have as such tried, but with no luck, if anyone could help i would be gratefully appreciated.

2002-Jan-11 7:08pm FishHerring73864

This is for when you have different places on a MUSH grid (like 4 cities), and rather than have everything be in the Master Room, you want to have city-specific codes for each section of the grid. For the sake of ease, we\'ll call the zone-specific code Local Globals and the zone-master will be Zone Master Room.
1) Make sure that the room you are going to put the Local Globals in is @lock/zone <db #>==<whoever\'s in charge>. The double = is needed, otherwise someone can carry the person in charge and pass the lock.
2) @chzone <the room you want in the zone>=<db # of the Zone Master Room>
3) Drop all the Local Global objects into the Zone Master Room.
That should do it.

2002-Sep-20 9:43am ellis1138

Large Ansi Output Cutoff

Large Ansi Output Cutoff javelin Sun, 2012-02-12 22:50

Alright.. I don\'t think my question got added right the first time, so here goes. Anyways, I have a function that is outputting a lot of ansified text (a grid of characters), but after a certain number, it just cuts off and stops displaying the characters. I checked the function invocation limit, and that isn\'t the problem. When I remove the ansi(), it outputs fine.. I\'m thinking it may have something to do with the output buffer, but I\'d be unsure in how to change that. Any suggestions?

2001-Apr-05 8:17pm twpage

As you suggest, the cutoff is likely due to limited buffer size and
the way that the MUSH stores ANSI codes. Each ANSI transition takes
up between 4 and 7 bytes in the fixed-size (usually 8K) evaluation
buffer... so if you\'re doing color transitions with every character,
you\'ll only be able to fit around 1000 visible characters into the
buffer. Possibly less if you\'re combining foreground, background,
and highlight in each change (that\'s 3 separate transitions, when
One way to deal with this would be to generate (and @pemit or whatever)
each line of output separately. It\'s very unlikely you\'ll have so much
ANSI stuff that you won\'t be able to fit 80 visible characters into the
Alternatively, if you have hardcode access to the server you\'re doing
this on, you can increase the BUFFER_LEN above 8K. I really don\'t
encourage this, however.
PennMUSH may start dealing more economically with ANSI in future... but
I wouldn\'t wait for it.

2001-Apr-06 4:39pm popiel

My Parent Room object isn\'t working.

My Parent Room object isn\'t working. javelin Sun, 2012-02-12 22:58

I Found some softcode on the Net, that creates a fancier version for displaying objects and exits, the only problem is that it didn\'t display them in two side by side columns, so i attempted to join the example from this FAQ site with the other, it sort of works but the columns aren\'t displaying properly.
Any help would be greatly appreciated. The code is as follows:

@create Room Parent v.04
@link Room Parent v.04 = here
@set Room Parent v.04 = INHERIT
@set Room Parent v.04 = NO_COMMAND
@CONFORMAT Room Parent v.04=[ansi(gh,[ljust(Contents:,43)] Obvious Exits:%r)]
@set Room Parent v.04/CONFORMAT=no_command
&CREDITS Room Parent v.04=Coded by Jamie. For permission to use email jamie@dj-tech.org.
@DESCRIBE Room Parent v.04=[ansi(hb,[repeat(=,76)])]%r[u(me/inf_desc)]%r[ansi(hb,[repeat(=,76)])]
@set Room Parent v.04/DESCRIBE=no_command visual
@EXITFORMAT Room Parent v.04=[ljust([iter(lcon(me),[switch(##,%#,,[switch(hasflag(##,DARK),0,[switch(type(##),PLAYER,[switch(idle(##),-1,,%r[ansi(hc,[name(##)])])],THING,%r[ansi(c,[name(##)])])])])])],44)][iter(lexits(me),[switch(hasflag(##,DARK),0,{[ansi(c,<)][ansi(hc,[ucstr([extract([fullname(##)],2,1,;)])])][ansi(c,>)][ansi(r,-)][ansi(c,name(##))%r]},{})],)]
@set Room Parent v.04/EXITFORMAT=no_command
&INF_DESC Room Parent v.04=%tThis is the default description for the room parent by Jamie. You can set your own description with the inf_desc attribute. You can customize your top describe border with inf_desc_border_t and the bottom one with inf_desc_border_b. Also you can customize the headers for the contents and exits using inf_contents_header and inf_exits_header. Changing the color that objects and players show up in can be done with the inf_player_color and inf_obj_color. Changing the colors for the exits can be done with inf_exit_c. Further the exit alias color can be set with inf_alias_c and the brackets around the alias with inf_alias_bra.
@dolist [lattr(Room Parent v.04)] credits=@set Room Parent v.04/##=no_command
@set Room Parent v.04/credits=visual
@wait me/10=@pe/silent %#=[ansi(hr,INSTALLATION COMPLETE.)]%r[ansi(hc,Email jamie@dj-tech.org with comments/feedback/questions)]

2001-Dec-22 3:43pm FishHerring73864

This is a good example of the wrong way to put questions up on the FAQ. Huge code-dumps usually don\'t go over well, especially when they\'re mangled into one big unreadable block. Fixing specific broken pieces of code is probably better left to mushes with code-help channels or other resources. What the code is doing instead of what\'s expected isn\'t even mentioned. At least what is expected is.

The idea is to have exits and contents in two columns, with colors in the exit names. There\'s a FAQ entry on both bits of it, and it\'s fairly easy to combine them. Take the format_exit attribute from the colorizing-exits FAQ, and plug it in where the two-columns FAQ gets the exit names.

Examples of good questions: How do I do SOMETHING? What\'s wrong with APPROACH? Why does THIS happen?

2002-Jan-04 9:13pm shawnw

The problems with ## in iter() and @dolist

The problems with ## in iter() and @dolist javelin Sun, 2012-02-12 22:54

Using ## in iter() and @dolist (And #$ in switch()) can be dangerous if not treated with care. The problem is that the ## token is replaced /before/ evaluation of the code, not during, as with %-substitutions. This means that if the current list item that takes the place of ## has anything resembling code in it, it will get evaluated. In badly-written code, this can provide a malicious attacker with the ability to run any functions as the object the iter() is on. Obviously, this is bad.
There are several measures you can take to avoid these security holes. The first is to use itext() instead of ## when the list being itered over might contain arbitrary text and code (The results of things like lnum() and lcon() don\'t usually need this, because numbers and dbrefs are safe). The second is to use escape() or secure() on the list argument, (not around the ##\'s). This will escape or remove the special characters that indicate code as opposed to plain text (Brackets, percent signs, etc.).

2001-Jun-11 7:48pm shawnw

Using ascii2mush and figlet for easy beautification

Using ascii2mush and figlet for easy beautification javelin Sun, 2012-02-12 22:49

If you ever wanted nice, large text, or complex maps on MUSH, and have had a flag day doing it (like me), you might want to take a look at ascii2mush.
Ascii2mush (http://ftp.pennmush.org/Scripts/ascii2mush.pl) is a nifty perl script made by Javelin@M*U*S*H, that converts spaces to %b or to [repeat(%b,number)], escapes "\\"s, and generally makes ascii art and the like display the way you want it to.

To use it, you must have PERL installed. The next steps assume you use *nix, but if you use PERL regularly on another OS, you should be able to figure out how it works.
Download the script, modify the path in the #! line (first line) to the path where perl lives (to find out, type whereis perl), save it, and place it somewhere in your path (or if you are root and want other users to be able to use it, place it in /usr/local/bin for example).

You can now either type ascii2mush <file>, in which case it will convert the contents of <file> to MUSH format, or use pipes to it, like with figlet.

For example, if you want to display \'Hello!\' in big letters in a certain room, you can use figlet (for information on figlet and how to get it, see http://st-www.cs.uiuc.edu/users/chai/figlet.html) in combination with ascii2mush like this: figlet Hello! |ascii2mush, and copy and paste the result to the MUSH. For more information on how to use figlet, read the documents packaged with figlet, available on the above URL, or type \'man figlet\' if it\'s installed.

If you want to create a visual map, you can draw the map in a text file (pico -w map, then draw and save it), and then type ascii2mush map, and it will convert the map to MUSH format.
Ascii2mush can save you a lot of time when creating graphical things on a MUSH, so if you don\'t want to spend a lot of time perfecting your maps etc, I recommend using it.

2001-Apr-01 4:47pm aiviru

Using regrep

Using regrep javelin Sun, 2012-02-12 23:05

I\'ve run into the limit of my knowledge with regrep. I have a \'media article archive\' object containing attributes which are formatted as -
I want to search the attributes for a keyword in <title>. regrepi() looks to be the way to do this
regrepi(<dbref>,ART_*,<what goes here???>
but I can\'t work out what I need as a regexp expression to do the search. I have tried many combinations but simply don\'t know enough about regular expressions to make it work. Regexp experts, please help. (Argon@CM2)

wildgrepi() might be a better choice.

wildgrepi(<dbref>, ART_*, *|*|*%0*|*)


What is &quot;the queue&quot;?

What is &quot;the queue&quot;? javelin Sun, 2012-02-12 22:48

What is "the queue"?

For a probably better answer, see the collaborative book \"Enough to be Dangerous\" on this site.

2012-Feb-10 javelin
In PennMUSH, there are actually 4 kinds of queues that are important in softcode: the player queue, the object queue, the wait queue, and the semaphore queue. Usually people who talk about \"the queue\" mean the object queue.

  • The player queue is a line of commands that have been typed by players directly to the MUSH from their connection. These get their own queue because the MUSH prefers to run commands from this queue when it can, so that it feels more responsive to players\' direct actions.
  • The object queue is a line of commands to be run by objects (anything other than a player typing directly from their connection)
  • The wait queue is a line of commands that are to be run at some time in the future (commands that have been enqueued using @wait =)
  • The semaphore queue is a line of commands that are to be run at some time in the future and are controlled by a semaphore (commands that have been enqueued using @wait me/=)

Here\'s an example of the object queue in operation. Imagine that you\'re in a room with an object like this in it:

POP [#3]: @emit The toast pops!
START [#3]: $start: @emit %N starts the toaster; @tr me/POP

When you type \'start\', the object queues up this command set:

@emit %N starts the toaster; @tr me/POP

along with some information about who %N was at the time.
When this command set is at the front of the queue, the MUSH server executes it, \"Javelin starts the toaster\" is emitted, and the @trigger command is run, which puts the contents of the POP attribute onto the back of the queue.

In the meantime, of course, other things may be ahead of this and run from the queue, but eventually \"@emit The toast pops!\" is at the front of the queue, and is executed.

The @trigger command, @force command, and @switch/@select commands result in a new command-set being queued up. This is why code using these commands can feel slower -- you have to wait until the newly-queued command set is at the front of the queue before it runs. Of course, if speed isn\'t important, using the queue is a good thing -- it lets the MUSH server share its time between commands of all the objects, and reduces overall lag.

2001-Mar-29 6:33pm dunemush

Where can I get a softcoded chargen system?

Where can I get a softcoded chargen system? javelin Sun, 2012-02-12 22:46

Where can I get a softcoded chargen system?

There are few released softcoded chargen systems, as these systems are usually highly specific to the individual MUSH\'s notion of what a "character" should include (stats? skills? virtues and flaws?) and how they should be generated (roll dice? spend points? choose from lists?)

The good news is that there *is* a program that *generates* chargen systems, based on a rather simple specification. It\'s called \'gengen\' and you can try it out online (http://javelin.pennmush.org/gengen.html) and download it if you want to run it locally. It\'s written in perl, and produces output in quickbuild format (quickbuild\'s another perl script that speeds up offline building of areas, and is at http://javelin.pennmush.org/quickbuild.html).

gengen can produce chargen areas that are either linear (you go through them in order) or spoke-topology (you go through the facets in any order), and can create rooms for attributes to be set by dice rolling, point spending, choosing from a list, or entering arbitrary text. gengen-produced chargen systems are functional, but you\'ll often want to use them as a starting point for further customization.

2007-Mar-18 12:41pm dunemush

The Sandbox Globals Project also has a chargen system. See http://sgp.erisian.net/cgen/ for details.

2002-Jan-04 8:49pm shawnw

Which is better: @pemit or think pemit()?

Which is better: @pemit or think pemit()? javelin Sun, 2012-02-12 23:02

Which is better: @pemit or think pemit()?

@pemit foo=bar


think pemit(foo, bar)

The former case, using @pemit, is preferrable. In both cases, the parser has to find the command, and evaluate its argument(s). Using @pemit directly means there is one fewer function to evaluate in the argument than when using think pemit(), and it\'s thus more efficient.
The only times think X() is normally to be preferred over @X is when the function version returns a value and you need to do something with that value. A vendor object, for example, is more likely to use create() than @create so it can easily reference the newly created object by dbref.
Of course, there are also times where X() is the only option (Like when it\'s in an attribute being evaluated by u()). But for action list elements, remember @pemit over think pemit().

2002-May-18 12:36am shawnw

Will there ever be wait(), trigger() or force() functions?

Will there ever be wait(), trigger() or force() functions? javelin Sun, 2012-02-12 22:45

Will there ever be wait(), trigger() or force() functions?

No. The exploits made possible by side-effect functions pale in comparison to what can be done with functions that add commands to the queue. Imagine someone exploiting badly-written code on a wizard object that lets them evaluate arbitrary code as that wizard object. (It happens. A lot. Especially with people who don\'t know how to make iter() safe writing code). They could use it to do a @shutdown, or @nuke most of the database, or other nasty things. This is not desirable.

2001-Mar-28 11:02am shawnw

They could already cause this much damage using the set() function.

I thought the real reason wait(), trigger() and force() won\'t be implemented is that allowing functions to add entries to the queue is very difficult to implement without introducing denial of service vulnerabilities.

2003-Apr-23 7:17am pmak

These functions appear to have been implemented since the original author wrote this. I actually believe that this is not a bad thing since it adds a lot of power. I take the same attitude to mush object security as computer security. I would never intentionally try to do harm myself, but I presume that others will. I personally use regex matching on all commands to ensure safety. I have very little sympathy for wizards who fail to take basic precautions.

2005-Jul-23 6:53am interfecus

Starting up the server

Starting up the server javelin Mon, 2012-02-13 20:10

Questions about getting the server started (after you've compiled it).

My MUSH dies on startup, logs mutter something like 'Illegal compression code length'

My MUSH dies on startup, logs mutter something like 'Illegal compression code length' javelin Mon, 2012-02-13 19:51

My MUSH dies on startup, logs mutter something like 'Illegal compression code length'

This is a known issue with the Huffman compression, but it's nontrivial to fix. It happens in somewhat rare occasions, and only seems to affect MUSHes running on Linux.
While fixing the compression code itself isn't easy, fixing the problem is not too hard: Change compression types.
In the pennmush dir, open options.h in the editor, and find the line that goes '#define COMPRESSION_TYPE'. On that line, change the 1 to something else. Detailed descriptions are above it in the file, but in a pinch, you might want to set it to 4, and if that fails to 0. If it still doesn't work then something else is amiss.
After you've changed options.h, save it, and do a make install. After that, hopefully your MUSH will run again.

2003-Nov-12 9:46am aiviru

My mush doesn't start up and there's an error in the log file like sh: uncompress: command not found'

My mush doesn't start up and there's an error in the log file like sh: uncompress: command not found' javelin Mon, 2012-02-13 20:02

Some Linux distributions (Notably the last few releases of Redhat, and apparently Debian as well) don't include the compress and uncompress programs that Penn uses by default for compressing the database file. You can install the proper package (Probably called something like 'compress' or 'ncompress'), or just change the mush config file to use another compression programs like gzip.

2003-Apr-29 8:04pm shawnw

When I restart, I see weird 'b.found outdb' and similar messages

When I restart, I see weird 'b.found outdb' and similar messages javelin Mon, 2012-02-13 19:48

When I restart, I see weird 'b.found outdb' and similar messages

This happens on linux systems when mush.cnf has been edited in a DOS/Windows
editor and contains dos-style line breaks (CRLF) rather than unix line breaks
(LF alone).
Edit mush.cnf in an editor that'll show you if you have dos linebreaks
(I use vim -b or vi -b) and remove them, using one of the procedures for
converting dos databases to linux databases.

2001-Oct-16 5:36pm dunemush