The best way to understand mobprogs is to build them. Let's recall our prime example of a mobile, Karn:
#1 karn stonehammer grizzled barkeep owner trollslayer old dwarf~ Karn~ A grizzled old dwarf is busy serving bar patrons. ~ Advanced years and the lack of a right forearm do not appear to have slowed the old dwarf down. Karn pours drinks and serves meals as if a dwarf half his age with all body parts attached, and shows no signs of weariness. His skin is a mass of scars; tufts of hair are missing from his long grey beard in places where the skin has burned; his left ear has been pummeled so much nothing is left save a small shrivelled mass of cauliflower-like cartilage; several of his teeth are missing, and a long scar reaches from around his right nostril down his cheek to his lower jaw. Despite the obvious trials the dwarf has gone through, Karn keeps a jovial disposition, jovial in a dwarf sort of way. ~ dwarf~ BGTfinz ac 0 0 51 25 50d10+5000 1d1+999 5d8+20 bash -21 -21 -21 -21 ACDFK ABCDLQ 0 0 stand stand M 0 0 0 medium 0 M greet mKarnGreeting 100~ M act mKarnOffer drinks~ M speech mKarnStory story~ M speech mKarnStory tale~ M speech mKarnStory yarn~ M random mKarnRandom 10~ M hour mKarnCleaning 16~ App 35 D Be honorable, and tell Lord Astragoth I await him on the other side.~
We specifically want to look at the greet triggers, which are listed as:
M greet mKarnGreeting 100~ M act mKarnOffer drinks~ M speech mKarnStory story~ M speech mKarnStory tale~ M speech mKarnStory yarn~ M random mKarnRandom 10~ M hour mKarnCleaning 16~
The first trigger will set off a program every time (100 %) a visible player enters the same room as Karn. The second trigger calls a program when a player drinks something. The third, fourth, and fifth triggers call the "mKarnStory" program whenever someone says "story", "tale", or "yarn". The sixth trigger is a random trigger, and the seventh trigger is an hourly trigger.
So, what will Karn do or say when a visible player enters the room? We open our mobprogs thus:
#MOBPROGS #mKarnGreeting if rand 10 say Hold on a sec, I'll be right witcha. emote begins pouring beer from a tap. else if rand 10 say What can I gitcha? emote holds a stein up to the light and examines it. endif endif ~
Line one is the opening of the #MOBPROGS area header, where we will place all our mobile programs. Line three begins the first mobile program, which is Karn's greeting to all visible characters coming into the bar area where the old dwarf resides. Notice the name of the mob program: we start it with an "#m" which, for the immortals on Dawn, generally means a mobprog of some kind, and then follow the "m" with the name of the mobile (Karn) and what the program does (Greeting). This is a style issue, and although you as the builder may not agree with the style, nevertheless it helps the immortal in charge of areas (and the others) understand what it does. That is, "mKarnGreeting" is a greeting mobprog used by our dwarf barkeep, Karn.
If you have read the original builder's guide and its discussion of mobprogs, you will understand that the "if" statements given are if_checks, and will check certain states of the mud at the time the trigger is set off. In this case we call the "random" procedure, which will in effect choose a random number between 1 and 100, and if the number is 10 or less, the mobcommands (e.g. "say Hold on...", "emote begins...") will execute. If not, the program goes to the next if_check, another random check, and should this come under the designated number (10) the mobcommands will execute. If not, the mobprog ends without issuing any mobcommands.
The trigger, you'll remember, is set for 100 percent, that is, every time a visible player comes into the room, the trigger calls to the mobprog "mKarnGreeting". Then, when the mobprog does execute, there is only a 10 percent chance one thing will happen, and another 10 percent chance something else will happen, and that's that. As a builder you can control how often your mobprogs will kick in; if you want a mobprog to work every other week, it is possible with the right kind of coding.
Mobprogs liven up an area. Where years ago most mobiles crept around with nothing to say or do, just wandering along until a player came by to kill it, today's mobiles can do much more. A builder can have a mobile start a conversation with a player, hand out quests to players, spell a player up, attack certain players, transport players, gamble with a player, and so forth. Mobiles can also provide background "noise" to an area; thus no longer will a room be a description -- it also can make sounds and smells and burn a player up. Let's jump to Karn's random trigger to see what I mean:
#mKarnRandom if rand 5 mob echo "A barmaid calls out, 'Karn, another round of red over here.'" chuckle say People never get tired of the stuff. emote grabs several mugs off the shelf and begins pouring red beer from a barrel. else if rand 5 mob echo "A barmaid rushes up to the counter with an empty tray." mob echo "The barmaid asks, 'Have my order ready?'" nod mob echo "The barmaid smiles in return." mob echo "Quickly gathering up the plates and steins, the barmaid dashes off, sloshing red beer over the counter, stool, amd floor." say Hey! Watch out! Payin' cust'mers here! growl emote begins wiping up the mess. else if rand 5 mob echo "You hear someone fall out of a chair at the far end of the room." grumble else if rand 5 mob echo "You hear loud, boisterous laughter from someone across the room." endif endif endif endif ~
This is a decent start. Whenever a player is in the room, once in a while something will happen around Karn. Karn is shooting off the programs, but the mobcommands are written so in some ways Karn looks like a bystander through the whole affair.
Still, the mobprogs will make the whole affair look somewhat unnatural. That is, when a player sees the first set of mobcommands execute, for example, she will see something this at her prompt:
<365hp 402m 305mv 13287tnl inside> A barmaid calls out, 'Karn, another round of red over here.' Karn chuckles politely. Karn says, 'People never get tired of the stuff.' Karn grabs several mugs off the shelf and begins pouring red beer from a barrel. <365hp 402m 305mv 13287tnl inside>
The action occurs all at one time, which is generally not how action happens around a player. The player is instead more used to this:
<365hp 402m 305mv 13287tnl inside> A barmaid calls out, 'Karn, another round of red over here.' <365hp 402m 305mv 13287tnl inside> Karn chuckles politely. <365hp 402m 305mv 13287tnl inside> Karn says, 'People never get tired of the stuff.' <365hp 402m 305mv 13287tnl inside> Karn grabs several mugs off the shelf and begins pouring red beer from a barrel.
The bad news is, mobprogs alone won't help bring out this sort of realism. The good news is, builders can resort to scripts to insert an even better measure of realism in their areas. Before making an actual script, we first rewrite portions of the random mobprog that Karn accesses when his trigger trips:
#mKarnRandom if rand 5 mob setscript $i sKarnRandom01 2 false else if rand 5 mob setscript $i sKarnRandom02 2 false else if rand 5 mob setscript $i sKarnRandom03 2 false else if rand 5 mob echo "You hear loud, boisterous laughter from someone across the room." endif endif endif endif ~
What we've done is use the mobprog to call out to various mobscripts, which in turn will hold the environmental mobcommands we prefer were more realistic:
#SCRIPTS #sKarnRandom01 {mob echo "A barmaid calls out, 'Karn, another round of red over here.'"} {chuckle} {say People never get tired of the stuff.} {emote grabs several mugs off the shelf and begins pouring red beer from a barrel.} ~ #sKarnRandom02 {mob echo "A barmaid rushes up to the counter with an empty tray."} {mob echo "The barmaid asks 'Have my order ready?'"} {nod} {mob echo "The barmaid smiles in return."} {mob echo "Quickly gathering up the plates and steins, the barmaid dashes off, sloshing red beer over the counter, stool, amd floor."} {say Hey! Watch out! Payin' cust'mers here!} {growl} {emote begins wiping up the mess.} ~ #sKarnRandom03 {mob echo "You hear someone fall out of a chair at the far end of the room."} {grumble} ~
Now each action and interaction will take place at each pulse, presenting a more realistic view of the circumstances. Not that some emotes and echoes shouldn't take place at the same time; in fact, there are times you may want to have certain actions occur together. You see, when two or more mobiles and players are in a room together, sometimes they do things at the same time (in mud-speak, we say they process at the same pulse.) Let's make up a script to see what we're talking about:
#sKarnStory05 {emote grabs a slice of grilled ham with some tongs and puts them on a plate.} {emote turns around and places the plate on the bar.} {say It took me a dozen years, but I managed to find Butch.} {say 'Scuse me a sec.} {yell Order up!} {say Now, as I wuz sayin', I found Butch, an' he was as mean as ever.} {say I'd gotten used to havin' no arm, fought in many battles wit' elfs and orcs and other varmints.} {mob echo "A barmaid rushes up to the bar and grabs the plate of ham."} {say But, tell th' truth, I wasn't lookin' forward t' Butch.} {say It's th' kinda thin' a youngin' don't git used to.} {mob echo "The barmaid leaves to her table."} {emote strokes his beard as he thinks.} {say But I heard ol' Butch wuz up to his ol' haunts an' tricks, so I went lookin' fer him.} {say You know trolls don't get older, just uglier wit' th' years?} {say Well, I found 'im, near a lake far to th' east, but I can't say if it wuz me who found 'im, or him who found me.} {say It wuz like he knew I wuz comin', an' laughed when he saw me.} {say So he looks at me real close, grinz, an' says, "How's yer arm, runt?"} {say An' next ya' know, he grabs somethin' from 'is backpack. I'll be durned if it weren't my arm!} {say "Got a gift fer ya'" he says, then throws it into th' lake! "But ya' gotta go through me firs'!".} {say All this time I thought Butch ate m' arm. Turns out he wuz collectin' parts.} {cough} {say If'n ya' go over to th' fireplace, you can see how th' battle turned out.} {grin} {say Still, I never did get my arm back. By th' time the battle wuz over, my arm was gone.} {sigh} {emote returns to his work.} ~
A lot more happens in this script. We have Karn telling a story about his last encounter with Butch. While he is telling the story, a barmaid comes up to grab the plate of ham he just finished fixing. This is what our player will see:
<265hp 277m 178mv 636tnl inside> Karn grabs a slice of grilled ham with some tongs and puts them on a plate. <265hp 277m 178mv 636tnl inside> Karn turns around and places the plate on the bar. <265hp 277m 178mv 636tnl inside> Karn says 'It took me a dozen years, but I managed to find Butch.' <265hp 277m 178mv 636tnl inside> Karn says ''Scuse me a sec.' <265hp 277m 178mv 636tnl inside> Karn yells 'Order up!' <265hp 277m 178mv 636tnl inside> Karn says 'Now, as I wuz sayin', I found Butch, an' he was as mean as ever.' <265hp 277m 178mv 636tnl inside> Karn says 'I'd gotten used to havin' no arm, fought in many battles wit' elfs and orcs and other varmints.' <265hp 277m 178mv 636tnl inside> A barmaid rushes up to the bar and grabs the plate of ham. <265hp 277m 178mv 636tnl inside> Karn says 'But, tell th' truth, I wasn't lookin' forward t' Butch.' <265hp 277m 178mv 636tnl inside> Karn says 'It's th' kinda thin' a youngin' don't git used to.' <265hp 277m 178mv 636tnl inside> The barmaid leaves to her table.
The player will see each action happen every two pulses -- Karn says something, the barmaid comes to the bar, Karn says something else, the barmaid leaves to her table, and so forth. We have set up another situation where the action is unnatural; afterall, the barmaid will be grabbing plates as Karn talks, right? That is, the two activities will happen simultaneously.
We've come to another problem, that is, relying on scripts to provide a natural feel to a mob program, and finding out we cannot allow two or more mobiles to work simultaneously. Not so fast! There is an easy workaround for this kind of problem: the use of curly brackets. Notice what we do below:
#sKarnStory05 {emote grabs a slice of grilled ham with some tongs and puts them on a plate.} { emote turns around and places the plate on the bar.; say It took me a dozen years, but I managed to find Butch. } {say 'Scuse me a sec.} {yell Order up!} {say Now, as I wuz sayin', I found Butch, an' he was as mean as ever.} {say I'd gotten used to havin' no arm, fought in many battles wit' elfs and orcs and other varmints.} { mob echo "A barmaid rushes up to the bar and grabs the plate of ham."; say But, tell th' truth, I wasn't lookin' forward t' Butch. } { say It's th' kinda thin' a youngin' don't git used to.; mob echo "The barmaid leaves to her table." } { emote strokes his beard as he thinks.; say But I heard ol' Butch wuz up to his ol' haunts an' tricks, so I went lookin' fer him. } {say You know trolls don't get older, just uglier wit' th' years?} {say Well, I found 'im, near a lake far to th' east, but I can't say if it wuz me who found 'im, or him who found me.} {say It wuz like he knew I wuz comin', an' laughed when he saw me.} {say So he looks at me real close, grinz, an' says, "How's yer arm, runt?"} {say An' next ya' know, he grabs somethin' from 'is backpack. I'll be durned if it weren't my arm!} {say "Got a gift fer ya'" he says, then throws it into th' lake! "But ya' gotta go through me firs'!".} {say All this time I thought Butch ate m' arm. Turns out he wuz collectin' parts.} {cough} {say If'n ya' go over to th' fireplace, you can see how th' battle turned out.} {grin} {say Still, I never did get my arm back. By th' time the battle wuz over, my arm was gone.} {sigh} {emote returns to his work.} ~
By using the curly braces in places, we allow several actions by one or more actors to occur simultaneously. Karn speaks, and the barmaid grabs the food off the bar counter. It happens at the same time, as actions in the real world happen at the same time. The players will see this as natural. Here's what players will see now:
<265hp 277m 178mv 636tnl inside> Karn grabs a slice of grilled ham with some tongs and puts them on a plate. <265hp 277m 178mv 636tnl inside> Karn turns around and places the plate on the bar. Karn says 'It took me a dozen years, but I managed to find Butch.' <265hp 277m 178mv 636tnl inside> Karn says ''Scuse me a sec.' <265hp 277m 178mv 636tnl inside> Karn yells 'Order up!' <265hp 277m 178mv 636tnl inside> Karn says 'Now, as I wuz sayin', I found Butch, an' he was as mean as ever.' <265hp 277m 178mv 636tnl inside> Karn says 'I'd gotten used to havin' no arm, fought in many battles wit' elfs and orcs and other varmints.' <265hp 277m 178mv 636tnl inside> A barmaid rushes up to the bar and grabs the plate of ham. Karn says 'But, tell th' truth, I wasn't lookin' forward t' Butch.' <265hp 277m 178mv 636tnl inside> Karn says 'It's th' kinda thin' a youngin' don't git used to.' The barmaid leaves to her table.
What a difference, mmm?
You can use mobprogs and scripts for many, many things. Even for surprises. Here's a script we'll use to have a bar patron toss his lunch on a hapless player:
#mIngridRandom if rand 20 mob echo "Someone at another table begins chuckling loudly." else if rand 20 mob echo "You overhear Ingrid taking an order for more beer from another customer." else if rand 20 mob echo "A drunk wobbles and nearly trips over his own feet." mob echoat $r "The drunk spews chunks at you!!" mob echoaround $r "The drunk spews chunks at $R!!" mob echo "The drunk says ''Scuse me.'" mob echo "The drunk wobbles out of the room." endif endif endif ~
So, whenever Ingrid the barmaid is in the same room as a player, she will on occasion send out a set of commands that will make it look like a drunk is vomitting on a player. So player Jane will see this:
<265hp 277m 178mv 636tnl inside> A drunk wobbles and nearly trips over his own feet. The drunk spews chunks at you!! The drunk says ''Scuse me.' The drunk wobbles out of the room.
Another player in the room will see this:
<257hp 188m 235mv 2435tnl inside> A drunk wobbles and nearly trips over his own feet. The drunk spews chunks at Jane!! The drunk says ''Scuse me.' The drunk wobbles out of the room.
Neither player will have a way at getting back at the drunk, because the drunk doesn't really exist. A cruel joke, perhaps, but an interesting one that the players will appreciate because it adds to the atmosphere (and, who knows, the player's friend may eventually end up being spewed on as well?).
Let's develop an even more elaborate script, one where, if our half-elf, Fyn, is brought a pair of sandals, he will cast a beneficial spell on the player. First, a player asks him for a quest, which kicks off a mobprog:
#mFynQuest if ispc $n mob setscript $i sFynQuest 2 false endif
The if_check above is to prevent mobiles from asking about the quest. The mobprog then calls a script:
#sFynQuest {say Well, now that you mention it...} {emote slowly lowers his eyes down towards his feet.} {say I am in need of a new pair of sandals.} {chuckle} {say I'm a vain traveller, and like to look my best.} {cough} {say I am looking specifically for a pair of, ahem, Birkenstock sandals.} {say Think you can get some for me? I will gladly reward you for them.} {smile} {emote returns to his drinking.} ~
Fyn asks for a simple object, some Birkenstock sandals, which any low-level player can get. What the quest requires, however, is an object from another area, a different area. We are, in essense, making a cross-world quest, another fun thing a player can do. Should she find the object and give it to Fyn, Fyn brings up this mobprog and script:
#mFynReward if ispc $n mob setscript $i sFynReward 2 false endif ~ . . . #sFynReward { mob junk all; say Ah! Thank you very much! } {beam} {say When the time comes that I go in search of further adventure, I can go in style.} {grin} {say I'm sure you are happy for me, but am equally sure you would like a reward.} {smile} {say Here we go...} {emote twiddles his fingers and whispers a few words.} {c 'detect invisibility' $n} {say Thanks again!} {emote turns away and begins sipping his beer.} ~
You may notice the first command in the script is "mob junk all". This will force the mobile to junk anything in its inventory, which is useful for quests which require a player bring an object to the mobile. Then Fyn will go through several socials and sentences, anf finally cast a simple "detect invisibility" spell on the player. Not an awesome spell, no, but a good return for a cheap pair of sandals.
This should do it for mobprogs and scripts. You will find many more examples of these in the the area file itself. Explore them and see what's possible. We have not covered everything one can possibly know about mobprogs and scripts, but it should give you a start.