Random Generation in CoffeeMud 5.9

coffeemud logo

Introduction to Random Generation

Random generation in the realm of mud areas, rooms, items, mobs, and so forth is a strange proposition.  In the end, it always boils down to selecting among known, fixed, and constant alternatives that make sense in a particular context.  For example, a mob that might be named "George" or "A path in the forest" is certainly random, but doesn't make much sense, so we tend to restrict our alternatives in some way.  Also, selecting evenly among alternatives, while certainly the most common thing you will do, also sometimes doesn't make sense.  A random Moon description might include words like "full", "new", "crescent", "half", and "BLUE".  However, just because you want the "BLUE" alternative to be available, doesn't mean you want it to have an equal chance of describing your moon as the other choices.   Also, sometimes the context in which an alternative makes sense can be extremely narrow.  Having "a rat" as a random monster in your dungeon almost always makes sense, except in the "cat room".  Again, judgement must come into play. And lastly, the more random a particular area is, the more it will seem like every other random area.  Randomness is best used to select overall themes for an area, which the content reflects, as opposed to every room having random content and descriptions.

All of these considerations and more have gone into the devising of a random mud engine, and particularly to the format of the input data it uses.  This engine receives a series of sets of alternatives which may include a relative weight for each alternative, and potentially the context in which each alternative applies or doesn't apply, and then makes selections and instantiates real mud objects based on those selections.  The input to the engine is a very specifically built XML file, and the output is actual mud objects (mobs, items, areas, rooms, or all the above) in your game.

Overview of XML Tags

The random generator works by reading a specially-written XML document that contains tags describing the object or objects to generate.  For example, area generation looks for tags named <AREA />, mobs for <MOB />, items for <ITEM />, rooms for <ROOM />, and so forth.  

The embedding of tags can also be significant.  For example, to generate a mob from a given <MOB /> tag, the tag must either contain a NAME attribute, or a <NAME /> tag embedded inside the <MOB /> tag.  Another example would be that
room tags may contain mob and item tags.

Generation sometimes requires that a specific starting object be named by ID, in which case an ID attribute may be found on the tag, allowing it to be referenced globally, no matter where it is embedded.

The basic tag types are AREA, ROOM, MOB, ITEM, and STRING.  Any tag that contains other tags of the same tag type is a Container tag, and usually has rules in the form of special attributes for how to select among the alternatives in the container.  In cases where one of something is called for, but multiple options are available, and no rules are found for how to select among them, a random roll will be made.  In cases where one or more of something is allowed, and multiple options are available, all the alternatives found will be selected.

Each basic tag type is used to build an object of that type.  For instance, the MOB tag is used to build a MOB.  Therefore, each basic object type must have other tags or attributes to "fill in the details", such as name, level, and so forth.  These Details may be defined as variables on the command line using GENERATE or by the "define" attribute, or may be given as an attribute of the basic tag, or as other tags inside the parent tag.  A Detail given as an attribute always supersedes any detail given as internal tags, no matter what.  A detail found as an defined variable identifier, supersedes both tags and
attributes.  See the glossary for more tails on each major tag type.

Basic tags may also have special pre-defined variables to help give some context to help with their parsing, and will often cause variables to be defined as their details are filled in.  Basic tags also have certain required details which must be resolved for the
object to be created, and other optional details which may or may not be given, and which are extremely object-specific.  Again, the glossary entry for each basic tag type will have more information about this.

Tags are always evaluated recursively, from first to last.  Any tag may contain zero or more of the following meta-attributes:
  
