@desc
) and have set the four messages
for picking it up (@succ
and @osucc
) and
dropping it (@drop
and @odrop
).
While these are not important as fas as the action is concerned, it is
always good practice to set these five fields, and, if you have locked
the object (with @lock
) you should also set the failure
text (with @fail
and @ofail
).
Now you are ready to create your action. You want to be able to
shoot
your Plush SuperSoaker. Since a Plush SuperSoaker would not
actually shoot water, you just want a simple message printed to the
screen every time you shoot
it.
First, create your action, and attach it. Attaching an action defines where the action belongs; it is not the same as linking an object, which will be discussed shortly. The creation step attaches the action to its object at the same time. Type the following:
@action shoot=supersoaker
This costs one penny. If you now examine your SuperSoaker you will see
that it has an action shoot
attached to it.
Try it. Just type shoot
while holding the SuperSoaker or while it
is in the same room as you.
It didn't work, did it? The reason for this is that the action was not linked. The action will not succeed because the Muck doesn't know what to do with it. It's very much like having an exit from a room that doesn't lead anywhere. (In fact, it *is* like having an exit from a room that doesn't leave anywhere; actions and exits are the same type of object. We will return to this point later.)
What you need is to link the action to something that does absolutely
nothing. This will satisfy the Muck that the action is linked, and
still ensure that shoot
will do nothing but print a message to the
screen. There is just such a linking destination, called
dummy-for-exits. when you link to it you'll have to refer to it by
its database reference (dbref) of #56
. This number isn't special; it is
just the object number that this simple program is stored under.
Linking an action or exit costs another penny.
Link the action with the following command:
@link shoot=#56
If you try to shoot
now, the action will succeed. But nothing at all
is printed! That's because you haven't set the success messages. Set
some appropriate messages with @succ
and
@osucc
:
@succ shoot=You pull the plush trigger and plush water comes
streaming out everywhere!
and similarly with @osucc
. Now your Plush SuperSoaker is ready to
shoot! Don't forget to set the object's @desc
or
@succ
field to suggest
that the Plush SuperSoaker can shoot
when tou look at it or
pick it up respectively.
explode
option. But there are a few ways you can improve the
SuperSoaker. You may have noticed that before you linked the
shoot
action, trying to perform the action failed. Instead of linking
and setting the @succ
messages (for a success), you could leave the
action unlinked and set the @fail
messages instead (for failure), saving
yourself a whole penny in the process. From the point of view of
another player, the two are indistinguishable. However, you probably
shouldn't do this, since it allows other players to "steal"
your action by linking it themselves. Spend the extra penny and do it right.
Doing this is fine if there is only ever going to be one result of an
action, but say you don't want anybody else to use your Plush
SuperSoaker. You have to lock it so that only you can use the
shoot
action. Use the @lock
command for this:
@lock shoot=me
By doing this, only you can succeed in the shoot
action (you get the
SUCC message) whereas everyone else fails (and gets the FAIL message).
Anybody can still pick up the water pistol though. To stop that from
happening, lock the *object*, not the action, to you.
More room for improvement can be seen if you do the following: drop
the supersoaker, then shoot
while it is on the ground. True to form,
the shooting still happens. It would be more realistic to make shooting
only possible while you are holding the gun. This requires a different
lock on the action:
@lock shoot=supersoaker
This will succeed only if you have the supersoaker in your possession.
By locking both the Plush SuperSoaker and its action, you have made a
safe weapon that only you can pick up or fire.
For a Real Muck Example of this, try the stuffed sheepdog called
Minimax in Ariel's Room (#5160
). He has two actions,
cuddlenhug
and
shake
. They only work if you are holding him.
Another Real Muck Example that shows a lock is the crystal chandelier
in the Palace (#5153
). It can be turned on and off by anyone holding a
trident. Specifically, if something you are holding has the property
_trident:yes
, the lock succeeds. Try setting the property on your own
home-made trident or any other thing you own, or even yourself. Don't
forget to clear the property afterwards. Tridents are dangerous things!
Let's say that you would like a window in your room. Furthermore, you
would like to be able to open it and close it (but only open it when it
is closed and close it when it is opened) and have its present state
reflected in the listing of the room's contents when you do a
look
.
Graphically, you'd like:
+--------+ close +--------+ | | -------------> | | | opened | | closed | | | <------------- | | +--------+ open +--------+where opened and closed are states and
open
and close
are
actions to change the state. (Technically this is not a true toggle
since the actions are different, but if we named them the same then
there would be no perceivable difference between this and a true toggle.
The version presented here is more general and more useful.)
The trick with creating this object is that every state is a separate
object. You actually have two windows, identical in most respects
except that one has the description opened and the other is
closed.
You then create two actions, one per object, and link the actions to the
opposite object. You cannot close an already-closed window because
there is no close
action on the closed window.
This works because linking an action to an object does a fairly strange-sounding thing: The object that the action is linked to is brought to the same place as the object that owns the action, then, the object that owns the action is sent to its home room.
In our case - say the window was already closed - we apply the
open
action, the opened window is brought into the room, and the
closed
window is sent to its home, which is probably the Player Start room
unless you changed it.
The actual steps for creating this window would be:
@create opened window
@create closed window
@action open=closed window
@link open=opened window
@action close=opened window
@link close=opened window
Now drop the closed window into the room and open
it. The opened
window is miraculously teleported from its previous location (you were
holding it) to the room and the closed window is nowhere to be seen. If
you remember the dbref of the closed window (say it was
#2496
), you can
verify that it has gone home by locating it:
where #2496
The Muck will report that the closed window is in the Player Start Room.
Once you have the basic toggle working, you can do a few things to
embellish it. You will have to add descriptions for the two windows,
somehow hinting that you can open
and close
it. You should add
SUCC and OSUCC messages to the two actions, and if you have locked
them at all, FAIL and OFAIL messages too. It is always nice to add
dummy actions (such as an open
action on the already-opened window),
because people are sure to try opening it twice just to see what
happens. Such actions would be simple do-nothing actions as have
already been described.
Another thing you should be aware of is that there is always an
"anti-window" at the Player Start which is in the opposite state to the
one in your room. It's not good manners to clutter up this room, so
don't be surprised if a Wizard hands you your anti-window at some time.
What would be better is to create a "Warehouse" room which only you can
access, and set all these objects to have their home there. For
example, say your warehouse is room #5172
(this is Ariel's Warehouse's
dbref). Set the home of each window with:
@link closed window=#5172
and likewise for the opened window.
For a Real Muck Example of this, try the soft inviting bed in Ariel's
Room (#5160
). Its two states are "unoccupied" and "occupied" and you
can switch between them by the actions bounce
and
arise
. Only one
player can occupy the bed at any time, which you can verify by bouncing
twice on it. Unfortunately, a small problem that shows up with the
bed is that if player A bounces on the bed, player
B can arise from it,
on A's behalf, as it were. The analogy with the window example is one
person opening it and another closing it. Making a bed that is more
realistic (only the bouncer may change its state by arising) would
require a program, which is beyond the abilities of a Builder. You can
alleviate this a bit by careful wording of the actions, and only telling
the bouncer how to arise when she first bounces on it.
+-------+ +-------+ <-------- | | --------------------> | | shoot | empty | reload | 3 | (fails) | | | | +-------+ +-------+ ^ | | shoot shoot | | v +-------+ +-------+ | | | | | 1 | <-------------------- | 2 | | | shoot | | +-------+ +-------+The process is exactly the same as before, except that you now have four Plush SuperSoakers and five actions. Naturally, this starts to cost money; the window would cost 24 pennies, whereas this device would cost 50! Building macros in your Muck client program to set the mundane information (SUCC, OFAIL, DESC, actions, etc.) is quite worthwhile for such objects, if your client will do macros. You would probably also want to make the
reload
action
locked to a room or Plush Water source in a real life situation.
For a Real Muck Example, play with the hat stand in the Palace
(#5153
). It has five states and you can place
or remove
a hat up to
a maximum of four. The hat stand's description changes very slightly at
each state.
To name an example, let's look at the Secluded Beach
(#5120
),
specifically the ramp into the water that leads to Atlantica. This exit
is locked so that female characters can only enter if they are carrying
seashells. Now, it's unreasonable to expect every female character to
carry seashells, so we need a way of giving them seashells just before
they use the exit, then reuse the shells for some other player's use.
(You can actually bypass the shell-getting if it annoys you. There's a
topless
exit which goes the same place and doesn't have a seashell
lock.)
A very small variation on the toggle presented above will suffice. (In
fact there are two subtly different ways of summoning an object.) If
the seashells aren't on the beach, the player can do a
search
in the
room and the single pair of seashells, wherever they are, whoever is
carrying them, will be teleported to the beach. There they can be
picked up and worn while the player enters Atlantica. Since she will
have probably forgotten about them afterwards, it doesn't matter too
much if they disappear without warning once she is in Atlantica.
The search
action is part of the room. That is, it was created
with the command:
@action search=here
The action was then linked to the seashells as normal:
@link search=seashells
What happens when a player search
es is that, as before, the linked-to
object (seashells) is brought to the room. But because a room can't be
sent home like an object, that's all that happens.
As long as only one player wants to use the seashells at once, this method works well.
There is one side-effect of this which you will notice if you list the
room's exits. This action is listed among the exits! Remember that an
action and an exit are the same thing, so the exits
command is just
listing all action/exits belonging to the room. You can suppress the
printing of an action in the exits listing by setting its HAVEN flag.
Do this:
@set search=haven
Another variation on summoning an object works a little better if you
are using one object as the summoner. This method does not require the
summoning to be fixed to a room.
The trick is to create a normal toggle situation as described earlier, but to set the summoning action's STICKY flag. When the action is performed, the usual happens: the linked-to object is brought to the room, but if the action is sticky, the action's source object is not sent home. To set an action's STICKY flag, do this:
@set action=sticky
There are three ways. If you can force a player to pick up the object, you can simply make it sticky, so that when the player drops it, it will go back to its home position. To set an object to be STICKY, type:
@set object=sticky
(Note that sticky actions and sticky objects behave quite differently.)
A simple Real Muck Example is the cute sea slug in the Princess' Hall
(#5156
). You can pick it up and take it anywhere. When you drop it it
slithers back to its home in the hall.
Another way, which doesn't require a player to pick up the object, is to make yet another variation on the toggle. Recall that a toggle will send an object home while teleporting another one here. What would happen if the object you are teleporting here is already here? The net effect would be to send the first object home, and nothing more.
To do this, you'll need an object that isn't going to be moved from this room. It doesn't actually have to be related to the object you want to send home. You can't use the room itself for this purpose. Form an action that will send the object home. Attach it to the object:
@action vanquish=object
Then link the action to some immovable object:
@link vanquish=anchor
Set the SUCC and OSUCC messages, as always, and then try it out with a
simple vanquish
. The object has gone to its home. This technique
will only work if neither object nor anchor can be picked up or moved.
Otherwise unexpected things happen.
As always you should set the object's home to a private warehouse-type building (and you need only have one warehouse, where all your toggle objects are kept).
The safest way of all, with few restrictions, is to turn the sending into a summoning. As far as you are concerned, the object is being sent to your warehouse room. But imagine the situation from someone standing in the warehouse. The action is summoning the object to that person's location.
So, make an action, in your warehouse, and link it to the object you
want to move. It won't be in the warehouse at the time, so you will
have to refer to it by its dbref. This is exactly how you summoned an
object in the previous section. Now, go back to the room where the
object is, and create the dismissal action, attaching it to the object.
The trick is to link this action to the summoning action you made in
your warehouse. As explained in Other Links below, linking to an
action causes the actions to chain, so that the second action is
performed. The object is summoned to the warehouse by this action and,
as far as you are concerned, it has disappeared from your location just
as it should. This method uses one more dbref than the second method,
so to conserve this limited resource you should only use it where
necessary. Also note that summoning and vanquishing an object, while
related, need not be done together at all.
For a Real Muck Example, look at the chest of drawers in the Princess'
Hall (#5156
). When you open
it, some miscellaneous odds and ends pour
out. You can pick them up then drop them (the first method shown here)
or you can put them back
in the drawer (the second method). The @succ
message for both is the same, somewhat hiding the true implementation.
There is a way to make as many different actions as you like and have them do as many things as you like. You can see how it works by noting two things about actions. First, you can have multiple actions with the same name on the same object. Second, if there is an ambiguity, the Muck will favour a success over a failure.
The main caveat is that if there are two possible successes or two possible failures, you have no way of knowing which action will trigger. So you have to be very careful designing your lock functions such that exactly one can ever be true at once.
Imagine you want to create a Change Room, but you want to segregate
the males from the females so that they end up in different rooms
without them having to choose themselves. In fact, to be really
careful (and to emphasise the point), you will need three rooms: one for
people with sex:male
and no sex:female
(the
men); one for people with sex:female
and no sex:male
(the women); and one for everyone else. The last room is needed
because some players (notably guest players) might not have a gender,
and because it is possible to be carrying an object with a
sex
opposite
to your own, so that you may actually pass both a sex:male
and a
sex:female
lock. The division given above is the safest way to do it
and will work for everybody.
You'll need three rooms. You will have to refer to the rooms via their dbrefs, but we'll stick to names here as it makes it clearer. You will also need three exits. Link one to each of the three rooms, and give them exactly the same name. You will have to refer to the exits by their dbrefs too since they are ambiguous.
The task is now to choose proper lock functions. In this case, they would be:
@lock #female exit=sex:female & !sex:male
@lock #male exit=sex:male & !sex:female
@lock #questionable exit=(sex:female & sex:male) | (!sex:female &
!sex:male)
You can try out all possibilities to convince yourself that only one
exit will ever be unlocked at once.
Using this technique, you can create as many actions as you like and
let them perform any link you want. For a Real Muck Example, look at
the blue dress in Ariel's Room (#5160
). It has four locks: one that
triggers when you are not holding the dress; one that triggers if you
are holding the dress and wearing something else (such as Ariel's
seashells); one that triggers if you are holding the dress, not wearing
anything else, male and not female, and one that triggers if you are
holding the dress, not wearing anything else, and female or not male.
These cover all eventualities.
What happens when you have two actions with the same name, and both of them can theoretically succeed? The Muck picks one at random. This is a simple way to make two or more actions happen nondeterministically.
Going back to the Plush SuperSoaker example, say you'd like to make it so
that when you shoot
it, there is a 50% chance that it backfires and
drenches you instead. (We are talking about the non-counting
SuperSoaker from the first section. This is only for the sake of
illustration. The same technique can be used where any action can be
used.) Your first step is to create another shoot
action to go with the
one you already have:
@action shoot=supersoaker
This time you are going to have to work with the action's dbref rather
than its name. Remember the number the Muck returns. You will use it
when you link the action to dummy-for-exits:
@link shoot backfire=#56
Don't forget to describe the action too in its SUCC and OSUCC messages.
(Remember, while you might think that backfiring is a "failure" of
sorts, the Muck must see it as a successful action. Recall
that the Muck doesn't care what text goes with an action.)
Once you've done this, try your new version of shoot
. Half the time
it will backfire, or whatever you set the message to say, and half the
time it will work "normally".
There is nothing about this that limits the actions to two. It is just as easy (though somewhat time-consuming) to have ten different actions, all with the same name.
If you want to have the actions' frequencies anything other than
equal, you will have to use a little more trickery. You can create a
three-to-one frequency ratio by making three "normal"
shoot
s and one
backfire
one. By setting the messages the same for the first three
the player doing the shooting will not know which one is being
triggered. Doing this becomes inefficient (and chews up dbrefs,
of which there are a finite number), so if you want to create
unusually-weighted random actions, investigate other techniques, such
as RUFUS
, available on FDCMuck.
A word of advice: use random actions sparingly. Players don't usually
like having room exits or important actions that only work some of the
time. Try to keep random actions to trivial or humorous situations.
If an action is linked to a program, the program is run. This is only
of real use if you have some Mucker-written program that you are able to
run. You have already done this by linking do-nothing actions to
dummy-for-exits (#56
). The program does nothing, but it is a program
nonetheless.
If an action is linked to another action, it chains the actions. The first action will cause the second action to trigger. In itself this isn't very useful (unless you are being sneaky with locks or something). Linking to actions really comes into its own when you make multiple links. See the following section.
Actions that link to rooms simply transport you to the room. The room must be set LINK_OK for you to be able to make the link.
With this, you can create an action that allows you to go to a room at any time, even if you cannot jump there. To set it up, navigate to the room you want to be able to teleport to. When you are there, create an action and attach it to yourself:
@action goroom=me
Then link the action to the room.
@link goroom=here
Now, wherever you are in the Muck, you can move to this room by simply
typing goroom
. This has the advantage over
home
in that you can create your own OSUCC message to be displayed to the other
people in the room, and that it can take you to any room, not just your
home. It also has the advantage of not sending the objects
you carry to their homes. If you are carrying a toggle item with
several states, none of which actually has its home as you, this is an
important advantage.
Linking to a room is normally how an exit from a room is made. In
fact, since actions and exits are the same, goroom
is in every respect
a portable exit that you carry around with you, the other end of which
always leads to the room you linked it to.
An action that is linked to a person teleports you to the room that the person is in. The same considerations apply as when linking an action to a room, and the person must be JUMP_OK at the time you activate the action.
Let's begin with a simple example of what multiple linking can do. In
the room West of House (#5121
) there is a mailbox. You want to be able
to open the mailbox, to reveal a leaflet. Up to now, you could swap the
mailbox with an open mailbox containing a leaflet, or you could have the
open and close actions bring and dismiss a leaflet without changing the
status of the mailbox at all. What you really want is this:
+----------+ | | +-----> | open box | +----------+ open | | | | closed | ---------+ +----------+ | | | | | mailbox | <----------------------+ close +----------+ | | | +----------+ | | | +-----> | leaflet | | | +----------+The
open
action brings the open box and the leaflet here and sends
the closed mailbox home. Assuming you already have the objects and have
set their home to be your warehouse room, you would do this by:
@action open=#closed mailbox
@link open=#open box;#leaflet
Note that you separate the multiple link destinations with a semicolon.
The close
action is a little more difficult to achieve. You must swap
the open box with the closed box, then send the leaflet home. This can
be done by creating two actions, one being the close
that players use,
and the other being something that no player should ever type. Let's
create the latter action first, and have it swap the two mailboxes:
@action close_2=#open box
@link close_2=#closed mailbox
This action, which we called close_2
in the hope that no one would
ever type that, is just a simple toggle link, just as you've seen
before. The cunning part comes when you create the proper
close
action:
@action close=#leaflet
@link close=#closed mailbox;close_2
The first half of the link sends the leaflet home while bringing the
closed mailbox here. The second half chains the close_2
action, which
sends the open box home while bringing the closed mailbox here. Of
course, the closed mailbox is already here, so you have in effect
swapped two objects for one.
What has been presented here is the "optimised" linkage. You could
just as easily link the open
action to two other actions, one of which
opens the mailbox (swaps the closed mailbox with the open box) and one
of which brings the leaflet here (using the summoning by
action-connected-to-a-room method). It may help to do it this way on
more complex examples.
Multiple linking works with the full range of linkable objects that normal linking does. You can link to any number of objects, actions and programs, but you can only link to one program, room or player. This is because you can only be teleported to one room at once, for obvious reasons, and for efficiency and stack balance reasons in the case of linking to programs.
Using multiple links, you can not only create any combination of summoning and vanquishing objects, you can also run a string of programs, move an object somewhere automatically as you exit a room, or make sure you are carrying a certain object before you enter a room. The possibilities are immense.