mprogs

July 22, 2005

MPROG Tutorial

I get into the meanest, nastiest frame of mind I can manage, and I write the nastiest (testing) code I can think of. Then I turn around and embed that in even nastier constructions that are nearly obscene.

Donald Knuth

The tutorials on MPROGs are more or less complete. Code testing resulting from this has squished a good many obfuscated bugs.

It is important to remember that mobs, objects and rooms see the world from slightly different perspectives, so the $ codes may vary in their output slightly when run by different entities. Please test your programs with the object/room/mob that will be running it.


1. An introduction to *progs: The basics

2. Creating a simple mprog
3. Triggers: Setting the prog loose on the world
4. Mob commands
5. Control logic waltz - IF then ELSE then ENDIF


An important note on the order of prog execution

Mprogs are always fired in this order:
Room
Mob
Object

So if you have a speech trigger on all three, the room will react first, then the mob, then the object.

I have added some validation code so that if an item/mob is purged/removed from play whilst it's running (by itself or another prog), it's code will no longer be executed, avoiding unfortunate crashes and hangups.

Scrawled illegibly by Meathe at 04:08 PM

mprogs

July 20, 2005

Control logic waltz - IF then ELSE then ENDIF

Logic, like whiskey, loses its beneficial effect when taken in too large quantities.

Lord Dunsany

The mprog interpretter is a fussy little beast, and if the code isn't precisely how it expects it, your mprog will not run how you expect it to.

IF statements often throw people, as the syntax is not entirely consistant. Every IF needs to be partnered up with its ENDIF, or the mud will complain. If you do use an ELSE, ensure it's between the IF and the ENDIF and not outside. You do need to keep track of how many you've used, in particular when you nest IF statements (stack one inside another).

The basic flow logic of the if command is (though this is not the syntax):
IF (the condition) is true
then do this code
ELSE
do this code
ENDIF

Rot being rot, things are not quite so simple, and in this case the (condition) varies quite a bit depending on what you wish to test.

Before introducing all of the options and things you can do these truth tests on, to begin with, lets take some very simple cases. We want our greeting goblin from before to only greet people under level 15, so we need a way to compare the character's level to a certain value. Happily, IF level compares the level of a character to a number. Operators determine what kind of comparison will be performed (equal to, less than, etc).

Here is the complete list of operators, with a few examples.


OpMeaningCode exampleExplanation
== is equal to, matches IF level $n == 15 (If the character is level 15)
!= Not Equal toIF level $n != 101 (If the character is not hero level)
> Greater thanIF level $n > 101 (If the character is a higher level than 101)
< Less thanIF level $n < 102 (If the character is below level 102)
>= Greater than or equal toIF level $n >= 102 (If the character is level 102 or greater)
<= Less than or equal toIF level $n <= 101 (If the character is level 101 or below)

So we can finally add some smarts to the greeting goblin, and he can now determine for himself who he wants to talk to, with the code looking like this:


IF level $n <= 15
say Hello, little man thing.
ENDIF

If, however, you want it to laugh at everyone over level 15 as well, you need the else statement. The else statement is still part of the IF, it needs to be nestled between the IF and ENDIF


IF level $n <= 15
say Hello there, newbie.
ELSE
snicker $n
ENDIF

This also means the goblin will laugh at immortals, which does not bode well for its survival.

To extend the program above further, to laugh at everyone over level 15 but not immortals, you have to nest one if statements inside the other. This can be hard to follow, as an aid, the if statements are colour coded. You will see that the first endif closed the most recent if statement.


IF level $n <= 15
say Hello there, newbie.
ELSE
IF level $n >= 102
say Deus ex machina!
ELSE
snicker $n
ENDIF

say Perhaps you should reroll if you want me to talk to you?
ENDIF

There are three other ways to control the execution of mprogs, and they are BREAK, OR and AND. BREAK very simply stops the current mprog running in its tracks. It bails out. This can be useful if you just want a program to exclude certain people.


IF level $n <= 15
BREAK
ENDIF
....

The code above will bail out if the target is under level 16, or continue if they are 16 or over.

OR and AND are used in very similar ways and are extended parts of the IF statement. Their syntax is the same as an IF statement, and they must immediately follows the line with the IF.


IF (condition 1)
AND (condition 2)
[some code]
ENDIF

Both conditions must be true for the code to run.

If you wanted to test if an object had a vnum between 100 and 200 (from the Feline village), you'd have to nest two if statements like this:


IF vnum $o >= 100
IF vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF
ENDIF

Which works perfectly well, but looks a little messy. Using the AND statement, you can eliminate one of the IF/ENDIF pairs.