id exposes the tag to either the Generate command, or to the "insert" or "like" attributes.
load the xml inside the file named is inserted into the tag
fromsimilar to from, except only the tag in the file with the same id is merged with the tag
content_load the text inside the file names is returned as the value of the tag.  Variables in the content are handled.
like a comma separated list of other tag "id"s of the SAME TYPE. These may NOT be container tags.  This will allow the current tag to be parsed as if it contained the same tags and attributes as the listed tags. This is useful for making one-off variations on existing tag structures.
insert a comma separated list of other tag ids. The targeted tags may be of any type, and may be containers.  It will cause the tags to be parsed and the resulting tags added as contents of the host tag as if they were already inside it.  Remember, the listed tags will be parsed first, so any "condition", "select" or other operations will occur.
copyof a tag "id" or standard class id. This will cause the stats and attributes and other details of the listed items into the current object.
validate a boolean expression which must evaluate to true for the tag to be finally built into an object.  Check "condition" below for more information....
condition the value is a boolean expression which must evaluate to true for the tag to be included in its parent.  This is similar to "validate" except that "condition" determines whether a tag is among the allowed choices, whereas "validate" determines whether, after being chosen, it is finally built into a final thing (whether string, mob, item, whatever).  These expressions may use boolean operators like AND and OR and NOT (or !), string constants are always single-quoted 'string', string comparison operators include = , !=, and IN to check to see if the lhs string is a substring of the rhs string. Numeric comparisons may be made as well, and  numeric comparison operators include > < >= <= != =.  Parenthesis may be used to group sub-expressions. Defined variables may be included, but only if preceded by a $ character. For instance, to check if the variable "bob" is equal to "bobvalue", you would enter $bob='bobvalue'.  Undefined string ids are treated as ''.  Remember that in XML, a < and > characters can not appear in attribute values, which is why they must be written as &lt; and &gt; in your xml.
define this attribute is only used if its "condition" is met, and it is "selected" by its parent tag, if applicable.  It is a comma separated list of any combination of the following:
  • "id": either a new or existing identifier, in which case the value that this tag resolves to will be set to that identifier, allowing it to be used in "condition", tag values, or other places.
  • "id=value": will set the new or existing identifier "id" to the given constant "value".
  • "id+=number": see below
  • "id*=number": see below
  • "id-=number": see below
  • "id/=number": Will attempt to evaluate the existing value of the identifier"id" as a number, and perform the given operation upon it with the "number" given. For instance "bob+=3" will add the number 3 to the current value of the identifier "bob".  Any undefined "id" will be treated as if it were 0. When dealing with areas, there is an extra feature of defined identifiers.  An identifier whose name starts with "_" will persist for every tag and object in the room's "room group".  An identifier whose name starts with "__" will persist throughout the entire area.  Otherwise, any variables defined using this command will persist only for one room.
predefine identical to "define", but always evaluated when encountered.
tagdefineidentical to "predefine", but the value will be the post-processed (SELECT, INSERT, etc) tag itself
select used mostly by container tags, this attribute allows you to specify how multiple choices are resolved by this tag.  More than one selection may be made, which makes sense when selecting MOB tags for a ROOM.  However,  sometimes it does not, such as when selecting a NAME for a MOB.  In those cases, any remaining multiple-choices are always selected randomly from.  Possible values are:
  • "all": always selects every choice.
  • "any-X": selects any X** of the choices, without repeating.  Make sure you have another choices to cover the possible value of X!
  • "pick-X": same as "any-X", but the tag choices will be checked for the
    • "pickweight" is container-entry attribute, and is used only when the parent tag is using 'select="pick-X" ' as a relative weight when selecting among the choices.
  • "limit-x": selects up to X** random choices, but less is OK too if no more.
  • "repeat-X": always selects every choice, and treats the choices as if  enough of them actually existed to select X** of them, even if not enough choices were given.
  • "none": always selects none of the choices (why would anyone use this?!)
  • "first": selects the first choice (another stupid one)
  • "last": you guessed it, select the last choice
  • "first-X": selects the first X** choices.
  • "last-X": selects the last X** choices.
** Where you see X above, this may be a number, or a math formula or math expression. (see mud help on math formulas/math expressions)
merge must be "true" if two tags with the same ID are included in the same xml document.  It permits some of the tag parameters, and all of the content tags, to be merged together into a single referenced tag.  In this circumstance, child tags of parent tags which are being merged may optionally include "merge=false" to prevent duplicates from being formed.  

Merge can also be set to "over" to cause one tag with an ID to always overwrite another with the same id. If more than one tag is set to merge="over", a number can be added after the word "over" to give priority.  For example, a tag with merge="over9" would always overwrite a tag with the same ID and merge="over4".
pickweight a helper attribute for the "select" attribute, when a "pick" value is used by the select attribute.  See "select" attribute above.
action used by string-type choices to inform the engine on how to combine the multiple choices into a single string.  Possible values include:
  •           "append": append the tags value to the string as built so far.
  •           "replace": completely replace any string build so far with this ones value.
  •           "prepend": always put this strings value at the beginning of the final string
