Croaker's TinyMUSH Manual
Last update: December 8, 2004
Author: Croaker
Editor: Josh Juran <wanderer@metamage.com>
URL: <http://www.metamage.com/mush/croaker/>
5. Action Lists
Action lists are what make machines in MUSH possible. Simply put, an action list is a string of commands stored in an attribute of an object which are executed after certain conditions are met. These commands run as if they were typed in by the object. Action lists are the "programs" that objects in MUSH run. Each attribute can be considered as, say, a line of a BASIC program. Each attribute can accomplish many things, including triggering itself again, or even rewriting itself or another attribute.
Each action list has to be triggered in some way. The most common action lists are associated with attributes that you are familiar with from MUD. These are ASUCC, AFAIL, ADROP, and AKILL.
5.1. Common action lists: ASUCC, AFAIL, ADROP, and AKILL
In MUD, when an object is successfully "used" (that is, picked up) two things happen. The message stored in the SUCC attribute is sent to the player who picked the object up, and the message stored in OSUCC is displayed to all other players in the room. In MUSH, a third thing occurs, the commands stored in the ASUCC attribute (if there are any) are executed.
As you can probably guess, the commands in AFAIL will be run when someone fails to use an object (tries to pick it up but can't), AKILL will be run if an object is killed, and ADROP will be run if an object is dropped.
The actual structure of an action list is simply a string of commands as you would enter them to perform the desired operation. The commands are separated by a semicolon, ";", and for the most part are executed in the order they were entered (i.e. left to right.) Therefore, an attribute is "programmed" thus:
@attribute object = command1; command2; command3...
There is no need for an "end" statement, execution of the action list stops when the end of the list is reached. Command1 will be executed, and then command2 and so forth. You can clear an attribute by setting it to nothing.
Example: Adrop
@create superball Created. @drop superball = You bounce the superball on the floor. Set. @adrop superball = n;s;n;s;n;s;:stops bouncing and lands at your feet. Set.when dropped, the superball will north and then south several times print out the message that it has stopped, and then terminate execution
drop superball You bounce the superball on the floor. superball goes to the north end of the lab. superball has left. superball goes to the north end of the lab. superball has left. superball goes to the north end of the lab. superball has left. superball stops bouncing and lands at your feet.remember, we don't see the superball come back since it cannot hear
Example: Afail
have the ball print out a message and then go north
@afail superball = :rolls away from %N;n Set.make sure I'll fail when I try to pick it up
@lock superball = me & !me Locked. look Croaker's Robot Lab(#3061R) The robot testing grounds. Contents: superball(#5088) simple ahear machine(#4284) Obvious exits: west east north aus get superball You can't pick that up. superball rolls away from Croaker superball goes to the north end of the lab. superball has left.
Example: Asucc
Set the ball so I can get it again
@unlock superball Unlocked.have the ball page me when it is taken (a good burglar alarm)
@asucc superball = page croaker=someone picked me up! Set. get superball Taken. You sense that superball is looking for you in Croaker someone picked me up!
Example: Akill
Back in section #2, I killed Mocker. He's back for more
From Mocker's perspective Mocker goes back to the robot lab and... sets his akill to send him back to the robot lab from his home to kill me back
@akill me = s; robot lab; kill croaker=100 Set. "Go ahead, make my day! You say "Go ahead, make my day!"My perspective, again...
Mocker says "Go ahead, make my day!" kill mocker = 100 Ow! Hey! What did I ever do to you? Mocker has left. Mocker has arrived.Mocker's akill takes over and brings him back almost immediately
Mocker's perspective, again...
Croaker has killed me! That Jerk! Croaker killed you! Your insurance policy pays 50 pennies. Mocker's room(#3505R) Obvious exits: sNow Mocker's akill acts as autopilot and moves him to the robot lab
Croaker's Workshop This room is entirely white, with a black grid on the walls, ceileing,and floor. It gives you the impression of being in a a room made out of graph paper. The only furniture is a few work benches crowded with various dimensional stabilizers, reality wrenches, foobar manipulators. There are several doors leading in random directions, some of them seem to be leaning against a wall. Obvious exits: Robot Lab North port3 port2 port1 east Croaker's Robot Lab The robot testing grounds. Contents: Croaker Obvious exits: west east north aus You found a penny! Sorry.Revenge is not his...
You'll notice that Mocker could not kill me in a room that I control. Had it been someone other player's room, he could have gone through with his murder plot.
AKILL only takes effect after you are sent home, so you have to go back to where you were if you want an eye for an eye.
5.2. Command Grouping: using the {}
Suppose you want to have an object reprogram itself, and then continue with some operation. The problem you run in to is how to differentiate between the commands you want to store in another attribute and the commands you want this attribute to execute. For example:
@adrop ball = "now you can't get me!; @afail me=:rolls away; north; @lock me = me & !me
The problem is that the ADROP should store the north, not execute it (as it will in its present form.)
To solve this problem, MUSH allows you to defer the execution of some statements by enclosing them in braces (almost universally known as "squiggly brackets.") All commands in the braces are skipped, and if an attribute is set to the contents of a pair of braces the braces will be removed and the commands in them will be stored in the attribute.
Our above example would become:
@adrop ball = "now you can't get me!; @afail me = {:rolls away; north}; @lock me = me & !me
After dropping it, the ball's AFAIL will be set to the contents of the braces.
Example: deferring commands
@create test object Created.have the object rewrite its ADROP after being dropped
@adrop test object=@adrop me={:goes boom!;@destroy me};"If you drop me again, I'll explode! Set. drop test object Dropped. test object says "If you drop me again, I'll explode!" look test object test object(#5666) You see nothing special. Adrop::goes boom!;@destroy me get test object Taken. drop test object Dropped. test object goes boom! You get your 10 penny deposit back for test object.
5.3. Cost of Running a machine
Like most things in the real world, machines in MUSH cost money to run. It costs 1/64 of a penny for each command a robot executes in addition to any costs those commands normally has (i.e. kill or @create.) The reason for this cost is an attempt to keep machines from slowing the system down with unnecessary commands. A machine that sits in a room and says "zootlewurtle" to itself will slowly use up your supply of money, and a machine that repeatedly creates or clones objects will burn up your money faster, and a machine that kills itself repeatedly will drain your penny supply in no time. You should therefore be careful of leaving a runaway machine. Machines that sit around and wait for certain things to happen (like being dropped) will not use any pennies while sitting idle, and are thus economical.