IF vnum $o >= 100
AND vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF

The OR statement is very much the same, though more useful. At least one condition must be true for the code to execute. Without an OR statement, the code can be repetitive, and quickly becomes nightmarish if you want to add an ELSE.

IF objtype $o wand
SAY Yessir, staves and wands, that's what I buy.
ELSE
IF objtype $o staff
SAY Yessir, staves and wands, that's what I buy.
ELSE
SAY Nosir, I don't buy those.
ENDIF
ENDIF

However, with the OR statement, it's quite simple to add an ELSE statement.

IF objtype $o wand
OR objtype $o staff
SAY Yessir, staves and wands, that's what I buy.
ELSE
SAY Nosir, I don't buy those.
ENDIF

The table below contains all the conditions that can be tested, with a short definition and example for each one.

IF … Argument Definition/Code
Rand 0 to 99 [example] Percentage chance of being true.

[definition]
IF rand 50
SAY Heads!
ELSE
SAY Tails!
ENDIF

Objhere <name/vnum> [example] Is the object (by vnum or name) in the room? Note: The object needs to be on the floor. It will not detect objects that are carried or in pits/containers. If you use a name and not a vnum, use one word only , do not use ' marks

[definition]
IF objhere 21298
SAY That is one powerful weapon there!
GET ultimate
WEAR ultimate
CACKLE
ENDIF

Mobexists <name> [example] Does a mob or PC with this name exist anywhere? Note: One word only , do not use ' marks'

[definition]
IF mobexists whitewhale
SAY So ye seek the white whale. This be luck, lad. Call me Ishmael.
ELSE
SAY Corsets and soap, lad. Corsets and soap.
ENDIF

Mobhere <name/vnum> [example] Is the mob (by vnum or name) or PC (by name) in the room. Note: If you use a name and not a vnum, use one word only , do not use ' marks

[definition]
IF mobhere whitewhale
SAY Thar she blows!
ELSE
SAY Back to the crows nest, lad.
ENDIF

Objexists <name> [example] Does the object with this name exist anywhere? Note: One word only , do not use ' marks'

[definition]
IF objexists 21298
SAY Yes, there is an ultimate weapon. Somewhere.
ENDIF

People Op. <num> [example] Compares the number to the count of visible NPCs/PCs in the room (always excludes the mob running the prog)

[definition]
IF people == 4
SAY Four people, for I never count myself.
ENDIF

Players Op. <num> [example] Compares the number to the count of visible PCs in the room

[definition]
IF players > 1
SAY You know what they say, two's company.
ENDIF

Mobs Op. <num> [example] Compares the number to the count of visible NPCs in the room (always excludes the mob running the prog)

[definition]
IF mobs == 4
SAY We could form a quintet!
ENDIF

Clones Op. <num> [example] Compares the number to the count of visible NPCs with the same vnum as the mob running the program (always excludes the mob running the prog)

[definition]
IF clones == 2
SAY We are now three.
ENDIF

Order Op. [example]

Researching

[definition]

Hour Op. <num> [example] Compares the number to the current hour (0=midnight to 23=11pm)

[definition]
IF hour == 0
SAY It's midnight and all's well that ends well. Go to bed already you slackers.
ENDIF
IF hour == 1
SAY It's 1 A.M. on the streets of Kjeldoran and the rats are out, grab yer slingshots and stones.
ENDIF
IF hour == 2
SAY It's 2 A.M. and the thieves are culling the unwary, step lively, do not tary.
ENDIF
IF hour == 23
SAY It's 11 P.M. and the cats are serenading each other from the fences, throw a shoe.
ENDIF

Ispc $_ [example] Is $_ a player?

[definition]
IF ispc $n
SAY You're not like the other mobs.
ENDIF

Isnpc $_ [example] Is $_ a mob?

[definition]
IF isnpc $n
SAY You're just like all the other mobs.
ENDIF

Isgood $_ [example] Is $_ good? (alignment 350 or over)

[definition]
IF isgood $n
SAY It is not enough to have a good mind; the main thing is to use it well.
ENDIF

Isevil $_ [example] Is $_ evil? (alignment -350 or less)

[definition]
IF isevil $n
SAY Work is a necessary evil to be avoided.
ENDIF

Isneutral $_ [example] Is $_ neutral? (alignment between 350 and -350)

[definition]
IF isneutral $n
SAY In truth, the world is neither with us or against us; it is but raw material in our hands, and can be heaven or hell according to what we are.
ENDIF

Isimmort $_ [example] Is $_ an immortal? (Level 102 or above)