requires a comma-separated list of variable identifiers which must have already been defined before this tag can be evaluated.  Such variables are usually defined by the user of the GENERATE command, but can also be defined at parse-time by the "define" attribute, if you are creative.  Each item in the list is of the format "id=type", so that the parser can check to see not only if the variable is defined, but that it is defined properly.  Possible types include "#" for a number, "int" for an integer, "$" for a string, or a semicolon-delimited list of possible string values.

Tag values:
A non-container non-basic tag will typically have a string value.  This value may contain any embedded variables or identifiers, so long as they are preceded with a $ character.

A string beginning with a $ character will be assumed to be an identifier, and will be searched for within the list of defined variables and identifiers.  If the identifier resolves to a tag, the tag will be parsed as a string.  If the identifier resolves to
a string, so much the easier.

Defined variables or tag names can also be embedded in {} characters; for example: ${ame}. When embedded in this way, the name may be preceeded by:
  • "u:" to force to all-uppercase
  • "l:" to force all-lowercase
  • "p:" to force plural
  • "j:" to force javascript and mobprog-safe
  • "1:" to encourage to one line (remove tabs and cr/lf)
  • "c:" to force to be capitalized (first letter upper, rest lower).
  • "_:" to remove punctuation and replace spaces with underscores.
Special embedded variables:
  • $SYSTEM_RANDOM_NAME:[NUMX]-[NUMY] generate a random name with between NUMX and NUMY syllables.
  • ${STAT:[STATNAME]} embed the value from another stat on the same object.  STATs are things like NAME, DISPLAY, DESCRIPTION, etc...
  • ${STAT:[PATH]:[TO]:[ANOTHER]:[OBJECT]:[STATNAME]} embed the value from another objects stat, potentially in a different room. Where path-to-another-object may be: ROOM to refer to the room containing the object, NORTH,SOUTH,EAST,WEST,UP,DOWN,NORTHEAST..etc.. to specify a room in a specific direction, ANYROOM to specify any room connected to this one, MOB to specify any mob in the room, ITEM to specify any item in the room, AREA to specify the area object, or AREAGATE to specify a connecting room outside the area.  For example a string such as: "To the east is the residence of ${STAT:ROOM:EAST:MOB:NAME}" would embed the name of a mob in a room to the east of the current room. This command may internally cause post-processing if necessary, and so is almost guaranteed to always work unlike some of the special ROOM_ tags.
  • (a(n)) will remove any indefinite or definite articles from the string immediately following it and replace it (or insert) either "a" or "an" depending on the first letter of the word.

Using the Random Generator

There are currently two ways to use the Random Generator, one is the Archon GENERATE command, and the other is the Area type "StdAutoGenInstance".

Generate Command:

The most straightforward way to access the random generator is using the Archon GENERATE command.  The usage is as follows:

GENERATE [OBJ TYPE] [ID] (FROM [FILENAME]) ([VAR]=[VAL]...) ([DIRECTION])

This command uses an xml file to generate random content for your mud.  This content can be anything from whole areas, to rooms, mobs, items, or simple strings. By default, the content is built from the file in resources/randareas/example.xml, though the builder may specify his or her own xml file path as one of the many arguments.  The arguments, briefly, are:
OBJ TYPE One of the following: AREA, ROOM, MOB, ITEM, QUEST, or STRING
ID one of the "id" xml attributes defined on any tag in the XML file. Use GENERATE STRING LIST for a list of all "id" attributes defined in your file.
FROM "path/to/xmlfile.xml" An optional argument to specify your own xml file, with the resources directory being the default root.
VAR=VAL One or more variables and their definitions.  Many tags will have a specific set of required variables which must be defined in order for the content to be generated.  Failing to specify one of the required variables will cause an error message listing the variables which must be defined, and the type of data required for the variable.  Variable types which list numbers as their data types may also have math expressions values (so you can use random numbers).  See the help on MATH EXPRESSION for more information on this.  In addition to required variables, you may also use the space to enter one or more "override" values.  Many object fields (such as LEVEL for mobs and items, or NAME, etc) as well as the XML id tags, can have their "random" values overridden by defining them using the generate command.
DIRECTION This applies only to ROOM and AREA object types.  The object, if successfully generated, will be linked to the current room that the player is standing in, in the direction they specify.

