This is an example of building on EMuck using an example of reasonable complexity. This example demonstrates how to save "states" within objects.
First, some preliminaries. We will be showing examples of things you should type, and the responses that you (should) get in return. These (should) be offset in your browser as follows:
say I just typed this
You say, "I just typed this"
The first line in this example should appear darker (emboldened) to indicate that it was something that YOU are expected to type. The second line should be a bit lighter than the previous line, indicating that this is a response from the game server. If your browser supports style sheets, the above example should be put into a "box" as well as being offset from the text.
Second, most of these commands for creating objects, rooms, and actions are available only to Builders, so you must have your BUILDER bit before you can run this tutorial. Check out EMuck's policies on building for information on how to become a builder.
Our example is a wind-up toy. The basic things that a wind-up toy does is get wound, and move until it winds down.
First, let's create a couple of objects to work with:
@create Generic Wind-Up Duck1
Generic Wind-up Duck1 created with number 16475.
@create Generic Wind-Up Duck2
Generic Wind-up Duck1 created with number 16476.
Note that the numbers you receive if you type these commands will almost assuredly be different than the ones you see in the example above.
When trying to access objects, the EMuck parser allows you to refer to a unique word within the object's name. In this example, we can refer to these objects as Duck1, and Duck2, respectively. If you have other objects in your inventory that clash with these names, you may want to use a slightly different and more unique name.
You can see these new objects in your inventory:
inv
Generic Wind-up Duck2(#16476)
Generic Wind-up Duck1(#16475)
You have 119 tickets.
You may have other objects in your inventory; we're just interested in the ducks. The inventory command also tells you how many tickets you have. You should keep track of these; building costs tickets on EMuck (10 tickets each to build objects, one ticket for each action, and one ticket to link your actions). This tutorial will create two objects, four actions, and one room for a total of 38 tickets (10 tickets for each object, 2 tickets for each action and its destination link, and 10 tickets for the room).
You may be asking why we have two ducks, if we are making a single toy. The answer is that we wish for our toy to have "states," which indicate its current state of operation. For this example, we will use Duck1 to represent a toy duck that hasn't been wound-up. Duck2 will represent a toy duck that is fully wound. Note that both objects represent the SAME duck, but at different times of its "life."
Let's set some descriptions on each of these ducks to show their states. While we are at it, let's create a couple of drop messages as well.
@desc duck1=You see a wind-up duck that needs winding.
Description set.
@desc duck2=You see a wind-up duck that is fully wound.
Description set.
@drop duck1=You drop an unwound duck onto the floor. Ker-PLUNK!
Message set.
@drop duck2=You drop a fully-wound duck onto the floor. QUACK!
Message set.
Next, let's create a storage room for your ducks. Since these two ducks are really two states for a single duck, you want a place to store the state that isn't being used. So, we create a room to hold the ducks. This room can be any room, but it is best if you don't have any links into a room (what is known as a "floating room."). If you have many objects that are similar to your duck, you can use the same room for all of them -- you don't need a separate room for each one.
@dig Place for Sleeping Ducks
Place for Sleeping Ducks created with room number 16481, parent 0.
@link duck1=#16481
Home set.
@link duck2=#16481
Home set.
Now, we need some actions for our ducks. We will want to have an action to wind up the duck, and another one to start it walking. We will call these actions "wind duck" and "start duck" and give them aliases of "wind" and "start."
@action wind duck;wind;wd1=duck1
Action created with number 16477 and attached.
@action wind duck;wind;wd2=duck2
Action created with number 16478 and attached.
@action start duck;start;sd1=duck1
Action created with number 16479 and attached.
@action start duck;start;sd2=duck2
Action created with number 16480 and attached.
You will notice that the names for the actions are separated by semi-colons (;). This allows you to specify different action names that will do the same thing. You will notice that each of these actions have three (count 'em!) names. The third name (wd1, wd2, sd1, and sd2) are used to allow you to uniquely refer to each action without having to remember the actions dbref number.
Now, we come to the tricky part! We need to have something happen when you "wind" and "start" each of your ducks. We will use the "wd#" and "sd#" aliases to make sure we specify the proper actions for each of these commands:
@link wd1=duck2
Linked to Generic Wind-up Duck2(#16476).
@succ wd1=You wind up the duck. It looks like it wants to 'start' going.
Message set.
@osucc wd1=winds up the duck.
Message set.
@link wd2=$null
Linked to dummy-for-exits(#56FHL).
@succ wd2=You cannot wind up the duck any more!
Message set.
@osucc wd2=tries to over-wind the duck!
Message set.
@link sd1=$null
Linked to dummy-for-exits(#56FHL).
@succ sd1=You try to start up the duck but it isn't wound up!
Message set.
@osucc sd1=tries to start a duck that isn't wound up.
Message set.
@link sd2=duck1
Linked to Generic Wind-up Duck1(#16475).
@succ sd2=You start up the duck. It walks, flaps its wings, and stops.
Message set.
@osucc sd2=starts up the duck. QUACK! QUACK! QUACK! It stops.
Message set.
What did we do here? Let's take it step by step.
We first @LINK wd1 to Duck2. This is a "fetch" command. If you have an action on an object linked to a second object, the second object will "replace" the first object in its location and the first object will go to its HOME. Then, we @LINK wd2 to $null, which is a special program (dummy-for-exits) that does nothing... it just allows you to display the @SUCC/@SUCC messages for your action. This message indicates that you cannot wind up the duck any more.
Next, we do the same thing in reverse with sd1... we @LINK it to $null and give it a message that indicates that you cannot start up the duck without winding it. We link sd2 to fetch Duck1, replacing Duck2 which is sent to its HOME.
Let's try it. Since both of the ducks are in our inventory, we will start by typing "wd1" to wind up Duck1:
wd1
You wind up the duck. It looks like it wants to 'start' going.
inv
Generic Wind-up Duck2(#16476)
You have 91 tickets.
Do you notice that Duck1 is no longer in your inventory? Where is it? Well, since we remember that its dbref is #16475, we can simply use the @LOCATE program to find it:
@locate #16475
[Generic Wind-up Duck1(#16475)] is located in Place for Sleeping Ducks(#16481R).
Notice that Duck1 is now in our storage room (second line of the response).
We still have Duck2 in our inventory, so let's look at it and try winding it up. Since Duck1 is in its HOME, and not in our inventory, we can use the generic names "duck" and "wind" and know that these will only refer to Duck2 and the "wind" action on that duck:
look duck
You see a wind-up duck that is fully wound.
wind duck
You cannot wind up the duck any more!
This all makes sense... Duck2 is fully wound, so you cannot wind it up any more. So, let's "start" it up...
start duck
You start up the duck. It walks, flaps its wings, and stops.
look duck
You see a wind-up duck that needs winding.
start duck
You try to start up the duck but it isn't wound up!
We started up the duck, and we got the appropriate responses. When we look at it, we see that it is no longer wound up. Indeed, if we try to "start" it again, it tells us so!
OK. Let's put the finishing touches on our ducks:
inv
Generic Wind-up Duck1(#16475)
You have 91 tickets.
@lock duck1=me
Locked.
@fail duck1=You try to pick up the duck and it >>QUACKS<< at you!
Message set.
@name duck1=Generic Wind-up Duck
Name set
wind
You wind up the duck. It looks like it wants to 'start' going.
@lock duck2=me
Locked.
@fail duck2=You try to pick up the duck and it >>QUACKS<< at you!
Message set.
@name duck2=Generic Wind-up Duck
Name set
We renamed both of our ducks the same, so they now appear to be the same object. You cannot tell the difference between them unless you look at them. The effect is that the "wind" and "start" commands will switch between the two ducks, depending on their current state. We've also @LOCK'ed the ducks so that only you can pick them up (to keep people from stealing your work!) -- this is completely optional. Since we @LOCK'ed the duck, we put an appropriate @FAIL message to tell people trying to pick it up that the duck doesn't want to be bothered.
All that remains is for us to find a suitable place to drop your duck and let people have fun playing with it.
I admit that this is a pretty lame example, but it shows how simple building commands can be used together to provide interesting effects. You can probably adapt this for other uses on EMuck.
Further building tutorials will build upon this idea to show how you can achieve even more interesting effects.