[definition]
IF isimmort $n
SAY Before me things create were none, save things
SAY Eternal, and eternal I shall endure.
ENDIF

Ischarm $_ [example] Is $_ charmed?

[definition]
IF ischarm $n
SAY All charming people have something to conceal.
ENDIF

Isfollow $_ [example] Is $_ following anyone?

[definition]
IF isfollow $n
SAY All Now far ahead the Road has gone. And you must follow.
ENDIF

Isactive $_ [example] Is $_ in a position other than sleeping (awake, sitting, resting, standing, stunned)

[definition]
IF isactive $n
SAY You can trouble me for a warm glass of shut-the-hell-up. Now, you will go to sleep or I will put you to sleep. Check out the name tag. You're in my world now.
MOB FORCE $n sleep
ENDIF

Isdelay $_ [example] Does $_ have a delayed mprog pending? (see MOB DELAY and addmprog)

[definition]
IF isdelay $i
SAY You know, I don't think I'll do that anymore.
MOB CANCEL
ENDIF

Isvisible $_ [example] Is $_ visible to the mob?

[definition]
IF isvisible $n
SAY I can see you!
ELSE
SAY Damnit, I know you're here somewhere.
ENDIF

Hastarget $_ [example] Does $_ remember someone? (used with MOB REMEMBER)

[definition]
IF hastarget $i
SAY Yes, I remember $q.
ENDIF

Istarget $_ $_ [example] Is $_ the mob's target? (IF istarget $n would reveal if the mob remembers the one who triggers the mprog)

[definition]
IF istarget $n
SAY $Q! Of course I remember you.
ELSE
SAY Yes, of course. We met…
COUGH
ENDIF

Exists $_ [example]

Not working

This command is redundant, as there is IF objexists and IF mobexists.

[definition]

Affected $_ <spell> [example] Is $_ affected by the spell specified?

[definition]
IF affected $n bless
SAY You are truly blest.
ENDIF

Imm $_ <imm> [example] Is $_ immune to <imm>? (Only one immunity may be checked at a time)

[definition]
IF imm $n fire
SAY I hate you hot weather people.
ELSE
SAY Flame on!
MOB CAST flamestrike $n
ENDIF

Act $_ <flag> [example] Does $_ have the act flag specified? Act flags can be seen in medit with ? Act

[definition]
IF act $n aggressive
SAY Fiesty little one, aren't we.
ENDIF

Off $_ <flag> [example] Does $_ have the offensive flag specified? Off flags can be seen in medit with ? off

[definition]
IF off $n area_attack
SAY I bet you could flatten the whole room.
ENDIF

Carries $_ <name/vnum> [example] Is $_ carrying the object referred to by name or vnum?

[definition]
IF carries $n 59
SAY My pocket watch! The time! I must go. Tea party.
ENDIF

Wears $_ <name/vnum> [example] Is $_ wearing the object referred to by name or vnum?

[definition]
IF wears $n ultimate
SAY Mind you keep the sharp end of that away from me.
ENDIF

Has $_ <type> [example] Does $_ have an item of that type?

[definition]
IF has $n drinkcontainer
SAY Ye wouldn't have any rum in that there bottle for an old sea dog, would ye?
ENDIF

Uses $_ <type> [example] Is $_ wearing an item of that type? (armor/sword/etc) Note: IF wears is for specific items (by vnum/name)

[definition]
IF uses $n armor
SAY I see you have some armour already. But none so fine as my wares!
ENDIF

Name $_ <name> [example] Do $_ and the name match? Note: The name must be typed in - you cannot use a second $_ value.

[definition]
IF name $n Meathe
SAY Trust not my reading nor my observations,
SAY Which with experimental seal doth warrant
PONDER
SAY Much ado about nothing, I think.
ENDIF

Pos $_ <pos> [example] Is $_ in the position of <pos>? (standing, sleeping, resting, etc)

[definition]
IF hastarget $i
MOB FORGET $q
ENDIF
MOB REMEMBER $r
IF pos $q sleeping
SAY Ah, the children of the night. What beautiful music they make.
MOB ECHOAROUND $q $i plunges $l fangs into the bare neck of $q.
MOB ECHOAT $q You feel a sudden warmness, followed quickly by a chill you cannot explain.
MOB DAMAGE $q 1000 3000 lethal
ENDIF

Clan $_ <clan> [example] Is $_ in this clan?

