http:// www.metamage.com / mush / croaker / chapter7.html

Croaker's TinyMUSH Manual

Last update: December 8, 2004

Author: Croaker

Editor: Josh Juran <wanderer@metamage.com>

URL: <http://www.metamage.com/mush/croaker/>


7. Commands and Functions for Machines

The commands and functions in this section are generally only helpful when used in machines. These commands allow the machines to wait a period of time before performing actions, a decision making command, and functions to get the date and generate random numbers.

7.1. Delaying Commands with the @wait command

The @wait command can be used to specify a period of time to wait before executing a command. This allows a machine to break up it's execution over a period of time, instead of operating as fast as possible. A machine that wanders from room to room at full tilt is much more annoying and is a greater drain on the system (not to mention your bank account) than one that moves once every few minutes.

The syntax if the @wait command is:

@wait time = command

Where time is the number of seconds to postpone the command, and command is the single command to be executed. Note that only a single command can be postponed by a wait command. Multiple commands must have multiple wait commands associated with them if an entire block of commands is to take place in the future.

While @wait does not cost more than the customary 1/64 of a penny to run, the command does require a "deposit" of 10 pennies which is refunded after the command is run. This is to prevent a huge number of commands to postponed and thus slow down the system. The 10 pennies are refunded after the time elapses and the command runs.

Note that this command (as well as every command in this section) works with players, if for some reason you wish to put off a command for a while.

Example: the @wait command

@create time bomb
Created.

@adrop time bomb = :is set off!; @wait 5 = "tick; @wait 10 = "tick; 
@wait 15 = :blows up in a thunderous roar!; @wait 16 = @destroy me
Set.

drop time bomb
Dropped.
time bomb is set off!
time bomb says "tick"
time bomb says "tick"
time bomb blows up in a thunderous roar!
You get your 10 penny deposit back for time bomb.

The above example shows the manner in which commands have to be scheduled one after the other if they are to occur. You do not have to put events in sequence in an action list (although they tend to make more sense that way.)

Example: @waits out of sequence

@create tik tok
Created.

@adrop tik tok= @wait 5="A; @wait 1="B; @wait 7="C; @wait 6="D; @wait 1="E
Set.

drop tik tok
Dropped.
tik tok says "E"
tik tok says "B"
tik tok says "A"
tik tok says "D"
tik tok says "C"

There are some things you should think about when using the @wait command. It is a good idea to space the events out in time, not schedule them to occur all at once. You are not guaranteed what order commands set to execute at the same time will run. Therefore the closest possible spacing is one second, which is fine for most applications. It is also possible to have a @wait command trigger the object in some manner (like whispering to it, or by using the commands to be covered in the next section.)

Here is a simple example object using the @wait command.

Example Object: Paper Airplane

