BlobbieScript Manual

BlobbieScript was designed and written to replace the archaic Easyact system which had far outlived its usefulness. Easyacts were originally designed by Dimwit (Aaron Buhr) and are the basis of mobprogs in Merc 2.2. BlobbieScript is fully backward compatible with previously written easyact code (and thus quite possibly with mobprogs). Despite the compatibility, the features and power of the BlobbieScript engine are nowhere near as limited as that offered by these older engines. BlobbieScript was designed and coded from the ground up and is a bytecode language rather than a run-time interpreter. A quick benchmark has shown that the engine can process 60,000+ lines of BlobbieScript per second. Optimizations are known and are scheduled for sometime in the near future that could bump this up to about 80,000 lines per second. To see a couple of examples of BlobbieScript, please see the examples section.

Flaws in the Easyact Engine

The Easyact engine was a great engine in its hay day and served to be the basis for many other MUD scripting engines; however, it is well past its usefulness having reached somewhere around 10 years of age. Someone really should have put it out of its misery a long time ago. The following outlines the deficiencies encountered in the Easyact engine:

  • Not real-time, variables are expanded macros
  • Scripts are parsed on every run
  • No looping constructs
  • Nothing ensuring data is valid for duration of execution
  • Poor support for expressions
  • No concept of instance variables
  • Code is a mess and poorly scalable
  • No simple way to access internal data fields

Flaws in the Easyact Engine

Almost all of the features in the new BlobbieScript engine arose to solve inadequacies of the easyact engine. The following is a list of features that were (or will be) implemented to meet and exceed the shortcomings of the Easyact engine:

  • Backward compatible with existing Easyact code
  • Real-time data access
  • Looping constructs
  • Block protection for time sensitive routines (mutexes)
  • Fully exploitable precedence based operations
  • On the fly declaration and access of instance variables
  • Static variables
  • Associative array data containers
  • Contextual resolutions for accessing internal data fields
  • Variables use copy-on-write method of copying
  • Easily extensible
  • Return values from scripts for scriptlet embedding
  • Line continuation breaks
  • Error messages which pinpoint problems
  • context manipulation (thread management)
  • User function declaration (after initial engine)

Expressions

Previously the Easyact engine supported some simple block control mechanisms. Some of the mechanisms worked well, others not so well. The 'if' statement is a good example for one that generally works well. One of the greatest drawbacks of the 'if' statement though, is its lack of support for joining conditional expressions. This is solved in the new engine. The following control blocks are supported by BlobbieScript:


Keyword Description
static Initialize static variables
if Test for conditional block entry
elseif Test for conditional block entry where priors have failed
else When all prior tests fail then enter this block
endif Close a series of conditionals
for Initialize and loop over some expression while it evaluates to true.
endfor Loop back to beginning of the matching for block.
foreach Iterate over an array's values.
endforeach Loop back to beginning of the matching foreach block.
do Enter a looping block
dowhile Test conditional for re-entry into 'do' block
while Test conditional for entry into block
endwhile Loop back to beginning of a 'while' conditional loop
wait Wait for a number of time units (secs, hsecs, qsecs, tsecs)
protect Run code in block to completion
endprotect Marker for end of protected block
break Break out of innermost loop or if none then return
continue Jump to beginning of looping block immediately
label Set a marker for a 'jumpto' statement
jumpto Jumpto a given labelled point in the script
return Exit script optionally providing a return value
retval Return a value but do not exit script
<< The final evaluation of the whole line is fed into the mud's interpreter as though the script owner had issued it as a command.
\ Indicates line continues or is a continuation
{ or } A line containing only these and spaces is ignored

Expression Evaluation

One of the biggest problems in creating the BlobbieScript engine was to try and add in real language support while adding the flexibility of evaluating expressions as can be done in almost any other programming language. To maximize ease and backward compatibility there exist two modes of expression evaluation: pure and impure.

Pure expressions are any expressions that are part of a block control expression or part of a function's parameter part. These are called pure because they do not require special treatment to be evaluated in their context. To illustrate, the following is now possible:

0001 if( %getLevel( $n ) < 50 and !%getRandom( 1, 10 ) )
0002 {
0003    damage $n %( (1d10 + 1) * 3 )
0004 }
0005 else-
0006 if( %getAlign( $n ) / 10 > 60 or %getAlign( $n ) < -60 )
0007 {
0008    damage $n %( 1d(1d10) )
0009 }
0010 endif