The GENERATE command is an interesting way to deliver large amounts of dynamic content for your world, though it can never replace the caring touch of a real, creative builder.  If anyone is interested in writing their own xml content, please open up the /resources/randareas/example.xml file and begin reading it and all of the LOADed files. Use those file as an example on how to construct your own.

Examples of the Generate Command:
generate area maze_dungeon from randareas/example.xml areasize=50 areaname=test level_range=10?20 aggrochance=50 theme=kobolds south

generate string list

StdAutoGenInstance Area Type:

The StdAutoGenInstance area type is specially formulated to replace any rooms of its own with auto-generated rooms and content.  

This area type is, firstly, an Instance generator.  That means that each group that goes into the area will have their own unique generated rooms to play in, which will be different from any other groups, and will persist until the group gets tired of playing it (causing the area to time-out and be garbage collected).

This area type also permits the path and name of the top-level random generation xml file to be specified, where the /resource directory is considered the default path root.

Lastly, any required or optional variables. Many tags will have a specific set of required variables which must be defined in order for the content to be generated.  Failing to specify one of the required variables will cause the area generation to fail, putting an error message in your mud.log file.  Variable types which list numbers as their data types may also have math expressions values (so you can use random numbers).  See the help on MATH EXPRESSION for more information on this.  In addition to required variables, you may also use the space to enter one or more "override" values for existing defined things.  One special variable is passivemins which can be set to the number of minutes an instance will remain passive before being deleted, with a default of 30 minutes.

Glossary of XML Tags

AREA tags:
As the highest-level possible tag, an area is parsed only with the variables it is given on the GENERATE command line, and using whatever it can find in its XML contents for its details.  All details mentioned below will automatically cause a variable to be defined or re-defined when they are parsed.  The variable will be called "AREA_DETAILNAME".  For instance "AREA_CLASS" for class, and "AREA_NAME" for name.

The layout of an area will cause its rooms to be logically grouped up into streets, "leaf" rooms (rooms with only one exist), and other logical groupings.  "leaf" rooms are always done first, followed by streets, and others.  The layout will automatically define certain variables for each room to help with parsing the rooms details.  These variables include:

  • $AREA_NUMLEAFS: the number of leaf rooms for the whole area
  • $ROOMTAG_NODETYPE: one of surround, leaf, offleaf, street, square, interior
  • $ROOMTAG_NODERUN: for streets, which way they run.  Values are ns, ew, nwse, nesw
  • $ROOMTAG_NODEFLAGS: various rooms flags. Values include: corner, gate, intersection, tee, offleaf
  • $ROOMTAG_NODEEXITS: comma separated list of all exits from a room
  • $ROOMTAG_NODEGATEEXIT: if this room is a "gate" rooms, which direction is the gate in.
  • $ROOMLINK_N, $ROOMLINK_S, $ROOMLINK_E, $ROOMLINK_W, etc: "true" if an exit exists that way.
  • $ROOMTITLE_N, $ROOMTITLE_S, $ROOMTITLE_E, $ROOMTITLE_W, etc: if already done, the title of a room that way.
  • $NODETYPE_N, $NODETYPE_S, $NODETYPE_E, $NODETYPE_W, etc: type of room node in that direction, if any.

Required details:

  • "CLASS": The CoffeeMud class type to use to create the area.
  • "NAME": The name of the area.  Must be unique to your MUD.
  • "LAYOUT": The name of the layout generator to use.  At the moment, supported layouts include MAZE, BOXCITY, BOXCITYSQUARE, CROSS, GRIDCITY, TREE, APARTMENT
  • "SIZE": The number of rooms to create in the area.

Optional objects: (See below for details on these object tag types and their details)

  • "AFFECT"
  • "BEHAVIOR"
  • "ROOM"

