Area Building

· Home
· Overview
· Helps
· Mobiles
· Objects
· Rooms
· Resets

· Shops
· Specials
· Time
· Weather
· Scripts


Writting Scripts

This section talks about things to think about when writing scritps. Scripts are ment as a flexible alternative to hard coding things in. It allows area designers to add life and variety to an otherwise passive area. Good scripts are short and sweet, don't feel you need to add scripts to every mob and object in your area. A few well placed scripts can spice up the place, but too many can lead to a noisy, unplesent area.

In this section we'll talk about some design considerations you should remember when writing scripts.

Working with Mobs

Mobs are the lifeblood of the mud. And most mobs are pretty booring. They just stand there and wait to get killed, or they might wander around a little while waiting to get killed. Some mobs try to kill you right away, and some don't. Without scripts, that's about as interactive as mobs got.

Now we have a wide variety of script triggers like @rand, @action, @greet, @entry, etc.That are triggered when certain actions happen in the mud. If you want a mob to say hello to everyone who walks into the room the mob is already in, you can use a @greet script that might look like this:

@greet 100~
{
 say Hello $n.persname!
}
~
|

This script will fire 100% of the time a new person enters the room.

If you want a more interesting fight on a mob, you might add a @fight script that looks like this:

@fight 30~
{
 if (@rand(1,100) < 25) {
 mpcast heal
} else if (@rand(1,100) < 33) {
 mpcast acid
} else if (@rand(1,100) < 50) {
 mpcast exorcise
} else {
 disarm
}
}
~
|

PCs and NPCs

In the mud, NPCs and PCs are both based on the 'character' class. As such most of their attributes are the same. However there are some exceptions, and those are noted in the player and mob attribute table. Be carefull when using an attribute that is either npc or pc only. You should always test for the condition you are looking for before attempting to use one of these attributes. For example if you wanted a mob that only greeted members of a certain tribe, you could use something like this:

@greet 100~
{
 if (@ispc($n) and $n.tribe) {
  if ($n.tribe == "illum") {
   say Greetings fellow member of the Illuminati.
  }
 }
}

First we tested to make sure who ever entered the room ($n) was a pc and if $n is in a tribe, then we went on with the rest of the script. The same would be true if you wanted to test an attribute specific to an npc.

Also, some attributes are available to both, but are used dierently. Some of the attributes, namely short_descr and long_descr are available on pcs, but are always blank. Here is a greet script that takes into account the diferences between pcs and npcs:

@greet 100~
{
 if (@ispc($n)) {
  say Greetings $n.name!
 } else {
  say Greetings $n.short_descr!
 }
}

This script takes into account the fact that mobs typically have very strange 'name' attributes. For example, the great red dragon's 'name' is actually 'great dragon red'. So if you were to simply use $n.name for both pcs and npcs, if the great red dragon entered the room this mob would say "Greetings great dragon red!" and that would be kinda silly. Similarly, since the short_descr on pcs is always blank, if you used only the $n.short_descr for both, when a pc entered the room the mob would say "Greeting !".

Altho we now have the attribute $n.persname, which is smart and chooses the name of a player, and the short_descr of an npc, so the use of $n.persname is prefered anytime printing or saying of a mob's name is used:

@greet 100~
{
 say Look! It's $n.persname!
}

You should also remember to take into account that many players will walk around invisable or hiding. If your mob does not have detect invis and detect hidden (most mobs shouldn't) you should take this into consideration in your scripts as well. Let's say you had a script that you wanted to have a mob attack only evil orcs. Because the aggressive flags on mobs are an OR opperator, if you were to set the mob aggie to orcs and evil, it would attack good orcs, as well as evil elves. So in order to test for both, you would need to write a simple script. However if this mob cannot see invisable or hidden things, then we should not attack:

@greet 50~
{
 if (@cansee($i,$n)) {
  if (($n.race == "orc") and ($n.alignment < -300)) {
   mpkill $n
  }
 }
}

If the mob can't see $n, then the rest of the script is bypassed.

Attributes, Variables, and the dot (.) notation

Mob Scripts

You see $n and $i being used a lot in all these examples. These refer to characters, either mobs or players, that relate to the script somehow. The $i variable always relates to the mob that the script is attached to. Therefor if we want to know anything about the mob itself, the room the mob is in, etc, we start with $i.

$i.short_descr returns the short description of the mob that this script is on (Barliman Butterbur)
$i.long_descr returns the long description of the mob (Barliman Butterbur stands here, a jovial greeting on his lips.)
$i.level the level of the mob
$i.room.vnum the vnum of the room this mob is in right now.
$i.room.area.name the name of the are the mob is in

Similarly, the $n variable is probably the most used variable, because it targets the actor that triggered the script. Scripts like @action, @speach, @give, and @greet all generate an $n variable that is associated with the mob or player that triggered it. So if Estranged were to enter a room with a mob that had a @greet trigger on it, then $n would point to Estranged, and any of Estranged's attributes could then be referenced based on that.

One thing to keep in mind. The period character is sort of a reserved character in scripts. Any period following a variable reference forces the script parser to look for more attributes. For example:

if (@isafected($n,B) and @ispc($n)) {
 say Oh, aren't we sneaky $n.persname...
}

If Estranged triggered this script and was invisable (the B is the AFF_INVISABLE flag) you would expect the mob to say "Oh, aren't we sneaky Estranged...". But in fact it will yield a parse error when we try and load the script, because the period signals the parser that the next set of letters is another attribute, and since the next letter is another period, the parser will complain that it's not a valid attribute. This causes particular problems where you may be using an echo to say something to a room. Unfortunately right now, variables and attributes must have leading and trailing spaces between it and other info.

IMPORTANT! One thing to remember is that the @death trigger does NOT generate an actor. The mob just dies. This is because, while player induced death is by far the most common way mobs die, a mob could die from poison, plague, or via another script. So any references to $n in a @death trigger will cause the script to crash when it triggers.

@death does now generate an actor, so $n will work.

Another frequently used variable is $r. This targets a random player or mob in a room. Most of the time this is simply used to spice stuff up. For example, Barliman has a random script on him that looks like this:

@rand 3~
{
 if (@rand(1,100) < 25) {
  if ($r) {
   smile $r
  }
 } else if (@rand(1,100) < 25) {
  if ($r) {
   hug $r
  }
 } else if (@rand(1,100) < 25) {
  if ($r) {
   noogie $r
  }
 } else if (@rand(1,100) < 25) {
  if ($r) {
   say $r! Good ta see ya, pal!
  }
 } else if (@rand(1,100) < 25) {
  forehead
 } else if ($r) {
  tickle $r
 }
}
~

All of the if ($r) statements are there to make sure that the random character that was picked is actually still around. This rarely is needed, but should always be there just in case.

One of the rarely used variables is $t. This refers to the 'victim', and for the most part 'victims' are only generated in an @action trigger. The victim is the reciever of the action. So if player A hit mob B with an acid blast, the mob would be assigned to $t. This is really only usefull if the mob with the script is observing two other characters interacting. For example if you wanted a mob to say something when others were fighting, you might use something like this:

@action p does UNSPEAKABLE things~
{
  say Way to go $n.persname! Kick $t.persname in the butt for me too!
}
~

More to Come!