look paper airplane
paper airplane(#2273)
You see nothing special.
Odrop:throws a paper airplane
Adrop:@wait 5=:flies off north; @wait 6=north; @wait 15=south; @wait 16=
:circles around some more; @wait 50=:flies east; @wait 51=east; @wait
200=west; @wait 201=:circles and lands at %N's feet.

drop paper airplane
Dropped.
paper airplane flies off north
paper airplane goes to the north end of the lab.
paper airplane has left.
paper airplane circles around some more
paper airplane flies east
paper airplane has left.
paper airplane circles and lands at Croaker's feet.

Below is a more complex object, a robot bartender. While the @wait commands here are not necessary for the machine to operate correctly, it does break up its output and give a feel that the machine is actually doing something instead of spitting out lines.

Example Object: Tendomatic

Tendomatic(#2282)
This robotic pot-bellied bar tender is dilligently waiting to take your
order. Tell it to 'pour <drinkname>', where <drinkname> is the name of any
drink you can think of, and it will serve it to you. The special AI system
has been programmed with every possible drink combination. Share and enjoy!
Owner: Croaker Key: *UNLOCKED* Gold Pieces: 1
Ahear:"Right-o, %N, one %1 coming up!;@wait 3=:pulls a glass out of the
cabinet.;@wait 3=@clone #2284;@wait 4=get glass; @wait 6=:expertly pours %1
into the glass.;@wait 6=@name glass=glass of %1;@wait 8="There you go,
%N,enjoy!;@wait 8=give %n=glass of %1;@wait 20= :starts wiping the bar with
a rag and humming, content with another job well done.
Home: Croaker's Bar(#2021R)
Location: Croaker's Bar(#2021R)

And now, its output...

"tendomatic, pour iced tea
You say "tendomatic, pour iced tea"
Tendomatic says "Right-o, Croaker, one iced tea coming up!"
Tendomatic pulls a glass out of the cabinet.
Tendomatic expertly pours iced tea into the glass.
Tendomatic gave you glass of iced tea.
Tendomatic says "There you go, Croaker, enjoy!"
Tendomatic starts wiping the bar with a rag and humming, content with
another job well done.

note that these events take place over a span of about 10-15 seconds, to make things more interesting...]

7.2. Decision making with the @switch command

The @switch is similar to the switch command in the C language. It allows you to match the contents of a variable or a value returned from a function (more on that in a moment) against a number of cases. A case is simply a string (which usually contain wildcards) that is compared to the switch string. If a match occurs the command that follows the case is executed. More than one command can be grouped together for execution by using the braces, {}, to indicate that the commands are to be considered the body of one of the cases. The format of the switch command is:

@switch value = case1, command1, case2, command2, ...

Example:

@ahear foo = @switch %1=*hello*,"Hi there!,*bye*,"Goodbye!

Example: The @switch command

@create switch test
Created.

@listen switch test=*test,*"
Set.

@ahear switch test= @switch %1= *hello*,"Goodbye!,
*goodbye*,"Hello!
Set.

drop switch test
switch test has arrived.
Dropped.

"hey test, hello!
switch test says "Goodbye!"

"test, don't say goodbye
You say "test, don't say goodbye"
switch test says "Hello!"

The method illustrated above answers one of the more often asked questions on MUSH, "how do I get multiple @ahears on one object?" Simply set the LISTEN attribute of the object to "*" and put a @switch statement in the AHEAR attribute with each case testing for the phrases you want to trigger the object.

It is possible to get a "default case" with the switch command, that is, a command that is run if none of the cases matches the switch value. This is handy to give out error messages, or to check for a single value (like the number zero) without having to account for all the other possible values. The syntax for this is:

@switch value = case1, command1, case2, command2, default-command

Example:

@ahear foo = @switch %1 =*hello*,"Hi!,*bye*,"Goodbye!,"I didn't understand that!

7.3. Intro to Functions

Functions in MUSH are special commands which get evaluated and the value they return is substituted for the actual function call. This means that if there is a function in an action list (also known as a "function call"), and that function evaluates to, say, 5, then the function statement will be replaced by the value when the action list is run. The function call is not permanently replaced with its value, mind you. It is replaced in the copy of the action list that will run.

Function calls can be made in one of two ways. If the first word in an argument to a command or another function is followed by parenthesis, that string is checked against the list of function names to determine if this is a function call or not. If it is recognized as a function, then it is evaluated and the function call is replaced by the results. If it is not recognized, then the text passes through unmolested, with no error message. If it is a function call, any text in the argument after the function is ignored. Only the first word in an argument is checked for this.

In those cases where the results of a function are to be concatenated with the surrounding text (i.e. the results of the function call are to be embedded in a string) then the function is surrounded by square brackets, "[]", to indicate that the text inside should be checked for a function call.

Function calls have this syntax:

function name(parameter list)

or

[function name(parameter list)]

where a parameter list is a list of values separated by commas. A function must be called with the exact number of parameters it expects or it will return an error message. For example, if there was a function foo, and it expected three parameters, a call to it might look like this:

foo(21,42,green socks)

Functions are evaluated if they are the first word in a say command, but the single quote and the pose command do not evaluate function calls normally. With these commands, the square brackets must be used to force the function to be evaluated.

7.4. Simple Functions: RAND() and TIME()

The previous section was probably more baffling then helpful, but a few examples with some simple functions should make everything as clear as MUD.

The RAND() function returns a random number. It expects a single parameter which determines the range of the random number. The return value will be between 0 and (range - 1.) Remember, you specify the range (i.e. the number of numbers that are a possible result) not the highest allowable number.

Example: The RAND() function

say rand(4)
You say "2"

say [rand(4)]
You say "0"

say [rand(4)]
You say "3"

"rand(4)
You say "rand(4)"

"[rand(4)]
You say "2"

"[rand(4)]
You say "0"

:rand(4)
Croaker rand(4)

:[rand(4)]
Croaker 1

You'll notice that the single quotes and the pose command ( " and : ) the function was not evaluated.

There are much more productive things to do with the RAND() function than to spout random numbers all day. It can be used in conjunction with the @switch command, as the following example shows.

Example: @switch command and RAND() function

@create random switcher
Created.
@adrop random switcher=@switch rand(4)= 0,"Ouch!, 1,"Boing!, 2,:smashes on
the ground,3,"I'm free!
Set.

drop random
Dropped.
random switcher says "Ouch!"

get random
Taken.

drop random
Dropped.
random switcher says "I'm free!"

get random
Taken.

drop random
Dropped.
random switcher says "I'm free!"

get random
Taken.

drop random
Dropped.
random switcher smashes on the ground

The other function to be introduced in this section is the TIME() function. TIME() will return a string that contains the time and date (remember, though, that the time will be whatever the local time of the machine running MUSH is on, so its time and your local time may differ.) TIME() does not expect any parameters, and will return an error message if you give it one. The parentheses are still required, however.

Example: The TIME() command

"time()
You say "Fri Jul 27 12:23:15 1990"

One could use the time command in a number of ambitious ways, such as to schedule the operations of a machine on a hour to hour or even day-to- day basis. A simpler use follows.

Example: the @switch command and TIME()

@create Day Teller
Created.

@listen day=*what day*
Set.

@ahear day=@switch time()=*mon*,{"today is Monday, N}, *tue* ,{"today is
Tuesday,%N}, *wed*, {"today is Wednesday, %N}, *th* ,{"today is Thursday,
%N}, *fri*, {"today is Friday, %N}, *sat*, {"today is Saturday, %N}, *sun*,
{"today is Sunday, %N}
Set.

drop day
Day Teller has arrived.
Dropped.

"what day is it?
You say "what day is it?"
Day Teller says "today is Friday, Croaker"


Last updated December 10, 2004 by Josh Juran
Metamage Labs