Optional details: (See Archon's Guide)

  • "CLIMATE"
  • "DESCRIPTION"
  • "THEME"
  • "BLURBS"
  • "PREJUDICE"
  • "BUDGET"
  • "DEVALRATE",
  • "INVRESETRATE"
  • "IGNOREMASK"
  • "PRICEMASKS"
  • "AUTHOR"
  • "ATMOSPHERE" 

ROOM tags:
Parsed with variables from the generate command, and from any defined variables internal, and from any internal tags and attributes, and from any variables defined by its AREA tag. As with areas, its details will cause variables beginning with ROOM_ to be defined.

Required details:

  • "CLASS"
  • "TITLE"
  • "DESCRIPTION"

Optional Objects: (See below for details on these object tag types and their details)

  • "MOB"
  • "ITEM"
  • "AFFECT"
  • "BEHAVIOR"
  • "EXIT"

You can also specify a "LAYOUT" attribute on a room tag, in which case all rooms contained inside that room tag (or inserted, or whatever) are used to build multiple rooms from that layout, much as specified above on the AREA tag.

MOB tags:
Parsed with variables from the generate command, and from any defined variables internal, and from any internal tags and attributes, and from any variables defined by other room tags. As with areas, its details will cause variables beginning with MOB_ to be defined.

Required details:

  • "CLASS": normally the CoffeeMud class the mob will be made from, though it may also be the word catalog in order to select a mob from your catalog, in which case "name" also becomes a required detail.

Optional Objects:

  • "MOB"
  • "ITEM"
  • "AFFECT"
  • "ABILITY"
  • "BEHAVIOR"
  • "FACTION"

Optional details: (See Archon's Guide)

  • "RACE"
  • "HPMOD"
  • "LEVEL"
  • "NAME"
  • "DISPLAY"
  • "DESCRIPTION"
  • "MONEY"
  • "ALIGNMENT"
  •  "DISPOSITION"
  • "SENSES",
  • "ARMOR"
  • "DAMAGE"
  • "ATTACK"
  • "SPEED"
  • "TATTS"
  • "EXPS"
  • "IMG"
  • "FACTIONS"
  • "VARMONEY"

(plus or minus others depending upon class)

The "RACE" detail can be the name of a race, or resolve to a RACE tag, see below.

ITEM tags:
Parsed with variables from the generate command, and from any defined variables internal, and from any internal tags and attributes, and from any variables defined by other room tags. As with areas, its details will cause variables beginning with ITEM_ to be defined.

Required details:

  • "CLASS": normally the CoffeeMud class the item will be made from, though it may also be the word catalog in order to select an item from your catalog, in which case "name" also becomes a required detail. 

    This value may also start with the string "metacraft:", in which case the remainder of the "class" value becomes either the name of the item to metacraft, the word "anything",  "all", or the words "any-" or "all-" followed by the ID of the common skill to use.  "metacraft:" class strings may also end with the characters "<" followed by a math expression  evaluating to an upper level limit for the item to craft, ">" for a lower limit, or "=" followed by a the base class ID to to filter in.  If the ID of the common skill is "resources" or "farmables", then raw resource items will be generated instead.

Optional Objects:

  • "MOB"
  • "ITEM"
  • "AFFECT"
  • "CONTENT"
  • "BEHAVIOR"
  • "EXIT"

Optional details: (See Archon's Guide)

  • "USES"
  • "LEVEL"
  • "ABILITY"
  • "NAME"
  • "DISPLAY"
  • "DESCRIPTION"
  • "SECRET"
  • "PROPERWORN"
  • "WORNAND",
  • "BASEGOLD"
  • "ISGETTABLE"
  • "ISREADABLE"
  • "ISDROPPABLE"
  • "ISREMOVABLE"
  • "MATERIAL"
  • "DISPOSITION"
  • "WEIGHT"
  • "ARMOR"
  • "DAMAGE"
  • "ATTACK"
  • "READABLETEXT"
  • "IMG"
  • "NOWEAR" (set to true to prevent the item from being automatically worn by mobs)

(plus or minus many many others depending upon class)

"ShopKeeper" type classes may use "SHOPINVENTORY" tags to hold ITEM, MOB, or ABILITY tags to designate what else is sold.  Also, the SHOPINVENTORY or those ITEM, MOB, or ABILITY tags  may contain optional PRICE or NUMBER attributes.


AFFECT tags

ABILITY tags:

CULTURALABILITY tags

BEHAVIOR tags

Required detail: 

  • "CLASS"

Optional Detail: 

  • "PARMS"
Optional Details that apply only when this tag applies to a RACE tag:
  • "PROFF"
  • "LEVEL"
  • "QUALIFY"

CONTENT tags:
Content tags:
A pure container tag that contains one or more ITEM tags, as above.

EXIT tags:
Exit tags:
Required detail: 

  • "CLASS"

Optional Objects: 

  • "AFFECT"
  • "BEHAVIOR"
Optional Details:
  • "NAME"
  • "DISPLAY"
  • "DESCRIPTION"
  • "DOOR"
  • "LEVEL"
  • "ABILITY"
  • "ISREADABLE"
  • "DISPOSITION"
  • "READABLETEXT"
  • "HASADOOR"
  • "DEFCLOSED"
  • "HASALOCK"
  • "DEFLOCKED"
  • "KEYNAME",
  • "CLOSEWORD",
  • "OPENWORD",
  • "CLOSEDTEXT"

RACE tags:

Required detail: 

  • "CLASS"
  • "NAME"
Optional Objects:
  • "WEAPON": tag which should contain an ITEM tag, denoting the creatures natural weapon
  • "RESOURCES": tag which should contain one or more ITEM tags, denoting racial resources
  • "OUTFIT": tag which should contain one or more ITEM tags, denoting the racial outfit
  • "ABILITY"
  • "CULTUREABILITY": same as ABILITY tag, but these are cultural abilities
  • "AFFECT"
Optional Details: 
  • "CAT"
  • "VWEIGHT"
  • "BWEIGHT"
  • "VHEIGHT"
  • "FHEIGHT"
  • "MHEIGHT"
  • "AVAIL"
  • "LEAVE",
  • "BODYKILL"
  • "AGING"
  • "HELP"
  • "BREATHES"
  • "ARRIVE",
  • "HEALTHRACE"
  • "BODY"
  • "WEAPONRACE"
  • "DISFLAGS"
  • "EVENTRACE"
  • "WEAR" - either a bitmask number, or wear locations names set equal to true to forbid, or false to allow, e.g (mouth=true back=false left_wrist=false)
  • "ESTATS","ASTATS","CSTATS","ASTATE","STARTASTATE" - either a | delimited stat list, or a series of var=value, e.g. (STRENGTH=5 HITS=2 ATTACK=2 etc..)


FACTION tags:
Required details: 

  • "ID"
  • "VALUE"


QUEST tags:
Optional parameter: 

  • "QUEST_TEMPLATE_ID"
The QUEST tag is supremely unique in that it does not represent an object in your world, or a property of some object in your world, but instead represents a relationship between players and your world by giving them tasks to perform.  In the end, a QUEST tag must resolve to a complete Quest Script document/string, which is then submitted to CoffeeMud's Quest Manager for execution, monitoring, and cleanup.  I won't go into the complete details of what goes into a Quest Script here, however.  Instead, you should check the Game Builder's Guide for a complete breakdown of a Quest Script.
Quest Scripts can be built from the ground up by assembling a String consisting of each line of the quest script, separated by %0D characters.

Scripts can also be built, however, by utilizing one of the existing Quest Maker templates.  These are the templates found in the /resources/quests/templates directory.   They are partially built Quest Scripts which, when run through the Quest Maker Wizard, can be filled out manually by a builder.  However, those templates can also be run through the Random Generator to generate randomly what the builder would normally have to type in manually.  

To create a quest script by running a Template through the random generator, you would specify the full path or ordinary name (e.g. normal_capture1) of the Template in a tag parameter on the QUEST tag called QUEST_TEMPLATE_ID.   When this is done, the quest script and its variables are extracted from the template.  The variables in the template then become required details for the QUEST tag.  When those details are resolved into STRINGs, the values are substituted into the template's quest script and then returned by the tag.

To discover the required details for a particular template, you should open up that template *.quest file and scan down the top part of the file whose lines begin with #.  When you see a line that begins with #$, you know you are looking at a variable definition whose variable name is a required detail for the QUEST tag using that template.
To save you some time, numerous existing quest templates have already had associated snippets of Random Generator XML written to demonstrate the above.  These are found in the /resources/quests/random directory, and can be indirectly accessed from the same /resources/randareas/example.xml that is used to generate random areas, rooms, mobs, etc.  This means that you can use the GENERATE command to generate a random quest of any type anywhere in your entire world by entering:

generate quest all_quests template=random "expiration=20 minutes"

The "template" variable specifies that you want any available quest template.  The "expiration" variable definition ensures that the quest is not saved to your database, and will in fact be destroyed after running for 20 minutes.  If you leave it off, or replace it with a "duration" definition (see the Game Builders Guide), then the quest will be writte to the database and become a persistant feature of your world.

If you look through the examples in /resources/quests/random , you will see much that is similar to Random Area documents. Strings and other selections are being chosen from, conditions are set for some values over others, etc.  However, since many of the quest Templates actually require that an already existing mob, or item, or even set of mobs in your world be selected as subjects for the quest, the Random Generator engine had to be extended to support not only the creation of new mobs, items, rooms, and areas, but the selection of existing ones inside the world.  To do this, see the next section on the OBJECT tag.
OBJECT tags:
This tag type is unique in the sense that it can contain any MOB, ITEM, AREA, ROOM, or other main object types, intermingled.  It is also unique in that it need not resolve to the creation of any new object at all, but can instead be used to select from an existing object in your already existing world.

To do the later, the OBJECT tag value mnust begin with SELECT: and be followed by an MQL query string.  When this is done, the OBJECT tag will take on the properties of whatever was selected by the query.  See the next section on MQL for how these queries work.

Notes on MQL

MQL Stands for MUD Query Language.  It's purpose is to allow the Archon, or a random quest xml document, to select existing objects in the game, or the properties of existing objects.  

The structure of MQL is similar to SQL in that all MQL statements are of this structure:

SELECT: [property, property, ..] FROM [object set]  WHERE [object comparison, object comparison]
* note the colon : after the word SELECT above.

The SELECT clause defines the properties you wish to be returned from the MQL statement.
The FROM clause defines the set of objects that you might want to return the properties of.
The WHERE clause defines the conditions under which any member of the set in the FROM clause may be included in the final results.

A FROM clause can be a simple world set term, such as one of the following:

  • A CMFS file path to a CMARE file, such as ::/resources/map/plains.cmare
  • AREAS to use the set of all world areas
  • ROOMS to use the set of all existing world rooms
  • MOBS to use the set of all existing world mobs
  • ITEMS to use the set of all existing world items
  • In case where a qualifying object is implied, AREA can be used to refer to that specific area.
  • Another SELECT: statement in parenthesis, such as: SELECT: name from (SELECT * from AREA)
The FROM clause can also include narrowing suffixes.  A narrowing suffix comes after the simple term, and is separated from it by a backslash \.   For example, if your from clause looks like SELECT * FROM AREAS\ROOM  , then the ROOM portion is the narrowing suffix of the AREAS term.  You can also continue adding more narrowing suffixes as needed.  For example: SELECT * FROM AREAS\MOBS\EQUIPMENT  .  Each suffix narrows or alters the term immediate before it, and the entire FROM clause will end up reflecting the type of object described by the final term, whether it be simple, or a narrowing term.

The following are useful narrowing terms:
  • AREAS to use the unique set of areas in which the prior term is located
  • ROOMS to use the unique set of rooms in which the prior term is located, or which the prior term contains
  • EXITS to use the unique set of exits in which the prior term is located, or which the prior term contains
  • MOBS to use mobs in a room or area, or nearby mobs for others
  • MOB to use the set of all mob contained in the prior term, or ensure the simple Mob result of a query
  • ITEMS to use all items in a roow or area, or nearby items for others
  • ITEM to use the set of all items contained in the prior term, or ensure the simple Item result of a query
  • OWNER to use the set of all item owners of the prior term, if it was items
  • FACTIONS to use a set of all mob factions, where ID is the faction id, and VALUE is the numeric value
  • PLAYERS, PLAYER to use the set of all players contained in the prior term
  • RESOURCES to use the racial or material components of a mob or item
  • NPCS to use the set of all non-player mobs in a room or area, or nearby npcs for others
  • NPC to use the set of all non-player mobs contained in the prior term, or ensure the simple Mob result of a query
  • EQUIPMENT to use the set of all  worn items of the prior term
  • ABILITIES to use the set of all  abilities of the prior term
  • PROPERTIES to use the set of all  uninvokable effects of the prior term
  • EFFECTS to use the set of all  permanent or temporary effects on the prior term
  • BEHAVIORS to use the set of all  behaviors of the prior term
Be careful when using narrowing terms to make sure they make sense for the term prior to them.  For example, if importing mobs from a cmare file, AREAS will not likely resolve to anything, since the mobs aren't in the world yet.

The SELECT: clause can include one or more comma-delimited properties of  the objects in the from clause, or it can be an asterisk *, or a period ., to refer simply to the FROM objects themselves.  It can also be a string or numeric literal, or an XML tag when embedding MQL in a random quest document.    Different kinds of objects have different kinds of properties, so it is tricky to define precisely what a legal and illegal object property might be.  Choosing incorrectly will usually just result in an empty string "".

To summarize, valid property terms include:
  • A valid property of an object from the FROM set, e.g NAME, CLASS, etc..
  • A string or numeric literal, e.g. "Bob The Builder", 12.34, etc..
  • An asterisk * or a period . to refer to the FROM set object itself.
  • Another MQL statement, e.g. (SELECT: * FROM areas\mobs)
  • An XML tag id, e.g. $tagname
An example of a legal property might be the property CLASS, since it applies to everything from areas and rooms, to mobs, and items.  NAME is also a property that almost all objects have.  Beyond this. using the GMODIFY command might be the simplest way to get a list of valid properties for a specific type of world object, or objects imported from cmare files.  

As mentioned previously, SELECT: clause properties can be separated by commas in order to select more than one.  For example: SELECT: class, name FROM areas\mobs would show the class id and name of every mob in your game.  

SELECT: clauses can also include an AS qualifier for each property selected.  This has only the effect of changing the apparent name of the property for other parts of the system.  For an example using the WHERE command to issue MQL: WHERE AREA SELECT: class as classid, name as mob_name FROM areas\mobs would show the same results as the previous example statement, but with different name tags for the class and name properties.  This might be important when using an embedded SELECT: statement as your FROM clause, since you can only select properties that the embedded clause has returned, by the names they were given.

SELECT: clauses, similar to FROM clauses above, can include narrowing terms.  Like FROM clauses, these narrowing terms are separated by backslashes \.   SELECT clauses, at the moment, only support one narrowing term: COUNT.  The purpose of the COUNT term is to report the number of times the value of the previous terms appears in the rest of the FROM: clause.  For example, suppose you wanted to know the number of times each mob name is used, to do that, you might enter SELECT: name, name\count FROM areas\mobs

Lastly, SELECT: clause can contain aggregating prefixes before a property term, which will transform the final result set in some way by aggregating the rows according to the prefix.  Prefixes, like suffixes, are separated from the property term by a backslash \.  The value aggregating prefixes are:
  • MEDIAN to return only the median value of all the property terms in the existing result set
  • MEAN to return the mean value of all the property terms in the existing result set
  • COUNT to return the count of the number of  items in the result set
  • UNIQUE to include only one row where the property is of any given value
For example, to quickly count the mobs in your game, you might enter SELECT: COUNT\* from AREAS\MOBS

The WHERE clause contains one or more conditions, which you can further compare using connectors like AND, OR, or parenthesis to group conditions together.  Each condition consists of  two terms separated by a comparator.  Value comparitors include = (equal to), <> (not equal to), > (greater than), < (less than), >= (greater or equal), <= (less or equal), IN (in a set or object group, or a substring of), or LIKE (matching a ZAPPERMASK).

A condition consists of two property terms, similar to those described in the SELECT: clause above, except that condition terms can not use aggregating prefixes.  Narrowing suffixes, however, are permitted.  For example NAME = 'Bob' is checking whether the NAME property of an item in the FROM clause is equal to the string literal "BOB".  If it is, when that condition is true.  Putting it together then, to show the mobs in your game whose names are EXACTLY "BOB", you might do SELECT: * FROM areas\mobs WHERE name="BOB". This works because NAME is a property of every mob in the AREAS\MOBS from set, and can be compared with the word "BOB".

Condition statements are grouped together into conditions using AND or OR.  For example, chaning the above condition to WHERE name="BOB" OR name="JOE" would expand the number of possible results by one name.