[definition]
IF clan $n tabernacle
SAY Welcome to the narthex, friend.
ELSE
MOB ZECHO $I's screams echo through the halls. '{rAlarums! Divers alarums!{x'
MOB KILL $n
ENDIF

Race $_ <race> [example] Is $_ of this race?

[definition]
IF race $n seal
SAY Now you just slipped that one in. There isn't a seal race.
ELSE
SAY I knew there wasn't a race of seals.
ENDIF

Class $_ <class> [example] Is $_ of this class?

[definition]
IF class $n demon
SAY Exorcizo te, omnis spiritus immunde, in nomine Dei
MOB TRANSFER $n 1
ENDIF

Objtype $_ <type> [example] Is $_ an object of the type?

[definition]
IF objtype $o staff
SAY Yes, it is here...This means six kadams high.
SAY And take back one kadam to honor the Hebrew God whose Ark this is.
MOB FORCE $n say You said their headpiece only had markings on one side. Are you absolutely sure?
NOD
MOB FORCE $n SAY They're digging in the wrong place!
MOB FORCE $n laugh
ENDIF

Ismaster $_ [example] Is $_ the master/owner of the mob/object running the prog?

[definition]
IF ismaster $n
SAY What is thy bidding, my master?
ENDIF

Ispk $_ [example] Is $_ PK?

[definition]
IF ispk $n
SAY Welcome to the lounge, $n.
ELSE
SAY Killers and freaks only.
MOB BLOCK $n
ENDIF

Isnpk $_ [example] Is $_ NPK?

[definition]
IF isnpk $n
SAY Killers and freaks only.
MOB BLOCK $n
ELSE
SAY Welcome to the lounge, $n.
ENDIF

Age $_ Op. <age> [example] Is $_ (older/younger/equal) to the age specified?

[definition]
IF age $n < 100
SAY This is the Legends bar. You may not enter.
MOB BLOCK $n
ENDIF

Vnum $_ Op. <vnum> [example] Is $_ (higher/lower/this) vnum?

[definition]
IF vnum $o >= 100
IF vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF
ENDIF

[Using the AND logic]

IF vnum $o >= 100
AND vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF

Hpcnt $_ Op. <%> [example] Are $_'s HP at more than %?

[definition]
IF hpcnt $n <= 10
SAY You have fought well, Knight.
MOB FLEE
ENDIF

Room $_ Op. <vnum> [example] Is $_ in a room with a vnum (equal/less/greater) than <vnum>?

[definition]
IF room $n <= 100
SAY You are in the realms of limbo. No life. No death.
ENDIF

Sex $_ Op. <sex> [example] Is $_ (equal/less/more) than sex? (0=neuter, 1=male, 2=female, -1=?)

[definition]
IF sex $n < 2
SAY I knew you were lesser.
ENDIF

Level $_ Op. <level> [example] Is $_ (equal/higher/lower) than level?

[definition]
IF level $n < 101
SAY Heros only.
MOB BLOCK $n
ENDIF

Align $_ Op. <align> [example] Is $_ (more/less/equal) to this alignment?

[definition]
IF align $n > 900
SAY You've been very, very good.
ELSE
IF isgood $N
SAY You've been good this year.
ELSE
SAY Coal in your stocking, $n
ENDIF
ENDIF

Money $_ Op. <amount> [example] Does $_ have (more/less/this) platinum amount? Amount calculated to be: platinum + (gold/100) + (silver /100000)

[definition]
IF money $n <= 10
SAY You sad assed bastard.
ENDIF

Objval0 $_ Op. <num> [example] Is the item $_'s value0 (greater/equal/less than)this amount?

[definition]
IF objtype $o wand
AND objval0 $o < 101
SAY Yes, it's a wand, but it's hardly hero material, is it?
ENDIF

Objval1 $_ Op. <num> [example] Is the item $_'s value1 (greater/equal/less than)this amount?

[definition]
IF objtype $o wand
AND objval1 $o < 5
SAY Yes, it's a wand, but There's no life left in it. I'm afraid it's valueless.
ENDIF

Objval2 $_ Op. <num> [example] Is the item $_'s value2 (greater/equal/less than)this amount?

[definition]
IF objtype $o container
AND objval2 $o == 0
SAY It's a nice $O, but it's harldly secure. There's no lock.
ENDIF

Objval3 $_ Op. <num> [example] Is the item $_'s value3 (greater/equal/less than)this amount?

[definition]
IF objtype $o portal
AND objval3 $o == 22598
SAY Surely, that will take you straight to failure.
ENDIF

Objval4 $_ Op. <num> [example] Is the item $_'s value4 (greater/equal/less than)this amount?

[definition]
IF objtype $o container
AND objval4 $o <= 50
SAY Must make things seem half their weight.
ENDIF

Grpsize $_ Op. <num> [example] Is $n's group (greater/less than/equal to) num?

[definition]
IF grpsize $n < 5
SAY You're going to need a bigger boat
mob block $n
ENDIF

Scrawled illegibly by Meathe at 04:33 PM

mprogs

Mob commands

Mob commands allow the programs to run commands that regular characters do not have access to. Many of these are similar to immortal commands, like transfer, zecho, oload (load obj) and purge, and some are unique to the mobs. The commands are entered into the code in the same way that normal commands like 'say Hello!', however, they are always prefixed with 'mob '.

The following table was stolen from the ToD Mob guide. A note about the syntax - $_ means any of the 'dollar sign codes' listed in Creating a simple mprog.

Command Definition
Mob Asound <string> This creates an echo to the rooms directly around the room the prog is triggered in
Mob Gecho <string> Displays the string to all players logged in (as the immortal command gecho)
Mob Zecho <string> Displays the string to all players in the same area the prog was triggered in (as the immortal command zecho)
Mob Echo <string> Displays the string to all players in the room the prog was triggered in (as the immortal command echo)
Mob echoat $_ <string> Displays the string to the target player only (as the immortal command pecho)
Mob Echoaround $_ <string> Displays the string to all others in the room the prog was triggered in except $_
Mob Kill $_ The mob will attack $_ (not effective for objects or rooms)
Mob Assist $_ The mob will attack any who attack $_ (not effective for objects or rooms)
Mob Junk <name/all> The item(s) in the mobs inventory are destroyed (not effective for objects or rooms)
Mob Mload <vnum> The prog loads the mob with the vnum stated (as the immortal command load mob <vnum>)
Mob Oload <Vnum> <R/W> The prog loads the object with the vnum stated, (as the immortal command load mob <vnum>). Using r will load the object to the room, w loads it to the mobs wear location. Objects and Rooms should always load object with 'R', or the object will be destroyed.
Mob Purge <name> The prog purges the object or mob with the ‘Name’ if left blank the mob will purge the entire room.
Mob Goto <Name/Vnum/$_> The mob will go to the location by name, room vnum or target $_.
Mob At <Name/Vnum/$_> <command> The command will be carried out at the desired location.
Mob Transfer $_ <name/vnum> The prog will transfer $_ to the name or vnum
Mob Gtransfer $_ <name/vnum> The prog will transfer $_ and its group to the name or Vnum
Mob Otransfer <name/vnum> <Name/Vnum/$_> The prog transfers the object (by name or vnum) to the location name, vnum or $_
Mob Force $_ <command> Forces $_ to do the listed command
Mob Gforce $_ <command> Force all in $_’s group to do the listed command
Mob Vforce <vnum><command> Forces all mobs with the ‘Vnum’ to do the listed command
Mob Cast <spell> $_ The prog casts the spell listed on $_
Mob Damage $_ [min] [max] <lethal> The prog damages $_ in the rangegiven (mob damage $n 20 200: This would damage $n between 20 and 200 damage). Using the "lethal" option means the damage can kill $_, otherwise it will not damage them below 1 hit point
Mob Remember $_ This will store $_’s name as for later use, the stored name can be called using the variables $q or $Q
Mob Forget <$q/$Q> The mob forgets the stored name
Mob Delay <Number> The mob begins to count down (15 pulses = 1 tick). When the counter hits 0, any mprog attached with a delay trigger will be fired. (not effective for objects or rooms)
Mob Cancel The ‘Delayed’ prog (As above) is canceled (not effective for objects or rooms)
Mob Call <vnum> The prog calls another prog, the vnum, inside the first prog. A maximum of 5 may be called from inside each other.
Mob Flee The mob will flee
Mob Remove $_ <vnum> The mob removes the item vnum from $_ and junks it (destroys)

Examples

Lets return to our crash test goblin. We want to make him a little mercenary, so that he will aid in combat anyone who gives him 400 (or more) platinum. He'll then make a little remark, send a message to the room (but not the briber) and force the bribing character to thank him. The mprog will be tied on to the goblin with a bribe trigger.


mpedit create 125
code
mob assist $n
mob remember $n
say You seem a worthy mark.
mob echoaround $n $i decides that $n is worthwhile. For now.
mob force $n thank $i
@
done
medit 120
addmprog 125 bribe 400
done
asave changed

Of course, goblins are notorious for their lack of ethics, morals and the vast willingness to kick someone when they're down...


mpedit create 126
code
say You know, you never did pay me enough.
mob echoat $q $i plunges $l little knife into your ribs.
mob damage $q 50 100 lethal
mob echoaround $q $i plunges $l little knife into $q's ribs.
@
done
medit 120
addmprog 126 attacked 10
done
asave changed

This code doesn't work as well as it should, however, as prog 126 will be triggered 1 in 10 (roughly) rounds of combat the goblin is involved in, regardless of whether the person who bribed him is there or not (or even still logged on).

There needs to be some form of test built in that can determine if the person who bribed him is there to be stabbed. Which leads to the next section... Control Statements.

Scrawled illegibly by Meathe at 03:29 PM

mprogs

Triggers: Setting the prog loose on the world

Progs can be triggered in many different ways. Triggers are chosen when you are attaching a program to a mob (or object or room). Multiple programs can be attached to a mob, and the same program may be attached with multiple triggers.

The syntax for attaching these are (depending on whether it's a mob, object or room):

addmprog <vnum> <trigger> <argument>
addoprog <vnum> <trigger> <argument>
addrprog <vnum> <trigger> <argument>

The argument depends on the trigger type. It can be a percentage (x% chance of being fired), a keyword or an amount (as for bribes).

% chance: When triggered, this is the chance of the prog being run
Direction: This is the direction the trigger is for. These directions used to be purely numeric, however, now you may use the number or word/letter equivilants, as shown here.

0northn
1easte
2souths
3westw
4upu
5downd

The table below shows what triggers are available (and whether they're available for Objects, Mobs or Rooms), what kind of argument it takes and some remarks on usage.

Available Trigger Argument Notes
OM act keyword When an action (or speech) with the keyword is performed
M attacked % chance On being damaged in combat
M bribe amount (platinum) When the mob is bribed with more than the amount
OMR cast Spell name When the spell is cast (by anyone in the room)
O R close Object: % chance
Room: Direction
Object: When the Object is closed
Room: When the exit in the direction specified is closed
M death % chance On the death of the mob
M delay % chance Triggered by the mob command, mob delay <time>, fires after the delay specified in the mprog.
OMR entry % chance Mobs: On entry to a new room
Objects: Only valid on portal objects.
Rooms: Entry from any direction
MR exall Direction Mobs: When a character leaves in that direction
Rooms: When a character leaves in that direction.
OMR exit Mobs: Direction
Object: % chance
Room: direction
Objects: Only valid on portal objects.
Mobs: When a visible character leaves in that direction
Rooms: When a character leaves in that direction.
OMR fight % chance Occurs every round of combat
O get % chance When the Object is picked up
OM give Mobs: <objname/vnum>
Objects: % chance
Mobs: On receipt of an object
Objects: On being given
OMR grall % chance On entry to a room, greets whether visible or not.
OMR greet % chance On entry to a room, only greets visible characters
For objects and rooms, this is equivilant to grall
M hpcnt % mob hit points When current hit points are below the % of original hp
OMR kill % chance Mob: When the mob makes a kill
Object: If the Object is a weapon and wielded when the character makes a kill
Room: When a kill occurs inside the room
O R lock Object: % chance
Room: Direction
Object: When the lock on an Object is locked
Room: When the lock on the direction specified is locked
O R open Object: % chance
Room: Direction
Object: When the Object is opened
Room: When the exit in the direction specified is opened
O R pick Object: % chance
Room: Direction
Object: When the lock on an Object is picked
Room: When the lock on the direction specified is picked
O put % chance On being put
M random % chance Tested 15 times per tick, percentage should be quite low.
OMR speech Keyword Whenever the keyword is spoken
M surr % chance A character surrenders in combat with the surrender command
O R unlock Object: % chance
Room: Direction
Object: When the lock on an Object is unlocked
Room: When the lock on the direction specified is unlocked
O use % chance Only works with Objects that may be used in an action: potions, food, stakes, thrown Objects, wands, etc.
O wear % chance On being worn

Some examples:

Added withWhat it does
addrprog 125 exit north Fires when someone leaves the room north
addoprog 135 exit 50 50/50 chance to fire every time someone exits (emerges) from the portal
addmprog 121 cast blessWhen a bless spell is cast in the same room as the mob
addoprog 122 give 100Every time the item is given to someone
addoprog 123 give 201 in 5 chance every time the item is given to someone
addmprog 145 bribe 300When the mob is bribed with 300 or more platinum
addmprog 121 speech whereWhen someone in the rooms says "where"
addmprog 122 exit southWhen someone leaves south

Removing Progs

Now they're attached. But mistakes happen, and changes sometimes need to be made. delmprog, delrprog and deloprog are the commands we need, however they don't use vnums, unlike the add version of the command, it uses an index number. Thankfully, it's easier to use than it sounds.

Lets return to the goblin (vnum 120, with programs 120, 121 and 122 attached).


medit 120
[enter]
Mass goblin stats, skipped
MOBPrograms for [ 120]:
Number Vnum Trigger Phrase
------ ---- ------- ------
[    0] 120   GRALL  100
[    1] 121   SPEECH where
[    2] 122   EXIT   south
delmprog 0
[enter]
Mass of goblin stats, skipped
MOBPrograms for [ 120]:
Number Vnum Trigger Phrase
------ ---- ------- ------
[    0] 121   SPEECH where
[    2] 122   EXIT   south

The GRALL trigger we added first (number 0), has been removed.

Scrawled illegibly by Meathe at 12:55 PM

mprogs

Creating a simple mprog

Here, we'll create a simple program, that reacts to a character, greeting them by name.

In the following examples, we'll use a goblin, with a vnum of 120. We know the vnums 120 onwards are free for mprog creation. Commands entered will be shown in this colour. In the mprog editor, the lines are always preceded by the angle bracket >. Do not type this in, it is the mprog edit prompt.


mpedit create 120
MobProgram Code Created.
code
-=======- Entering APPEND Mode -========-
Type .h on a new line for help
Terminate with a ~ or @ on a blank line.
-=======================================-
> say What would you be searching for, down in the depths, man thing?
> @
done

This is a very simple prog, and doesn't know anything about names. When it it triggered, it will simply say the line it has been given.

However, the program is not attached to anything, and so at this stage, will never actually run. Now it must be attached to the goblin (staples are preferred, crazy glue is ok), and the conditions that will trigger it set. There are a wide array of triggers and trigger types, however these will be covered in depth later. For now, we shall use one of the simplest, grall (greet all). Grall will trigger the mprog when anyone enters the room, visible or not to the goblin. Grall also takes a percentage to determine if it should fire every time, or more randomly.

Here we enter the mobile editor for the goblin and add the mobile prog (addmprog), also vnum 120 in this particular case, using a grall trigger, with 100% chance of triggering when anyone enters. In order to test this out, the mob is then loaded, and I leave and renter the room, triggering the program.

medit 120
addmprog 120 grall 100

Mprog Added.

done
load mob 120

Ok.
south
north

In common, a repulsive goblin says 'What would you be searching for, down in the depths, man thing?'

But we wanted this program to greet people by name. In order to do that, we need to look at the variables you can use in mprogs.

Variables

There is quite a selection of variables you can use in mprogs, and you should be able to find one that suits your purpose. The following table is large, but don't panic - you are not expected to memorise it. It's here for reference.

$i The name(s) of the mob/object/room
$I The short description of the mob/object/room
$n The name of who activated the trigger (Or Opponent)
$N The name and title of who activated the trigger
$t The name of the secondary character (Meathe points at Navarre, Meathe = $n, Navarre = $t)
$T The short description (NPC) or name and title of secondary character (PC)
$r The name or a random PC in the room
$R The short description (NPC) or name and title of the random PC
$q The name of the prog target (See MOB REMEMBER)
$Q The short description (NPC) or name and title of the prog target
$u The name of the wielder/wearer of the object (Oprog)
$U The short description (NPC) or name and title of the wielder/wearer of the object (Oprog)
$j He/She/It based on the sex of $i
$e He/She/It based on the sex of $n
$E He/She/It based on the sex of $t
$J He/She/It based on the sex of $r
$X He/She/It based on the sex of $q
$k Him/Her/It based on the sex of $i
$m Him/Her/It based on the sex of $n
$M Him/Her/It based on the sex of $t
$K Him/Her/It based on the sex of $r
$Y Him/Her/It based on the sex of $q
$l His/Hers/Its based on the sex of $i
$s His/Hers/Its based on the sex of $n
$S His/Hers/Its based on the sex of $t
$L His/Hers/Its based on the sex of $r
$Z His/Hers/Its based on the sex of $
$o The name(s) of the primary object (Meathe drops the staff, the staff = $o)
$O The short description of the primary object
$p The name of the secondary object (Meathe puts the staff in the chest, the chest = $p)
$P The short description of the secondary object.

WARNING

It is important to remember that mobs, objects and rooms see the world from slightly different perspectives, so the $ codes may vary in their output slightly when run by different entities. Please test your programs with the object/room/mob that will be running it.

An example is the following program, attached to both a room and an object with a kill trigger:

say Fataility! $n has killed $t!

The output on killing a goblin in the arena (for me) is:

ROOM:In common, the Arena says 'Fataility Meathe has killed a goblin!'
OBJECT:In common, -+-UlTiMaTe WeAPoN-+- says 'Fataility a goblin has killed someone!'

It's not an ideal situation, however, altering the logic of this would disrupt many current progs. Your milage may vary, simply remember to test.

From the table, either $n (name of person setting off the trigger) or $N (name and title) are what we'd like to use for the goblin. In this example, we'll replace the code 'man thing' with $N, add one line to make the goblin peer at the character and finally trigger the program again.


mpedit 120
code
-=======- Entering APPEND Mode -========-
Type .h on a new line for help
Terminate with a ~ or @ on a blank line.
-=======================================-
1. say And what would you be wanting in a place like this, man thing?
> .r 'man thing' '$N'
'man thing' replaced with '$N'.
> peer $n
> @
[enter]
Vnum: [120]
Code:
say And what would you be wanting in a place like this, $N?
peer $n
done
south
north

In common, a repulsive goblin says 'What would you be searching for, down in the depths, Meathe - devourer of fishes?'
A repulsive goblin peers at you.

You can see that the variables can be used in a mix and match style with standard player commands, like look, steal, emotes and the rest.

They are also used in mob commands and the control statements, so you will need to be familiar with how they work.

To enhance this program further, lines such as these could be added:

say I am but a poor, simple $I. I cannot be expected to know.
innocent $n
mutter
say $e's on to usss, my precioussss. $e knows of things. Kills $k we must.
scream $n
murder $n

Scrawled illegibly by Meathe at 11:34 AM

mprogs

An introduction to *progs: The basics

Credits: This guide is based on the Time of Darkness *prog guilde, written by Oaklore with a great deal of collaboration from Coyote. Robbie Roberts, Aaron Buhr, are the original creators of Mobprogram code, modified for ToD by Coyote and myself. All errors in this document are entirely mine. Please let me know of them so they may be corrected. This document will be revised on an ongoing basis, and any feedback or further questions are most welcomed.



2006-01-30: It seems most people are getting here from google searches. Welcome aboard. These pages refer to a prog system that is not-quite stock Rot, however should be broadly applicable. If you find errors, omissions, have a question or find it useful, please leave a comment.

Mob programs are one of the more complicated parts of on line creation. They needn't be, and this guide will be a walkthrough of some of the basics, with examples building on each other to eventually create some complex programs.

*Progs are used to control the action of a mob, object or even a room. All progs, no matter what they are attached to, use the same code and function in the same way, with some small exceptions, which will be noted where applicable. A program written for a mob will work equally well on a room, and vice versa.

Anatomy of a prog

Progs are written in a mix of english and gibberish (more on that later), though they do have a simple structure, which consists of three types of things:

  • Player commands - These are things like say, get, wear, drop. In the code, you write them as you would use them yourself. These are also restricted by level, so if the mob is level 15, don't expect it to have immortal commands.
  • Mob commands - These are additional commands that are specific to mob progs, to allow programs to do things impossible with player commands. In the prog, these are always prefixed with "mob ", even if it's a program intended for a room or object.
  • Control statements - IF/ELSE/ENDIF These control the flow of the program, based on the conditions you specify.
  • Of course, to get to writing them, it helps to know a few commands that will help you view, create, edit and otherwise display the progs.

    Mud Commands

    These commands are not part of OLC, but are very useful to

    mpstat/opstat/rpstat <name/vnum for rooms> - This command lists the vnum, name and target of the subject and any *progs attached.

    mpdump/opdump/rpdump <prog vnum> - The will display the program code, an easy way to look inside a current program without editing it. As rprogs/oprogs/mprogs are identical, any of these commands will dump any mprog, regardless of whether it's intended (or attached to) a room, mob or object.

    proglist <area> - This will list the vnums of progs in either the current area or the area specified.

    OLC Commands

    These commands are much like other OLC building commands, so should be straight forward:

    mpedit create <vnum> or mpedit <vnum> - This will create a blank mprog or edit an existing mprog.

    Once you have created (or entered editing mode), the following commands are used:

    code - This employs the OLC description editor (as used to describe rooms) to edit and manipulate code.

    When the prog is complete, you will want to attach it to the room/item/object. This is done by entering the appropriate editor (oedit, redit, medit).

    add(m/o/r)prog <prog vnum> <trigger> <phrase/percentage/direction>
    del(m/o/r)prog <prog sequence number>

    Attaching and removing progs and triggers will be covered in greater depth after we have created some progs to attach, it is listed so there will be a ready reference page later with all the commands you may wish to use.

    Scrawled illegibly by Meathe at 11:01 AM