[MUD-Dev] Macro languages

Caliban Tiresias Darklock caliban at darklock.com
Tue May 18 02:33:23 CEST 1999


On 03:00 AM 5/18/99 +0200, I personally witnessed Ola Fosheim Gr=F8stad
jumping up to say:
>
>I don't really think one need to make such macro programming very clever.=
 If
>aiming for the average user, then one probably should avoid difficult
>conditional structures and such.  Ok, that would be another one of the many
>I-have-always-wanted-to-make-this projects which I will never do.

This is the macro language Ultimate Universe uses. I'm including it
primarily as food for consideration in terms of what users demand in a
macro language; the entire TML series was created wholly in response to
player requests. This is one of the reasons it's such a mess... it was
accreted rather than designed. ;)

This may be a little hard to catch on to, since most of you aren't familiar
with the UU commands and a full coverage of them is beyond the scope of
this post. There is a need to know that a ship carries several "standard"
items, and then several "specialty" items -- the latter purchased from
ports around the universe which carry a total of a little more than 500
different types of items. The specialty items are generally called
"devices". The major commands I'll use in these examples are "scan",
"move", and "port". Scan allows you to look at an adjacent sector to see
what's in it; move takes you to that sector; and port allows you to dock at
a spaceport in order to buy and sell commodities in much the same way most
MUDs make you run around selling the weapons you pick up.

The basic idea is reasonably simple; you stick a bunch of commands
together, using a semicolon to indicate the border between commands. So for
example, M;125;P would mean (M)ove to sector (125) and then (P)ort. There
are about two hundred single-letter context-sensitive commands. So, for
example, C;S (computer; scan) was not the same as S (scan). The former can
scan any unoccupied sector, while the latter can only scan a sector
physically connected to your current location. To make matters worse, C-
turns color off and C+ turns it on -- complicating the command parsing
sequence. To toggle color, you would use C;C -- computer, color. Annoying,
eh? ;)

ALL prompts are handled straight out of the command sequence. So when
entering W gives you a menu of three choices, you can enter your choice
immediately after that -- W;1 -- and when that offers you a second and
third choice, you enter those likewise. The semicolon is really shorthand
for "enter".=20

Following this, we have a great number of substitutions, the most common=
 being:

 %1 Request Input from Captain       %2 =3D Sector you were last in.

So if your macro was M;%1;P you would (M)ove to a sector which you're
prompted for and then (P)ort. Since you will often find two ports selling
reciprocal items, each selling something the other is buying, you could use
M;%2;P over and over again to go back and forth between them. These are
supplemented by:

 %3 =3D Current Sector                 %4 =3D last input to %1 or %8.

So if you were to send a radio message that said "I'm in sector %3" and you
were in sector 12, the %3 would be replaced. (There was once a challenge in
the documentation to find a meaningful use for this. I found one around
1994-95, but it uses some later features which I haven't gotten into yet.)
Since it's common to use a prompted value repeatedly, %4 allows you to use
it again later. So to scan a sector and then move to it, you would use
S;%1;M;%4 -- not very useful, really.

 %5 =3D %1 plus one                    %6 =3D Counter value.=20

The %5 allows sequential scans. S;%5 will increment your last %1 value, so
using it repeatedly keeps raising the value of the %1 value.

The counter is a hideous special case. It allows you to set up
conditionals, and to do complex add/subtract operations:

 %#     Displays Counter Value on Command Line
 %#x    Set counter to x
 %#-x   Subtract x from Counter
 %#+x   add x to Counter
 %#>x   Do if counter is greater than x
 %#<x   Do if counter is less than x
 %#=3Dx   Do if counter equals x

 %:          terminate branch (end if block)
 %^          Else statement
 %!          Terminate macro immediately

With these, you could do terrible hard-to-read things like
%6>10;S;%6;%^;M;%6;%:;%#-10 -- if the counter is more than ten, scan the
sector, else move to the sector, and always subtract ten from the counter.=
=20

Note also that for %#<=3D5;X you had to use %#>5;%^;X because there was no <=
=3D
operator. And it gets worse.

 %-devnum    if device exists skip to %:
 %+devnum    if device does not exist skip to %:

Using these, you can determine what exists in your inventory. You can test
for any device by number. So you can say, for example,
%-125;W;1;10;1;%:;M;10; which would use a (W)arp device of type (1) to make
a warp to sector (10) in warp slot (1) if you didn't have device 125 (the
autopilot). Following this, you move to sector 10 -- if you have the
autopilot, you can get there without making a warp first, but if you don't
you just made one.