The difference between pure and impure expressions is also illustrated above. Notice to get the power of expression evaluation within a non- block control statement the expression needs to be evaluated with the special %() function. This is because for backward compatibility reasons the new engine guesses that anything in a block control statement is any of variable, function, or string. Given this interpretation all tokens extracted are considered to be implicitly joined by an invisible concatenation operator. Since this may become confusing if a variable is used that blends into an actual word the following can be used to ensure the end of the variable:

0001 @name = %getName( $n )
0002 echoto r all @{name}'s mother is a wench!

The advantage of such expression evaluation is that it gets rid of the old system of $.calc( 1, +, 3 ) since this can be expressed as %( 1 + 3 ). Moreover the engine fully supports integers, floats, strings, and associative arrays (AKA: dictionary, string indexed array, hash).


Other Types of Expressions

In addition to block control expressions and normal expressions there are comments, continuations, and block tags. Comments begin when a pair of forward slashes "//" are encountered and end at the end of the line.

0001 Example:
0002
0003 //
0004 // Get a list of creatures in the room.
0005 //
0006 @list = %roomGetMobs()     // Creatures are stored in @list
0007
0008 *
0009 * This is a deprecated style, and only works when
0010 * the "*" is the first non-whitespace character on
0011 * a line.
0012 *

The \ at the beginning of a line denotes that the expression continues from the previous line. This was added so conditionals can be nicely formatted for easy reading.

0001 Example:
0002
0003 echoto room all
0004 \   You can feel the rush of winds building in strength to
0005 \   a deafening roar. You clasp your ears to mitigate the
0006 \   painful effects of the sound.

Block control tags are more for aesthetic purposes. I come from programming background which uses braces to denote code blocks. Normally BlobbieScript doesn't support these blocks due to backwards compatibility; however, for the sake of good looking code (IMHO) any line containing only a sequence of "{" or "}" characters will be ignored.

0001 Example:
0002
0003 if( @n->name == "The Overlord" )
0004 {
0005    echoto notc @n Grovel before your master heathens!
0006 }
0007 else
0008 {{{{
0009    spit @n
0010 }}}}
0011 endif

Finally a semi-colon is permitted on most pure expressions where one would make sense. The behaviour of the engine is to strip it if it is the last character on the line. Note that commands normally passed on to the game's command interpreter will retain any trailing semi-colons.

0001 Example:
0002
0003 @i = 20;
0004 while( (@i -= 1) > 0 )
0005 {
0006    echoto room all A fireball suddenly explodes before you.
0007    damage room all %( 20 + 1d15 ) fire
0008
0009    wait 20 secs;
0010 }
0011 endwhile;

Expression - for

The for construct enables easy iteration over an expression. Unlike the while construct, the for loop provides a means to initialize, test, and update the evaluation.

    Example:

for( @i = 0; @i < 10; @i++ ) { %echoTo( @i, @self ) } endfor;

The above for loop will output the numbers 0 to 9 inclusive to @self. Studying the expression we notice the following pattern:

    Example:

for( [INITIALIZE]; [TEST]; [UPDATE] ) { %echoTo( @i, @self ) } endfor;

So when the for loop is encountered the INITIALIZE portion is processed, then the TEST part is processed to determine if the contents of the for block should be processed. If the contents are processed, then upon reaching the endfor construct the engine will process the UPDATE expression and then the TEST part. Subsequent runs through the loop will repeat this UPDATE/TEST parts until the TEST fails and the loop ends.

Expression - foreach

The foreach construct enables easy iteration over an array's values. This simplifies the task of updating a series of items, mobiles, rooms, or anything else in an array.

    Example:

foreach( %roomGetMobiles() as @mob ) { // // Give a little regen bonus. // @mob->hitpoints += 2d3 } endwhile;
    Example (with index):

@mobiles = %roomGetMobiles() foreach( @mobiles as @index => @mob ) { // // Move to Elkin fountain. // %move( @mobiles->@index, 115611 ); } endwhile;

Operators

Operators

Operators are at the epicentre of any kind of logical and mathematical processing. To facilitate the power that BlobbieScript will exhibit, many of the most common programming operators have been implemented. Some of the operators can be expressed in more than one way since not all programming languages use the same style. Remember operators will only be functional if found within a pure context, otherwise they are treated as part of the plain text input to the MUD's command interpreter.


Operator Description
 = 
Assign the right operand's value to the left operand (C style).
 := 
Assign the right operand's value to the left operand (Pascal Style).
 += 
Add the right operand to the left operand and assign the value to the left operand.
 -= 
Subtract the right operand from the left operand and assign the value to the left operand.
 /= 
Divide the right operand into the left operand and assign the value to the left operand.
 *= 
Multiply the left operand by the right operand and assign the value to the left operand.
 %= 
Assign to the left operand the remainder from dividing the right operand into the left operand. If the left operand and the right operand are both of the same sign then the remainder will be positive. Otherwise the remainder will be negative.
 ^^= 
Raise the left operand to the power of the right operand and assign the value to the left operand.
 &= 
Take the bitwise AND of the left operand with the right operand and assign to the left operand.
 |= 
Take the bitwise OR of the left operand with the right operand and assign to the left operand.
 ^= 
Take the bitwise XOR of the left operand with the right operand and assign to the left operand.
 <<= 
Shift the bits of the value of the left operand to the left by the value of the right operand and assign to the left operand.
 >>= 
Shift the bits of the value of the left operand to the right by the value of the right operand and assign to the left operand.
 .= 
Concatenate the right operand to the end of the left operand and assign the new value to the left operand.
 || 
Return the the boolean value of taking the logical OR of the left and right operands.
 OR 
Same as '||'.
 && 
Return the the boolean value of taking the logical AND of the left and right operands.
 AND 
Same as '&&'.
 & 
Return the value of taking the bitwise AND of the left operand with the right operand.
 | 
Return the value of taking the bitwise OR of the left operand with the right operand.
 ^ 
Return the value of taking the bitwise XOR of the left operand with the right operand.
 == 
Return the the boolean value of comparing the values of the left and right operands.
 != 
Return the the boolean value of applying the logical NOT operator to the boolean value of comparing the values of the left and right operands.
 === 
Return the the boolean value of comparing the values of the left and right operands with datatype checking. In other words if the datatypes of the left and right operands differ then this will return false, even if the values would normally return true when using the == operator.
 !== 
Return the the boolean value of applying the logical NOT operator to the boolean value of comparing the values of the left and right operands with datatype checking. In other words if the datatypes of the left and right operands differ then this will return true, even if the comparison would normally return false when using the != operator.
 < 
Return the the boolean value of checking to see if the left operand is less than the right operand.
 > 
Return the the boolean value of checking to see if the left operand is greater than the right operand.
 <= 
Return the the boolean value of checking to see if the left operand is less than or equal to the right operand.
 >= 
Return the the boolean value of checking to see if the left operand is greater than or equal to the right operand.
 << 
Return the result of shifting the bits of the left operand to the left by the value of the right operand.
 >> 
Return the result of shifting the bits of the left operand to the right by the value of the right operand.
 . 
Concatenation operator if one existed :) Concatenation occurs invisibly when two operands are detected with no joining operator. Thus the following is legitimate: %( Random: 1d100 ) which will a string of the form "Random: 73".
 MIN 
The left operand is limited to a minimum value as defined by the right operand.
 MAX 
The left operand is limited to a maximum value as defined by the right operand.
 + 
Return the result of adding the right operand to the left operand. This may also be used as a unary operator; however, as such it's benefits are aesthetic only.
 - 
Return the result of subtracting the right operand from the left operand. This may also be used as a unary operator to signify the negation of the right operand.
 / 
Return the result of dividing the right operand into the left operand.
 * 
Return the result of multiplying the left operand by the right operand.
 % 
Return the remainder when the left operand is divided by the right operand. If the left operand and the right operand are both of the same sign then the remainder will be positive. Otherwise the remainder will be negative.
 ^^ 
Return the result of raising the left operand to the power of the right operand.
 D 
Given that the left operand signifies a number of die and the right operand signifies the number of faces for each dice. Return an entry from the set of all possible dice roll totals with these criteria.
 ! 
Return the logical NOT of the right operand.
 ~ 
Return the bitwise NOT of the right operand.
 -> 
Please see "The Resolution Operator" section below.
 ->+ 
The array add operator. This is used in conjunction with the = operator to add elements to an array with auto indexing (@foo->+ = @value).
 ( ) 
Force the evaluation of the expression within the parenthesis to occur before any other evaluation.

Precedence

As with all expression evaluation mechanism there must exist a set of rules of precedence to ensure that what the user expects to happen, actually happens. BlobbieScript uses the following order of precedence, from highest to lowest, for its evaluations -- operators on the same line are of equal precedence:


Order of Precedence
 ( ) 
 -> 
 !  ~  + (unary)  - (unary) 
 D 
 ^^ 
 %  *  / 
 -  + 
 MIN  MAX 
 . (implicit and cannot be used explicitly) 
 << >> 
 ==  !=  === !== <  >  <=  >= 
 & 
 |  ^ 
 && 
 || 
 +=  -=  /=  *=  %=  ^^=  &=  |=  ^=  <<=  >>=  .= := ->+

Variables

Traditionally Easyacts only supported pre-set variables of a single character nature. While the most triggers still support these basic preset variables, newer triggers now use more readable named variables. For instance $i traditionally was a variable whose contents were a text pointer to entity for which the script was defined. While this can still be used, the more object oriented nomenclature of @this, or @self is preferred. These can also be written using $ but to break from the past it is suggested that all variables use @ instead of $ (similarly for function $. has been deprecated in favour of %). Additionally, script authors can now declare variables of their own naming on the fly.

0001 @charName = %getName( @self )
0002 @randNum = %getRandom( 1, 500 )

Local and Static Variable

There are currently five types of variables used in the Worlds of Carnage. The first two are types used by BlobbieScript. This style should always be denoted with the '@' marker such as @foo. These types of variables are only known to the script in which they appear, meaning two different scripts, even two different instances of the same script, will see a different value for @foo. As I have said there are two types, script variables can be declared as static, if so their values are remembered from one script instance to the next (and subsequently can be shared by multiple instances of the same script). The programmer needs to take care when declaring static variables since ANY variable in the static expression will become static and can thus block normal script variables.

0001 static @foo
0002 static @foo = @fee = (60 * 60) / 14
0003
0004 Strange Behaviour:
0005
0006 //
0007 // Normal variable.
0008 //
0009 @foo = 3
0010
0011 //
0012 // Static declaration, the original @foo has been clobbered and it's
0013 // value forgotten.
0014 //
0015 static @foo

Entity Variables

Another type of variable is the entity variable. Entity variables can be applied to a rooms, mobiles, or objects. Entity variables can be set using %setEntityVar(), retrieved using %getEntityVar(), and unset using %deleteEntityVar(). These variables are a great way to share information across multiple scripts, especially quest, or game information. For convenience three other functions exist: %setVar(), %getvar(), and %deleteVar(). These are a shorthand for accessing the entity variables of the script owner. For instance:

0001 %setVar( foo, 1 )       is identical to     %setEntityVar( @i, foo, 1 )
0002 %getVar( foo )          is identical to     %getEntityVar( @i, foo )
0003 %deleteVar( foo )       is identical to     %deleteEntityVar( @i, foo )

Persistent Variables

The fourth type of variable is persistent. These variables are saved and can be restored even after a crash. Such variables can be used to ensure an object is unique or to save ownership of some residential portion of the world. There is a multitude of uses for such data. When saving a persistent variable, the variable is shared amongst all entity instances with the same vnum. These variables are manipulated with the following functions:

0001 %setSavedVar()
0002 %getSavedVar()
0003 %deleteSavedVar()

Player Variables

The fifth and final variable type persists in the player's save file. These are known as player vars and can be set for players, objects, and rooms. The following functions are used to manipulate their values:

0001 %setPlayerVar()
0002 %getPlayerVar()
0003 %deletePlayerVar()

Player vars set on a room are exactly the same as saved vars since rooms can't be saved to player files, but only one instance of a room with a given vnum can ever exist. The following table summarizes the variable types:


Type Set / Get / Delete Persistence
Local @var1 = 1d5
@var1
Unable to Delete
Variable expires when script completes.
Static static @var1 = 1d5
@var1
Unable to delete
Variable and value persist through all invocations of the script for any given boot of the MUD server.
Entity %setEntityVar( )
%getEntityVar( )
%deleteEntityVar( )
Variable and value are set on a given room, mobile, or object and the value persists for any given boot of the MUD server.
Saved %setSavedVar( )
%getSavedVar( )
%deleteSavedVar( )
Variable and value are shared by all homogenous entities with the same vnum and value persists through MUD reboots.
Player %setPlayerVar( )
%getPlayerVar( )
%deletePlayerVar( )
Variable and value are saved in player files specific to a given player or object instance and persist through MUD reboots.

Predefined Variables

Scripts are fired when events occur. These events can be triggered by a player, a signal, or for a multitude of other reasons. There exists a set of default variables (many cryptic due to backwards compatibility) that are instanciated to facilitate knowledge of what elements played a key part in the firing of the script. These variables are listed below:


Variable Description
@this
@self
@i
A pointer to the owner of the script. Currently this may be a room, character, or object. The @i version was used historically and so has been retained.
@room
A pointer to the room containing the script owner at the time the script is run.
@roomId
The ID of the room containing the script owner at the time the script is run.
@I
The name of the script owner defined by @i. This is set to "something" for rooms and "nothing" for any invalid owners.
@p
Short name of object if the script owner is a character and can see the object defined by @o. If the object is not visible to the owner then it is set to "something". If the owner is not a character then it is set to "nothing".
@P
Short name of target object defined by @t if the script owner defined by @i is a character and can see the object. If the object is not visible to the owner then it is set to "something". If the owner is not a character then it is set to "nothing".
@n
Pointer to the actor that triggered the script. This is usually a character.
@N
The nice'd name of the script actor defined by @n if visible to the script owner. If not visible to the script owner then it is set to "someone". If the script owner is not a character then @n will be considered to be visible. If @n is not a pointer to a character then this will be set to "nobody".
@s
The gender specific possessive for a character script actor defined by @n. This will be one of: his, hers, its. If the actor is not a character then this will be set to "nothing".
@e
The gender specific pronoun for a character script actor defined @by n. This will be one of: he, she, it. If the actor is not a character then this will be set to "nothing".
@m
The gender specific objective for a character script actor defined by @n. This will be one of: him, her, it. If the actor is not a character then this will be set to "nothing".
@h
Pointer to a character being hunted by the character script owner defined by @i. If the owner is not a character then this will be set to "nobody".
@H
The nice'd name of the character defined by @h if visible to the script owner. If not visible to the script owner then it is set to "someone". If the script owner is not a character then this will be set to "nobody".
@t
Pointer to a provided target of the script. In the case of a script triggered by combat, @t will usually be set to the opponent.
@T
The nice'd name of the script target defined by @t if visible to the script owner. If not visible to the script owner then it is set to "someone". If the script owner is not a character then @t will be considered to be visible. If @t is not a pointer to a character then this will be set to "nobody".
@A
Conjunction for a target object as defined by @t. This will have an appropriate value of "a" or "an" (i.e. an apple).
@S
The gender specific possessive for a character script target defined by @n. This will be one of: his, hers, its. If the target is not a character then this will be set to "nothing".
@E
The gender specific pronoun for a character script target defined by @n. This will be one of: he, she, it. If the target is not a character then this will be set to "nothing".
@M
The gender specific objective for a character script target defined by @n. This will be one of: him, her, it. If the target is not a character then this will be set to "nothing".
@a
Conjunction for a the object defined by @o. This will have an appropriate value of "a" or "an" (i.e. an apple).
@o
Pointer to an object that played a part in the script's firing.
@O
Short name of the object defined by @o if the character owner defined by @i can see the object or the owner is not a character. If the script owner is a character and cannot see the object then this is set to "something". If the object defined by @o is not valid then this is set to "nothing".
@x
An arbitrary string that may be set by whatever triggers the script. The prupose of this value is highly dependent on the script. For instance the catch death act populates @x with the name of the creature that died since the creature itself cannot be accessed.
@X
The first word of the string defined by @x.
@q
Pointer to a random object in the current room if any exist.
@Q
Short name of the object defined by @q if the character owner defined by @i can see the object or the owner is not a character. If the script owner is a character and cannot see the object then this is set to "something". If the object defined by @q is not valid then this is set to "nothing".
@r
Pointer to a random creature in the current room if any exist.
@R
The nice'd name of the random character defined by @r if visible to the script owner. If not visible to the script owner then it is set to "someone". If the script owner is not a character then @r will be considered to be visible. If @r is not a pointer to a character then this will be set to "nobody".

Triggers

Many events in the game can be be caught by various event handlers. These event handlers are known as triggers since they trigger some kind of functionality when the event occurs. There are three entity types that can trigger an event. These entities are rooms, mobiles, and objects. Some event types can be triggered by multiple entity types, such as the random event. Most triggers will run an associated script; however, the text ones will merely present some text to player that cause the trigger to fire. Additionally there are a few types that don't do either and are for hacking in special functionality such as the set_skill trigger. Following are the lists of events that apply for each entity type:


Mobiles Objects
adj_sound
catch_act_act
catch_ask_act
catch_ask_text
catch_death_act
catch_enter_game
catch_entry_act
catch_examine_act
catch_exit_act
catch_give_act
catch_identify_act
catch_level_up
catch_practice_act
catch_say_act
catch_say_text
catch_script_call
catch_signal_act
catch_social_act
catch_speech_act
catch_speech_text
catch_talk
catch_tell_act
catch_weapon_strike
check_can_enter
check_can_exit
custom_command_act
custom_mobile_prompt
custom_mobile_status
fight_act
if_inroom
on_area_load
on_entry
on_exit
on_hour_of_day
on_immortal_goto_enter
on_immortal_goto_exit
on_load
on_location_change
on_real_hour_of_day
on_tick
on_zone_load
on_zone_unload
preempt_death_act
random_act
set_affect2
set_skill
set_teach
spec_proc
trigger_assignment
adj_sound
catch_act_act
catch_death_act
catch_dispel
catch_drop_act
catch_enter_game
catch_entry_act
catch_examine_act
catch_exit_act
catch_get_act
catch_get_from_act
catch_identify_act
catch_level_up
catch_list_affect
catch_put_into_act
catch_remove_act
catch_room_affect_show
catch_say_act
catch_script_call
catch_show_affect
catch_signal_act
catch_social_act
catch_speech_act
catch_talk
catch_use_act
catch_weapon_strike
catch_wear_act
check_board_permissions_act
check_can_enter
check_can_exit
check_can_put_into
custom_command_act
custom_equipment_location
custom_mobile_examine_info.source
custom_mobile_prompt
custom_mobile_status
fight_act
if_inroom
on_area_load
on_eaten
on_entry
on_exit
on_expire
on_hour_of_day
on_immortal_goto_enter
on_immortal_goto_exit
on_immortal_goto_qsave
on_load
on_location_change
on_real_hour_of_day
on_tick
on_weapon_strike
on_zone_load
on_zone_unload
preempt_death_act
random_act
spec_proc
trigger_assignment
Rooms  
adj_sound
catch_act_act
catch_death_act
catch_enter_game
catch_entry_act
catch_examine_act
catch_exit_act
catch_level_up
catch_say_act
catch_script_call
catch_signal_act
catch_social_act
catch_speech_act
catch_talk
catch_weapon_strike
check_can_enter
check_can_exit
custom_command_act
custom_mobile_prompt
custom_mobile_status
dream_for_world
dream_for_continent
dream_for_area
dream_for_zone
dream_for_room
fight_act
on_area_load
on_hour_of_day
on_load
on_real_hour_of_day
on_tick
on_zone_load
on_zone_unload
preempt_death_act
random_act
spec_proc
trigger_assignment
 

Functions

The easyact system provided a fairly rich set of functions for accessing the data structures that define the state of the mud at any given point of time. For the most part these functions have been carried forward with the same functionality. Where errors have been detected in the conversion process the errors have been corrected. One concept that was deprecated was the "*ERR*" or any similar type of return value when data is erroneous. Rather than this a null data structure is returned which can be tested with the %isNull( ) function. This is a more consistent and flexible approach to error handling. Generally speaking functions names are case-insensitive; however, for historical reason the %v( ) and %V( ) functions are case-sensitive. Functions are shown with any aliases they may have. I'm high on long names for clarity of code, so you'll notice some function names are just longer versions of the traditional short versions.


%act()%getMin()%mobIsUndead()
%actionDisown()%getMinIndex()%mobPageBufferClear()
%actionIsRunning()%getMobPointer()%mobPageBufferClose()
%affectCheckFlag()%getMobsWithId()%mobPageBufferCopyContents()
%affectGetAntidotes()%getName()%mobPageBufferGetContents()
%affectGetOwner()%getNpcPointer()%mobPageBufferOpen()
%affectGetSkillName()%getObjTypeId()%mobPulseActivity()
%affectSetOwner()%getOpponent()%mobPulseTick()
%affectSetSkillName()%getOpponents()%mobPulseViolence()
%applyBuoyancy()%getOrderId()%mobPurgeSkills()
%areaGetItems()%getOwner()%mobRankAtLeast()
%areaGetMobs()%getPcPointer()%mobRankAtMost()
%areaGetNpcs()%getPet()%mobSendBufferClear()
%areaGetPcs()%getPlayerVar()%mobSendBufferClose()
%areaGetStat()%getPositionId()%mobSendBufferCopyContents()
%array()%getRace()%mobSendBufferGetContents()
%arrayGetHead()%getRacePointer()%mobSendBufferOpen()
%arrayGetKeyForValue()%getRealTime()%mobSetStat()
%arrayGetKeys()%getReputation()%move()
%arrayGetSize()%getRoomPointer()%nAct()
%arrayGetTail()%getSavedVar()%noteGetStat()
%arrayGetValues()%getServerBootId()%noteSetStat()
%arrayHasValue()%getShortName()%npcGetLoadCount()
%arrayImplode()%getSubClass()%null()
%arrayMergeValues()%getTarget()%partyGetMobs()
%arrayShuffle()%getTargets()%partyGetNpcs()
%arrayUnset()%getTime()%partyGetPcs()
%arrayValuesToKeys()%getTotalHere()%partyRoomIsInFrontRow()
%asArray()%getTranslation()%positionAtLeast()
%asInt()%getVar()%positionAtMost()
%asNull()%getWeight()%printValue()
%asString()%globalDebug()%pulseActivity()
%attackCheckAttempt()%hasAffectItem()%pulseActivityDuration()
%attackCheckOpponentCount()%hasItem()%pulseTick()
%attackDeny()%hates()%pulseViolence()
%buffGetByLabel()%height()%pulseViolenceDuration()
%calculate()%hitsCond()%pure()
%canAttack()%int()%purge()
%canBodyAttack()%isAffectedBy()%randBetween()
%canSee()%isAffectedByBits()%randK()
%canTake()%isArray()%randPlayer()
%canTarget()%isAwake()%roomGetExits()
%canWear()%isCharm()%roomGetItems()
%clone()%isDark()%roomGetMobs()
%combatClear()%isDaytime()%roomGetNpcs()
%combatStart()%isEarlyTwilight()%roomGetPcs()
%combatStop()%isEquipmentLocation()%roomGetRandom()
%commandGetFlags()%isEquippedItem()%roomGetStat()
%containerGetStat()%isEvil()%roomSetStat()
%contextContinue()%isExit()%runCommand()
%contextDisown()%isExtra()%saveVersusBreath()
%contextGetId()%isFighting()%saveVersusBreathMod()
%contextGetVar()%isFloat()%saveVersusParalyze()
%contextGetVars()%isFollowing()%saveVersusParalyzeMod()
%contextIsValid()%isGhost()%saveVersusPetrify()
%contextKill()%isGladiating()%saveVersusPetrifyMod()
%contextPause()%isGood()%saveVersusPrayer()
%contextSetVar()%isHunting()%saveVersusPrayerMod()
%corpseGetId()%isImmortal()%saveVersusRod()
%corpseGetName()%isImmune()%saveVersusRodMod()
%corpseGetStat()%isInt()%saveVersusSpell()
%corpseIsDecapitated()%isItem()%saveVersusSpellMod()
%corpseIsNpc()%isItemHere()%scriptCall()
%corpseIsPc()%isItemId()%scriptCallMultiple()
%corpseSetStat()%isJailed()%scriptUsurp()
%damage()%isLateTwilight()%serialize()
%deathtrap()%isLeader()%serverGetProfile()
%deleteEntityVar()%isLinkDead()%serverLog()
%deletePlayerVar()%isMob()%setEntityVar()
%deleteSavedVar()%isMobHere()%setHatred()
%deleteVar()%isMobId()%setPlayerVar()
%doZoneActivate()%isNeutral()%setSavedVar()
%dream()%isNighttime()%setSilenceOff()
%drinkGetStat()%isNpc()%setSilenceOn()
%drinkSetStat()%isNull()%setVar()
%echo()%isOutside()%skillAffectAdd()
%echoTo()%isPc()%skillAffectExists()
%eqPos()%isPet()%skillAffectItemExists()
%equipment()%isResistant()%skillAffectMerge()
%equipmentLocationInfo()%isRoom()%skillAffectRemove()
%ereg()%isRoomId()%skillCheckGain()
%eregi()%isString()%skillGetELevel()
%evades()%isSusceptable()%skillGetId()
%exitGetStat()%isValid()%skillGetQuality()
%exitSetStat()%isVampire()%skillSetELevel()
%fastCommand()%isWaiting()%spell()
%filterActionWords()%itemClearType()%sprintf()
%filterGroup()%itemGetLoadCount()%string()
%filterId()%itemGetStat()%stringExplode()
%filterKeyword()%itemInitType()%stringFind()
%filterNotGroup()%itemIsTypeAffect()%stringFindI()
%filterNpcs()%itemIsTypeArmour()%stringFormat()
%filterOut()%itemIsTypeArrow()%stringGetSize()
%filterPcs()%itemIsTypeBoat()%stringIsPrefix()
%filterVisible()%itemIsTypeBodyPart()%stringIsPrefixI()
%float()%itemIsTypeBow()%stringLcFirst()
%follow()%itemIsTypeContainer()%stringPad()
%gainExperience()%itemIsTypeCorpse()%stringRepeat()
%getAffectItems()%itemIsTypeDrink()%stringReplace()
%getBounded()%itemIsTypeFood()%stringReplaceI()
%getClass()%itemIsTypeHerb()%stringSubString()
%getContainer()%itemIsTypeKey()%stringToLowerCase()
%getContents()%itemIsTypeLight()%stringToUpperCase()
%getContinent()%itemIsTypeMissile()%stringToWords()
%getEntityVar()%itemIsTypeMoney()%stringTrim()
%getEquipment()%itemIsTypeNote()%stringUcFirst()
%getEquippedItem()%itemIsTypeOther()%stringUcFirstAll()
%getFollowers()%itemIsTypePen()%stun()
%getGender()%itemIsTypePotion()%sunrise()
%getGenderPossess()%itemIsTypeRod()%sunset()
%getGenderTarget()%itemIsTypeScroll()%triggerDispel()
%getGuildId()%itemIsTypeStaff()%triggerInvoke()
%getHomeId()%itemIsTypeTome()%unserialize()
%getHomeTownRoomId()%itemIsTypeTrap()%updatePosition()
%getHuntDirection()%itemIsTypeTrash()%weaponGetType()
%getHuntPrey()%itemIsTypeTreasure()%weatherGetId()
%getId()%itemIsTypeWand()%where()
%getInventory()%itemIsTypeWeapon()%worldGetItems()
%getItemPointer()%itemIsTypeWorn()%worldGetMobs()
%getItemsWithId()%itemSetStat()%worldGetNpcs()
%getLanguage()%itemZap()%worldGetPcs()
%getLanguageId()%jumpTo()%zoneGetItems()
%getLeader()%load()%zoneGetMobs()
%getLevel()%math()%zoneGetNpcs()
%getLoadCount()%mobCheckImmortalLevels()%zoneGetPcs()
%getMax()%mobGetAffectItemsById() 
%getMaxIndex()%mobGetAffectItemsBySkill() 
%getMin()%mobGetStat() 

Resolutions

Details  |  Rooms  |  Mobiles  |  Items  |  Exits  |  Buffs  |  Races

This operator is powerful enough to warrant an entire section describing its use. Unlike other operators the resolution operator "->" is highly contextual and the actual functionality is completely dependent on the leftmost value of the resolution. Since this operator may be strung together in sequence to resolve a multi-level path for a container, it may not always behave as expected when the leftmost operand does not support multi-level resolution. This is true of strings. Currently