The major bug in this is that the command is documented and *operates* in
complete ignorance of the %^ code. So changing this to
%-125;W;1;10;1;%^;[any commands];%:;M;10; will NEVER EXECUTE the commands
in the 'else' block.=20

 %7 Value of Last Aware              %8 Alternative to %1.=20

"Aware" devices hold the value of various things on your ship. For example,
you might have the "Attack Drone Aware" device, which keeps track of the
number of attack drones on your ship. In yet another bad method, you would
use the device, and then %7 would include the number of attack drones on
the ship. Until you used a different "Aware" device... which would change
the meaning of your macros. Bad. ;)

%8 was never documented clearly enough for my taste. There is one
fundamental difference in how it works; %1 takes input and sticks it in the
place of the code. %8 just takes input. So while M;%1 expands to
M;(whatever you type at the prompt), M;%8 expands to M; and does nothing at
all with the value you just typed. So %1 could be functionally replaced
with %8;%4 if you were weird. This was useful to prompt for input at the
front of the macro, then execute a whole bunch of commands which would use
your input much later.=20

 %?          ? =3D Goto Macro A-Z=20

This caused some confusion. It means "goto" in the computer sense: it never
comes back. This meant loops were pretty braindead; you could do
%#<2500;M;%6;%#+1;%N in macro N to loop through 2500 sectors starting at
the current counter value. However, if you wanted to start at sector 1, you
had to do this:

   Macro A - %#1;%B
   Macro B - %#<2500;M;%6;%#+1;%B

This functionality was later supplemented by

 %?*    Gosub Macro ?               %*    Return from Last Gosub
 %*-    Clear Last Gosub tag        %**   Clear ALL Gosub Tags
 .      Global Comment

These were included only in the final release (and, I might note, were my
idea -- although I didn't like the way they got implemented), so weren't
very heavily tested. Probably very buggy. Definitely messy. So for example,
%A* would execute macro A until it came to %* or %*- which would either
return or wipe out the possibility of return, respectively. You could,
obviously, do several gosubs... but the stack was of limited size, thus the
%*- option.=20

 .      Global Comment

No one ever used this to my knowledge. It seems sort of stupid.

 %)     Display On                  %(    Display Off

Spam control, and speed enhancement since obviously your commands will run
a bit faster if the computer doesn't have to send you output. Usable ONLY
IN MACROS; whenever you're asked for input -- i.e. the input buffer is
empty -- the display is turned on. Nice safety net. Another good way to use
%8; you stick %8 up front, take input, and then %( for the rest of the
macro. When the macro ends, the display is turned back on.=20

%), incidentally, was rarely used. Sometimes people would do something like
%#<%5;%);%#;%(;%#+100;%: in place of %5 during the middle of a long loop;
this would turn the display on long enough to display the counter every 100
times through the loop.=20

As you can see from the above, this thing *looks* several orders of
magnitude worse than MUSHcode. ;)

I'm going to redesign in the next version, not this one. Right now, I want
everything to be perfectly compatible with the older versions for ease of
migration. I'll fix things in v3; 2.5 is just a straight port.

-----
| Caliban Tiresias Darklock            caliban at darklock.com=20
| Darklock Communications          http://www.darklock.com/=20
| U L T I M A T E   U N I V E R S E   I S   N O T   D E A D=20
| 774577496C6C6E457645727355626D4974H       -=3DCABAL::3146=3D-=20


_______________________________________________
MUD-Dev maillist  -  MUD-Dev at kanga.nu
http://www.kanga.nu/lists/listinfo/mud-dev




More information about the mud-dev-archive mailing list