Annotation of 43BSD/games/ddl/doc/doc.ms, revision 1.1

1.1     ! root        1: .RS
        !             2: .ds CF "\(co 1982 UCLA Computer Club
        !             3: .TL
        !             4: A Brief Description of UCLA
        !             5: Dungeon Definition Language (DDL)
        !             6: (Second Edition)
        !             7: .AU
        !             8: Bruce Adler
        !             9: Chris Kostanick
        !            10: Michael Stein
        !            11: Michael Urban
        !            12: .AI
        !            13: University of California
        !            14: Los Angeles, CA 90024
        !            15: .AB
        !            16: This document describes Dungeon Definition Language, a meta-adventure
        !            17: specification language.  It is designed primarily for the programmer
        !            18: who wishes to create a 
        !            19: \s-2DDL\s+2 
        !            20: "world", and secondarily for the programmer
        !            21: attempting to implement 
        !            22: \s-2DDL\s+2 
        !            23: on a new host machine.  
        !            24: .AE
        !            25: .bp 1
        !            26: .ds CF "\(co 1982 UCLA Computer Club
        !            27: .NH 
        !            28: Introduction.
        !            29: .PP
        !            30: \s-2DDL\s+2
        !            31: is a system of notation for the specification of "worlds".  Using
        !            32: \s-2DDL\s+2,
        !            33: a programmer may create Objects, Verbs to act upon those objects,
        !            34: and Routines to describe the behavior of Objects and Verbs.  The user
        !            35: of a 
        !            36: \s-2DDL\s+2
        !            37: program, known as the Player, types these verbs and the names of
        !            38: objects to manipulate those objects at a high level.  Thus, a Player's
        !            39: dialogue with a 
        !            40: \s-2DDL\s+2
        !            41: program will appear something like:
        !            42: .IP
        !            43: .DS
        !            44: .SM
        !            45: 
        !            46:   You are standing outside the north entrance of a large
        !            47:   brick building.  Inscribed above the doorway, appear the
        !            48:   text: 'AARDVARK'S MUSEUM -- GATEWAY TO ADVENTURELAND'.
        !            49:   There is a coil of rope here.
        !            50:   There is a shovel here.
        !            51:   There is a carbide-flame lamp here.
        !            52:   There is a copy of a newspaper here.
        !            53:  >take rope
        !            54:   OK
        !            55:  >south
        !            56:   You are in a large rotunda of an old museum.  Doors lead
        !            57:   to the north, south, east, and west, and a narrow stairway
        !            58:   in the north-east corner of the room leads down.
        !            59:   There is a ball-point pen here.
        !            60:   There is a slip of paper here.
        !            61:  >take paper
        !            62:   OK
        !            63:  >take pen
        !            64:   OK
        !            65:  >e
        !            66:   You are in a dimly lit room containing an empty display case.
        !            67:   A portion of a vandalized sign above the case reads:
        !            68:   'ARTIFACTS OF ANCIENT INDIA -- Several of these items,
        !            69:   including the sacred rhinoceros horn, the deadly ...'.
        !            70:   The rest of the sign is unreadable.
        !            71:   To the west, you can look through a large door into the rotunda
        !            72:   of the museum. On the east wall of the hall there is an outline
        !            73:   of an arch.
        !            74:  >sign paper
        !            75:   In a blinding flash of light, a stone archway appears in the east wall!
        !            76: .NL
        !            77: .DE
        !            78: .PP
        !            79: This sort of behavior will be familiar to users of the celebrated programs,
        !            80: .I "Adventure" 
        !            81: and 
        !            82: .I "Dungeon" 
        !            83: (AKA 
        !            84: .I "Zork"
        !            85: ), of Crowther, Woods, Anderson
        !            86: and Blank.
        !            87: While not as sophisticated in many ways as some of these programs,
        !            88: the primary function of 
        !            89: \s-2DDL\s+2 
        !            90: is to allow a number of interesting
        !            91: puzzles and games to be exchanged among users of disparate machines
        !            92: with a minimum of portability problem.
        !            93: .NH
        !            94: Processor Structure
        !            95: .PP
        !            96: \s-2DDL\s+2 consists of two processors.  The first,
        !            97: .I ddlcomp,
        !            98: reads a program in the \s-2DDL\s+2 language, analyzes it,
        !            99: notes syntax errors, and produces a data file representing
        !           100: the game described by the program.  The second,
        !           101: .I ddlrun,
        !           102: takes one such data file as input and presents a Player with
        !           103: the scenario represented by that file.
        !           104: .NH
        !           105: General Constructs
        !           106: .PP
        !           107: A \s-2DDL\s+2 program will consist of a series of declarations.
        !           108: Some declarations will define properties of Objects and Verbs;
        !           109: others will define Routines to be executed at various stages
        !           110: of play.  These routines are roughly similar to \s-2LISP\s+2
        !           111: functions in that they consist of a series of functional
        !           112: expressions.  Certain identifiers, such as DWIMI and START,
        !           113: are expected to be defined as routines by the programmer,
        !           114: and have special meaning to the processor.
        !           115: .NH
        !           116: General Flow of Execution.
        !           117: .PP
        !           118: When the 
        !           119: \s-2DDL\s+2
        !           120: program begins execution, a special routine which has been
        !           121: coded by the 
        !           122: \s-2DDL\s+2
        !           123: programmer is executed.  This routine must be given the
        !           124: name START.  START will normally initialize demons and set certain initial
        !           125: values.  Execution then proceeds in the cyclic fashion described below.
        !           126: .PP
        !           127: When a 
        !           128: \s-2DDL\s+2
        !           129: scenario is running,
        !           130: execution proceeds in a series of cycles known as "turns".  On
        !           131: each turn, a number of actions takes place.
        !           132: .IP "(1) Demons: " 10
        !           133: Each of the currently active Demon routines
        !           134: (routines set up to do some work on each turn)
        !           135: is run in order
        !           136: of activation.
        !           137: Demon routines are specified and activated by a 
        !           138: \s-2DDL\s+2
        !           139: program through 
        !           140: the 
        !           141: .I $sdem 
        !           142: function.
        !           143: .B Note: 
        !           144: The normal action of Looking (executing description routines) which
        !           145: one expects to occur on each turn must be coded by the 
        !           146: \s-2DDL\s+2
        !           147: programmer
        !           148: as a Demon.
        !           149: .IP "(2) Fuses: " 10
        !           150: All active Fuse routines are checked to see if they
        !           151: are to be executed on this turn.  Those Fuses which have thus "burned down"
        !           152: are then executed (in reverse order of activation) and removed from the
        !           153: Fuse list.
        !           154: .IP "(3) Parse: " 10
        !           155: The player types a line of input,
        !           156: and an attempt is made to resolve that input into a Verb, an Indirect Object,
        !           157: and a Direct Object, by means of attendant Prepositions, Articles,
        !           158: and Adjectives.  Unambiguous abbreviations for words are recognized
        !           159: by the parser.
        !           160: 
        !           161: If an input Noun is ambiguous (for example, if the user says
        !           162: "take book" when "red book" and "blue book" have both been
        !           163: \fIdefined\fR),
        !           164: \s-2DDL\s+2
        !           165: routines called DWIMD and DWIMI are used to disambiguate
        !           166: direct and indirect objects respectively.  DWIMD and DWIMI,
        !           167: which must be defined by the \s-2DDL\s+2 programmer, should return
        !           168: nonzero if the direct or indirect object is "possibly the one he means"
        !           169: (e.g. if it is in the room, etc); only if exactly one such object
        !           170: exists with the given Noun name can the parse complete successfuly.
        !           171: If
        !           172: any of the input components is found to be missing, the value zero is
        !           173: assumed for that object (and no associated routines are executed).
        !           174: 
        !           175: If a syntax error or unknown word is detected, a hopefully informative
        !           176: error message is printed.  In addition, unknown words encountered
        !           177: in the input
        !           178: may be saved in a file for perusal by the DDL programmer.
        !           179: 
        !           180: The direct object may be enclosed in double-quotes by the Player.
        !           181: Such a direct object is returned as a String to the program.  Strings
        !           182: may be detected by the program as having "numeric values" less than
        !           183: zero.  Strings may be operated on with the 
        !           184: .I $eqst, 
        !           185: .I $subs, 
        !           186: and 
        !           187: .I $leng
        !           188: functions, and the 
        !           189: .I $say 
        !           190: procedure.
        !           191: .IP "(4) Pre-action: " 10
        !           192: The PREACT routine (if any)
        !           193: that the 
        !           194: \s-2DDL\s+2
        !           195: programmer has associated
        !           196: with the input Verb is executed.  These routines typically will check
        !           197: for the availability of the object in question, and so on.
        !           198: .IP "(5) Indirect Object: " 10
        !           199: The ACTION routine associated with the Indirect Object
        !           200: that the Player typed (if any) is executed.
        !           201: .IP "(6) Direct Object: " 10
        !           202: The ACTION routine associated with the Direct Object
        !           203: that the Player typed (if any) is executed.
        !           204: For many specialized actions (like "rub lamp") the particular code
        !           205: is best attached to the object.
        !           206: If the Direct Object is a String, the ACTION routine (if any)
        !           207: associated with the object STRING (if such is defined by the
        !           208: programmer) is executed.
        !           209: .IP "(7) Room Action: " 10
        !           210: The ACTION routine associated with the room the Player is
        !           211: in (actually, the LOC of .ME) is executed.  Normally, this will be
        !           212: a "transition" routine which will check if the verb is "north", and so on.
        !           213: .B Note:
        !           214: This is the ONLY aspect of "built-in" action which depends in ANY
        !           215: WAY upon the actual state of variables within the "dungeon" itself.
        !           216: .IP "(8)  Verb: " 10
        !           217: The ACTION routine associated with the input Verb (if any)
        !           218: is executed.  ACTION routines for most Verbs will often be
        !           219: default routines.  For example the Action routine for the Verb "rub"
        !           220: might print "Rubbing that object is not useful."
        !           221: .LP
        !           222: If any of these routines terminates with ($exit 1), the remainder of
        !           223: the current turn is skipped.  Furthermore, the 
        !           224: \s-2DDL\s+2
        !           225: programmer is responsible
        !           226: for incrementing the Turn Counter (normally in a Demon routine) if Fuses
        !           227: are to be used.
        !           228: .NH
        !           229: Data types.
        !           230: .NH 2
        !           231: Objects.
        !           232: .PP
        !           233: Player machinations are in terms of Objects.  All Objects are nodes in
        !           234: a "containment" tree, the root node of which is labelled ".ALL".  
        !           235: A second special
        !           236: object, ".ME" is considered to represent the Player.  Objects will
        !           237: normally be treated either as rooms or portable-type objects, but 
        !           238: \s-2DDL\s+2
        !           239: itself
        !           240: does not distinguish these functions; all objects are stored and treated
        !           241: uniformly.  It is therefore possible, in principal, to write a 
        !           242: \s-2DDL\s+2
        !           243: scenario in which the Player may pick up a room, carry it, and
        !           244: later enter it.  Each object possesses the following attributes.  If
        !           245: any of these is not specified, it is given the default value of zero.
        !           246: .IP "LOC: " 6
        !           247: The object ID of the parent (location) of the object.
        !           248: .IP "CONT: " 6
        !           249: The object ID of the first child (contents) of the object.
        !           250: .IP "LINK: " 6
        !           251: The object ID of the next sibling (others in the same place) of the
        !           252: object
        !           253: .IP "ADJ: " 6
        !           254: The Adjective ID which uniquely distinguishes this object from others
        !           255: of the same name (if any).
        !           256: .IP "OTHERS: " 6
        !           257: The Object ID of another object with the same name as this object,
        !           258: though with a different adjective.  The DWIMx routines are called
        !           259: for each of the objects in this chain associated with 
        !           260: an ambiguous direct
        !           261: or indirect object.  For example, if the player types "take book",
        !           262: and both "red book" and "blue book" are defined, DWIMD will be
        !           263: called once with "red book" as its parameter, and once with "blue book"
        !           264: as its parameter.  If the DWIMD is coded correctly for this example,
        !           265: DWIMI will return TRUE (nonzero) if and only if the parameter book
        !           266: can be taken.  If zero or both books satisfy the DWIMD criteria,
        !           267: an error message is printed.
        !           268: .IP "NAME: " 6
        !           269: The unqualified Noun by which the Player names the object.
        !           270: .IP "PROPS: " 6
        !           271: Up to
        !           272: 25
        !           273: numeric values can be arbitrarily associated with an object by the 
        !           274: \s-2DDL\s+2
        !           275: programmer.  Properties
        !           276: 1-16
        !           277: may only possess the values 0 or 1.  The others may range in value from
        !           278: -32768 to +32767.
        !           279: The last three of these properties have special usages.  Their indices
        !           280: are predefined by the compiler.
        !           281: .RS
        !           282: .IP "LDESC (23)" 6
        !           283: The Routine ID of a "Long Description" routine
        !           284: .IP "SDESC (24)" 6
        !           285: The Routine ID of a "Short Description" routine
        !           286: .IP "ACTION (25)" 6
        !           287: The Routine ID of a "Action" routine, to be called if the Player
        !           288: either attempts to do something with that object (specifies it as a
        !           289: Direct or Indirect Object), or while inside that object.
        !           290: .RE
        !           291: .NH 2
        !           292: Verbs.
        !           293: .PP
        !           294: Each "command" typed by the Player must begin with a Verb which 
        !           295: has been
        !           296: defined by the 
        !           297: \s-2DDL\s+2
        !           298: programmer.  Each Verb has two Routines associated with it:
        !           299: .IP "PREACT: " 6
        !           300: The Routine ID of a routine to execute when the verb has been
        !           301: recognized and the remaining input identified, but before any "Action"
        !           302: routines associated with the Objects in that input have been executed.
        !           303: For example, the PREACT routine of "take" might check to see if
        !           304: the direct object is in the room.
        !           305: .IP "ACTION: " 6
        !           306: The Routine ID of a routine to execute after all input object action
        !           307: routines have been called.
        !           308: Our experience has been that such routines end up being "default" routines
        !           309: that typically only say things like "Rubbing that object does nothing."
        !           310: .NH 2
        !           311: Strings.
        !           312: .PP
        !           313: Simple strings may be defined by the 
        !           314: \s-2DDL\s+2
        !           315: programmer to be printed.  Strings
        !           316: may be up to 255 bytes in length, delimited by double-quote marks.
        !           317: Carriage returns may be embedded in strings freely, or the sequence \en
        !           318: may be used to represent a carriage return at any point.
        !           319: Additionally, strings may be generated by the
        !           320: .I $subs
        !           321: and
        !           322: .I $read
        !           323: functions at run time, or typed by the player
        !           324: as a "direct object."
        !           325: .NH 2
        !           326: Numbers.
        !           327: .PP
        !           328: \s-2DDL\s+2
        !           329: programers may only specify nonnegative integers up to 32767.
        !           330: However, a routine may compute any integer value from -32768 to +32767.
        !           331: .NH 2
        !           332: Adjectives.
        !           333: .PP
        !           334: Adjectives possess no data, but are uniquely numbered by the 
        !           335: \s-2DDL\s+2
        !           336: compiler
        !           337: so as to have unique internal IDs (which begin at the value 1).
        !           338: Adjectives are normally only used to distinguish various objects which
        !           339: have the same Noun name (e.g. the "red book" and the "blue book").
        !           340: .NH 2
        !           341: Routines
        !           342: .PP
        !           343: Routines represent the actual logical behavior of the Dungeon.  A routine
        !           344: consists of one or more calls to builtin or user-defined functions.
        !           345: Internally, a routine may be stored as an interpretive program for a
        !           346: very simple stack machine.  The internal representation is up to the
        !           347: implementer.
        !           348: Routines may call one another, and a single
        !           349: routine may call itself recursively.
        !           350: .NH 2
        !           351: Globals
        !           352: .PP
        !           353: 50
        !           354: globals (numbered
        !           355: 0-49)
        !           356: are available to the 
        !           357: \s-2DDL\s+2
        !           358: programmer and may contain any integer value.  They are named by
        !           359: numeric constants.  Such constants are conveniently assigned
        !           360: symbolic names by means of the VAR declaration described below.
        !           361: The last three globals are set each turn to contain the Indirect
        !           362: Object, Direct Object, Preposition, 
        !           363: and Verb typed by the player.  The constants
        !           364: .I Iobj, 
        !           365: .I Dobj, 
        !           366: .I Prep,
        !           367: and 
        !           368: .I Verb 
        !           369: are predefined by the compiler to refer to those
        !           370: globals.
        !           371: .B "Implementor's Note:"
        !           372: If \s-2DDL\s+2 is implemented on a system that
        !           373: does not permit case distinctions, these constants
        !           374: should be renamed as
        !           375: .I iobj,
        !           376: .I dobj,
        !           377: .I prepg,
        !           378: and
        !           379: .I verbg
        !           380: to avoid conflict with the
        !           381: .I VERB
        !           382: and
        !           383: .I PREP
        !           384: declarations described below.
        !           385: .NH
        !           386: \s-2DDL\s+2
        !           387: Programs
        !           388: .PP
        !           389: .B Note:
        !           390: In the syntactic descriptions below, metavariables such as
        !           391: .I varname
        !           392: refer to user-defined identifiers.  These identifiers consist
        !           393: of an arbitrary-length string of characters.
        !           394: These characters may be alphabetic (upper or lower case; case
        !           395: is distinguished), numeric, or one of the special characters
        !           396: '#', '$', '_', or '.'.  
        !           397: .PP
        !           398: A 
        !           399: \s-2DDL\s+2
        !           400: specification consists of one or more 
        !           401: \s-2DDL\s+2 
        !           402: statements, each terminated
        !           403: by a semicolon.  The following statements exist:
        !           404: .sp
        !           405: .IP "VAR \fIvarname, varname\fR,..." 8
        !           406: .sp
        !           407: Declares each 
        !           408: .I varname
        !           409: as a new symbol.  The symbol
        !           410: is defined as a constant with a value different from each
        !           411: previously declared \fIvarname\fR.  \fIvarname\fR must not
        !           412: be previously declared.
        !           413: .PP
        !           414: .B "Example:  "
        !           415: VAR strength, intell, wisdom;
        !           416: .sp
        !           417: .IP "VERB \fIverbname, verbname\fR,..." 8
        !           418: .sp
        !           419: Declares each 
        !           420: .I verbname 
        !           421: as a new verb.  
        !           422: .I verbname
        !           423: must
        !           424: not be previously assigned.
        !           425: .PP
        !           426: .B "Example:  "
        !           427: VERB north, south, east, west;
        !           428: .sp
        !           429: .IP "ADJECTIVE \fIadjectivename, adjectivename\fR,..." 8
        !           430: .sp
        !           431: Creates a new adjective with name 
        !           432: .I adjectivename,
        !           433: which must not be previously assigned.
        !           434: .PP
        !           435: .B Example: 
        !           436: ADJECTIVE red, green, blue;
        !           437: .sp
        !           438: .IP "NOUN \fInoun\fR [(\fIcontainer\fR)]" 8
        !           439: .sp
        !           440: Creates a new object named 
        !           441: .I noun
        !           442: whose
        !           443: initial location is 
        !           444: .I 
        !           445: container.  noun 
        !           446: .R
        !           447: may not
        !           448: be previously assigned; 
        !           449: .I container
        !           450: must be of
        !           451: type NOUN.  If the "(\fIcontainer\fR)" clause is omitted,
        !           452: the new object is placed in object .ALL .
        !           453: The 
        !           454: .I noun
        !           455: may actually be a adjective-noun pair;
        !           456: if so, the
        !           457: .I adjective
        !           458: must have been previously defined.
        !           459: .PP
        !           460: .B Examples: 
        !           461: .DS
        !           462: NOUN red book, blue book;
        !           463: NOUN gem(red book);
        !           464: .DE
        !           465: .sp
        !           466: .IP "ROUTINE \fIroutinename, routinename, ...\fR" 8
        !           467: .sp
        !           468: Declares that the \fIroutinename\fRs listed will be used
        !           469: for Routines later in the program.  This is to allow \s-2DDL\s+2,
        !           470: which is intended to be easily implementable, to deal with
        !           471: recursive routines (which have not yet been declared at the
        !           472: time of their definitions).  Only routines which are used
        !           473: before being defined need to be declared with this statement.
        !           474: .sp
        !           475: .IP "ARTICLE \fIarticle, article,\fR..." 8
        !           476: .sp
        !           477: Creates each \fIarticle\fR as an article.  Articles are recognized
        !           478: by the run-time parser, but are basically "noise" words.
        !           479: .PP
        !           480: .B Example: 
        !           481: ARTICLE the;
        !           482: .IP "PREP \fIprep, prep\fR,..." 8
        !           483: .sp
        !           484: Creates each 
        !           485: .I prep
        !           486: as a preposition.  Prepositions are basically
        !           487: used by the parser to recognize the presence of
        !           488: indirect objects in the Player's input.
        !           489: However, a global named
        !           490: .I Prep
        !           491: contains the preposition typed by the player on each turn
        !           492: (or zero if none).  The DDL program can thus distinguish
        !           493: "put red book on shelf" from "put red book in shelf" if
        !           494: it is so desired.
        !           495: .PP
        !           496: .B Example: 
        !           497: PREP into,on,using,to,at;
        !           498: .sp
        !           499: .IP "\fInoun\fR (\fInumexp\fR) = \fIexp2\fR" 8
        !           500: .sp
        !           501: Property \fInumexp\fR of \fInoun\fR is set to the
        !           502: value of \fIexp2\fR.
        !           503: .I exp2
        !           504: may be a number, a string, a routine name, or a new routine;
        !           505: the numeric value or ID of
        !           506: .I exp2
        !           507: is always placed into the specified property.
        !           508: .PP
        !           509: .B Examples: 
        !           510: .DS
        !           511: gem(11)=1;             { 11 == Luminous }
        !           512: gem(LDESC) = ($say "There is a bright gem here!");
        !           513: gem(SDESC) = ($say "a bright gem");
        !           514: gem(ACTION) = GemAction;  { Earlier-defined routine }
        !           515: .DE
        !           516: .sp
        !           517: .IP "\fIverb\fR (PREACT | ACTION) = \fIroutine\fR" 8
        !           518: .sp
        !           519: Assigns \fIroutine\fR as the pre-object action or default action of
        !           520: the given \fIverb\fR.  The routine may be a predefined routine name or
        !           521: an actual routine.
        !           522: .PP
        !           523: .B Example: 
        !           524: .DS
        !           525: rub(ACTION) =  ($say "Rubbing ")
        !           526:                (($sdesc ($dobj)))
        !           527:                ($say " seems silly!");
        !           528: .DE
        !           529: .sp
        !           530: .IP "\fIname\fR = \fInumber\fR" 8
        !           531: .sp
        !           532: Assigns \fIname\fR as equivalent to \fInumber\fR.  \fIname\fR
        !           533: must not be previously assigned.
        !           534: .PP
        !           535: .B Example: 
        !           536: OPEN=11; TRUE=1;
        !           537: .sp
        !           538: .IP "\fIname1\fR = \fIname2\fR" 8
        !           539: .sp
        !           540: Assigns 
        !           541: .I name1
        !           542: as a synonym for 
        !           543: .I name2.
        !           544: .PP
        !           545: .B Example: 
        !           546: n=north;s=south;se=southeast;
        !           547: .sp
        !           548: .IP "(\fInumexp\fR) = \fInumexp2\fR" 8
        !           549: .sp
        !           550: Assigns the global (or VAR) named by \fInumexp\fR to the value
        !           551: given by \fInumexp2\fR.
        !           552: .PP
        !           553: .B Example: 
        !           554: (Maxpt)=450;
        !           555: .IP "\fIname\fR = "
        !           556: "\fIstring\fR"
        !           557: .sp
        !           558: Assigns 
        !           559: .I name
        !           560: as equivalent to "\fIstring\fR".
        !           561: Frequently, it is just
        !           562: as easy to assign a routine to Say the given string
        !           563: as it is to define that string separately.
        !           564: However, there are other string functions, such as 
        !           565: .I $eqst
        !           566: and 
        !           567: .I $substr, 
        !           568: for which it may be useful to predefine strings.
        !           569: .PP
        !           570: .B Example: 
        !           571: .br
        !           572: err="Nothing happens.\en";
        !           573: .br
        !           574: MagicWord = "ShaZam";
        !           575: .sp
        !           576: .IP "\fIname\fR = \fIroutine\fR" 8
        !           577: .sp
        !           578: Assigns 
        !           579: .I name
        !           580: as equivalent to 
        !           581: .I routine
        !           582: .PP
        !           583: .B Example: 
        !           584: sayer=($say "Nothing happens.\en");
        !           585: .IP "INCLUDE ""\fIfilename\fR""" 8
        !           586: .sp
        !           587: .B
        !           588: (\s-2UNIX\s+2 implementation only)
        !           589: .R
        !           590: Causes input to be read from the named file.
        !           591: .RE
        !           592: .NH 
        !           593: Routines
        !           594: .PP
        !           595: A routine is a list of one or more "forms".  Forms are of three types:
        !           596: .RS
        !           597: .NH 2
        !           598: Conditional Forms
        !           599: .IP "(\fIform1\fB : \fIform form\fR ... [: \fIelseform elseform\fR ...])" 8
        !           600: .PP
        !           601: If 
        !           602: .I form1
        !           603: evaluates to
        !           604: nonzero, the subsequent \fIform\fRs are executed in
        !           605: sequence.  Otherwise, the list of \fIelseform\fRs is executed in sequence.
        !           606: Note that
        !           607: the second colon, and the subsequent \fIelseform\fRs, are optional.
        !           608: .PP
        !           609: .B Example: 
        !           610: .PP
        !           611: .DS
        !           612: (TRUE : ($say "Always do me") : ($say "Never do me"))
        !           613: .DE
        !           614: .NH 2
        !           615: Simple Looping Forms
        !           616: .IP "(WHILE \fIform1\fR : \fIform form ... \fR)" 8
        !           617: .PP
        !           618: If \fIform1\fR evaluates
        !           619: to nonzero, the subsequent \fIform\fRs are evaluated
        !           620: in sequence.  This process is repeated until such
        !           621: a time as \fIform1\fR is found to evaluate to zero.
        !           622: .PP
        !           623: .B Example:
        !           624: .PP
        !           625: .DS
        !           626: (WHILE ($eq ($loc .ME) JewlRoom) : (TRYmv .ME Prison))
        !           627: .DE
        !           628: .NH 2
        !           629: Basic Function Forms
        !           630: .IP "(\fIfunction arg1 arg2\fR ...)" 8
        !           631: .PP
        !           632: This is the basic function call (note that all builtin functions
        !           633: begin with the character $).  The \fIfunction\fR is applied
        !           634: to the \fIarg\fRs.  An argument may be a number,
        !           635: string, declared name, or another form.  However, the function must
        !           636: be a simple identifier, or a form which evaluates to a function
        !           637: identifier (
        !           638: .I 
        !           639: e.g.
        !           640: .R
        !           641: ($ldesc xxx)).
        !           642: In addition, three special argument types are recognized:
        !           643: .PP
        !           644: An argument such as "@\fInumber\fR" is interpreted as 
        !           645: "contents of global \fInumber\fR".
        !           646: .PP
        !           647: An argument such as "%\fInumber\fR" is interpreted as "the value of the 
        !           648: \fInumber\fR
        !           649: argument to this function".
        !           650: .PP
        !           651: An argument such as "[\fIadj noun\fR]" must be used if the programmer wishes to
        !           652: refer to an object with an associated adjective.
        !           653: .RE
        !           654: .NH
        !           655: Program Comments
        !           656: .PP
        !           657: Comments may be placed freely anywhere in a DDL program.  Comments
        !           658: are surrounded by "curly braces" { like these }, but may NOT
        !           659: be nested.  A single right brace will close any and all open
        !           660: comments.  
        !           661: .NH
        !           662: The Parser
        !           663: .PP
        !           664: The \s-2DDL\s+2 run-time parser is the Player's only
        !           665: interface to the world created by the \s-2DDL\s+2
        !           666: programmer.  The parser recognizes four basic
        !           667: forms of input "sentence":
        !           668: .DS
        !           669:        VERB  (e.g. "inventory")
        !           670:        VERB DIRECT-OBJECT  (e.g. "take rock")
        !           671:        VERB DIRECT-OBJECT PREP INDIRECT-OBJECT
        !           672:                (e.g. "plant flower in vase")
        !           673:        VERB INDIRECT-OBJECT DIRECT-OBJECT
        !           674:                (e.g. "give the troll the red blanket"
        !           675:                 or  "Turn the lamp off" where "off" is an object)
        !           676: .DE
        !           677: .PP
        !           678: Either a direct or indirect object may consist of
        !           679: a simple noun, an adjective-noun pair, or either
        !           680: type of noun phrase preceded by an article.  Additionally,
        !           681: a direct object may be a string delimited by double-quotes.
        !           682: The parser attempts to resolve all ambiguous noun references,
        !           683: and then sets up the globals,
        !           684: .I Dobj,
        !           685: .I Iobj,
        !           686: .I Prep,
        !           687: and
        !           688: .I Verb
        !           689: with the symbol-table values associated with the appropriate
        !           690: verb or object.  For an object this is an index into the
        !           691: Object Table; for a verb it is an index into the Verb table.
        !           692: A string typed as a direct object will be stored as an index
        !           693: into an internal temporary-string table, but its value
        !           694: will be negated so that the programmer can detect that a
        !           695: string has been typed, knowing that all strings (and only strings)
        !           696: have a numeric value less than zero.
        !           697: .PP
        !           698: When a syntactically invalid line is typed, the parser
        !           699: prints a (hopefully) helpful error message and accepts
        !           700: new input.  A new turn is
        !           701: .I not
        !           702: begun.  A similar action is taken when a nonsense word
        !           703: is typed.
        !           704: .PP
        !           705: Several commands may be typed on one line, separated by
        !           706: commas.  However, this is considered as identical to
        !           707: separating them by new-lines; they are dealt with on
        !           708: separate turn cycles (and extra prompts may be printed).
        !           709: .bp
        !           710: .NH
        !           711: Built-in Functions
        !           712: .PP
        !           713: The following functions are built-in functions available to the 
        !           714: \s-2DDL\s+2
        !           715: programmer.  These functions are the heart of the 
        !           716: \s-2DDL\s+2 
        !           717: system and are
        !           718: the means whereby the 
        !           719: \s-2DDL\s+2 
        !           720: routines manipulate all system data.  Thus,
        !           721: these functions completely describe the facilities of the 
        !           722: \s-2DDL\s+2 
        !           723: system.
        !           724: .PP
        !           725: The arguments to functions are here shown as "\fIobj\fR and
        !           726: the like.  In fact, any function may take any value as an argument.
        !           727: Mentioning the name of a symbol simply gives its symbol-table
        !           728: value.  For an object, for example, this is its index in the object
        !           729: table.  So, while it may be valid to say "($say window)", this will
        !           730: only print the message whose message number happens to be the
        !           731: same as the object index of the "window".  Note that the parser correctly
        !           732: assigns such symbol-table values to the variables
        !           733: .I
        !           734: Dobj, Iobj, Prep,
        !           735: .R
        !           736: and
        !           737: .I Verb.
        !           738: .NH 2
        !           739: Functions on objects
        !           740: .IP "\fB$loc    \fR" 8
        !           741: ($loc \fIobj\fR) \(-> The container of \fIobj\fR.
        !           742: .IP "\fB$cont   \fR" 8
        !           743: ($cont \fIobj\fR) \(-> First item contained in \fIobj\fR.
        !           744: .IP "\fB$link   \fR" 8
        !           745: ($link \fIobj\fR) \(-> The next object in the same node as \fIobj\fR.
        !           746: .IP "\fB$ldesc  \fR" 8
        !           747: ($ldesc \fIobj\fR) \(-> The routine ID for the long description of \fIobj\fR.
        !           748: .IP "\fB$sdesc  \fR" 8
        !           749: ($sdesc \fIobj\fR) \(-> The routine ID for the short description of \fIobj\fR.
        !           750: .IP "\fB$rtn    \fR" 8
        !           751: ($rtn \fIobj\fR) \(-> The ACTION routine for \fIobj\fR.
        !           752: .IP "\fB$prop   \fR" 8
        !           753: ($prop \fIobj\fR \fIpropnum\fR) \(-> returns the value of the \fIpropnum\fR'th property
        !           754: of \fIobj\fR.
        !           755: .NH 2
        !           756: Arithmetic Funcions
        !           757: .IP "\fB$plus   \fR" 8
        !           758: ($plus \fIarg1\fR \fIarg2\fR) \(-> \fIarg1\fR+\fIarg2\fR
        !           759: .IP "\fB$minus  \fR" 8
        !           760: ($minus \fIarg1\fR \fIarg2\fR) \(-> \fIarg1\fR\-\fIarg2\fR
        !           761: .IP "\fB$times  \fR" 8
        !           762: ($times \fIarg1\fR \fIarg2\fR) \(-> \fIarg1\fR*\fIarg2\fR
        !           763: .IP "\fB$quotient \fR" 8
        !           764: ($quotient \fInum den\fR) \(-> [\fInum\fR/\fIden\fR]
        !           765: .IP "\fB$remainder \fR" 8
        !           766: ($remainder \fInum den\fR) \(-> \fInum\fB mod \fIden\fR
        !           767: .IP "\fB$rand \fR" 8
        !           768: ($rand \fIarg\fR) \(-> Random integer between 1 and \fIarg\fR inclusive
        !           769: .NH 2
        !           770: Boolean Functions
        !           771: .IP "\fB$and    \fR" 8
        !           772: ($and \fIa b\fR) \(-> \fIa\fB (bitwise AND) \fIb\fR
        !           773: .IP "\fB$or     \fR" 8
        !           774: ($or \fIa b\fR) \(-> \fIa\fB (bitwise OR) \fIb\fR
        !           775: .IP "\fB$not    \fR" 8
        !           776: ($not \fIx\fR) \(->  \s-2IF\s+2 \fIx\fR nonzero \s-2THEN\s+2 zero \s-2ELSE\s+2 one.
        !           777: .IP "\fB$yorn   \fR" 8
        !           778: ($yorn) \(-> Waits for the Player to type a line of input.  Returns
        !           779: one if the Player types "yes" or "y" and zero otherwise.
        !           780: .IP "\fB$pct    \fR" 8
        !           781: ($pct \fIprob\fR) \(-> Returns one, \fIprob\fR% of the time, zero otherwise.
        !           782: .IP "\fB$eq     \fR" 8
        !           783: ($eq \fIarg1\fR \fIarg2\fR) \(-> 1 if \fIarg1\fR equals \fIarg2\fR, zero otherwise.
        !           784: .IP "\fB$ne     \fR" 8
        !           785: ($ne \fIarg1\fR \fIarg2\fR) \(-> IF \fIarg1\fR ~= \fIarg2\fR THEN  one  ELSE  zero.
        !           786: .IP "\fB$lt     \fR" 8
        !           787: ($lt \fIarg1\fR \fIarg2\fR) \(-> 1 if \fIarg1\fR < \fIarg2\fR, zero otherwise.
        !           788: .IP "\fB$gt     \fR" 8
        !           789: ($gt \fIarg1\fR \fIarg2\fR) \(-> 1 if \fIarg1\fR > \fIarg2\fR, zero otherwise.
        !           790: .IP "\fB$le     \fR" 8
        !           791: ($le \fIarg1\fR \fIarg2\fR) \(-> 1 if \fIarg1\fR <= \fIarg2\fR, zero otherwise.
        !           792: .IP "\fB$ge     \fR" 8
        !           793: ($ge \fIarg1\fR \fIarg2\fR) \(-> 1 if \fIarg1\fR >= \fIarg2\fR, zero otherwise.
        !           794: .NH 2
        !           795: Builtin Procedures (no return value)
        !           796: .IP "\fB$setg    \fR" 8
        !           797: ($setg \fIglobalnumber value\fR) \(-> No return value.  Sets the
        !           798: contents of global #\fIglobalnumber\fR to \fIvalue\fR.
        !           799: .IP "\fB$setp   \fR" 8
        !           800: ($setp \fIobj propnum value\fR) \(-> No return value.  Sets the \fIpropnum\fR'th
        !           801: property of \fIobj\fR to \fIvalue\fR.  Note that properties 1-16 may only contain 0 or 1.
        !           802: .IP "\fB$move   \fR" 8
        !           803: ($move \fIobj dest\fR) \(-> No return value.  Causes \fIobj\fR to be placed
        !           804: inside \fIdest\fR, and adjusts pointers accordingly.  \fBDanger\fR: No checking is
        !           805: performed to verify that $move is not being used to violate the tree structure
        !           806: of the object list (eg ($move obj obj)).
        !           807: Bad results are likely if this occurs.
        !           808: .IP "\fB$say    \fR" 8
        !           809: ($say \fImsg\fR) \(-> No return value.  Types \fImsg\fR.
        !           810: .IP "\fB$name   \fR" 8
        !           811: ($name \fIobj\fR) \(-> No return value.  Types the (5-letter) name of \fIobj\fR.
        !           812: .IP "\fB$num    \fR" 8
        !           813: ($num \fIx\fR) \(-> No return value.  Types the number \fIx\fR.
        !           814: .IP "\fB$exit   \fR" 8
        !           815: ($exit \fIn\fR) \(-> Leave present routine.  ($exit 1) causes the current
        !           816: "turn" to be prematurely terminated and the next turn to be initiated
        !           817: at the Demon phase.  ($exit 0) returns to the driver to begin the next phase.
        !           818: .IP "\fB$rtrn   \fR" 8
        !           819: ($rtrn \fIn\fR) \(-> Exits to the calling routine, returning value '\fIn\fR' TO
        !           820: THE CALLING FUNCTION.
        !           821: .IP "\fB$spec   \fR" 8
        !           822: ($spec \fIcode arg1 arg2 arg3 arg4\fR) \(-> Performs a special function as
        !           823: follows:
        !           824: .TS
        !           825: center box;
        !           826: c | c.
        !           827: code   function
        !           828: =
        !           829: 3      Terminate this run of DDL
        !           830: _
        !           831: 4      Save a game
        !           832: _
        !           833: 5      Restore a game
        !           834: _
        !           835: 6      Fork a shell with arguments \fIarg1 \- arg4\fR
        !           836: _
        !           837: 7      Preserve unknown words in file \fIarg1\fR
        !           838: .TE
        !           839: .PP
        !           840: Functions 4 and 5 prompt for a file name in which the saved game is
        !           841: kept.  
        !           842: Function 6 is a \s-2UNIX\s+2-specific function.
        !           843: Function 7 causes any unknown words encountered by the parser
        !           844: to be preserved in a file for later perusal by the 
        !           845: \s-2DDL\s+2 
        !           846: programmer.  It
        !           847: would be used to learn about things players have tried unsuccessfully
        !           848: that should be dealt with.  The file must already exist, and must
        !           849: be specified as a string.
        !           850: .PP
        !           851: ALL arguments must be specified, even if zero.
        !           852: .NH 2
        !           853: Global-value functions
        !           854: .IP "\fB$glob   \fR" 8
        !           855: ($glob \fIn\fR) \(-> Value of global \fIn\fR.  Equivalent to @\fIn\fR.
        !           856: .IP "\fB$verb   \fR" 8
        !           857: ($verb) \(-> The ID of the verb returned by the parser (zero if none).
        !           858: Typically used in comparisons, it is equivalent to @Verb.
        !           859: .IP "\fB$dobj   \fR" 8
        !           860: ($dobj) \(-> The ID of the direct object returned by the parser
        !           861: (zero if none).  Equivalent to @Dobj.
        !           862: .IP "\fB$iobj   \fR" 8
        !           863: ($dobj) \(-> The ID of the indirect object returned by the parser
        !           864: (zero if none).  Equivalent to @Iobj.
        !           865: .sp
        !           866: .B Note:
        !           867: There is no ($prep) corresponding to @Prep.
        !           868: .NH 2
        !           869: Transition Procedures
        !           870: .IP "\fB$setv   \fR" 8
        !           871: ($setv \fIv1 v2 v3 v4 v5 v6 v7 v8 v9 v10\fR) \(-> sets the values in
        !           872: the internal vector VECVERB to the values \fIv1\fR thru \fIv10\fR.  These are
        !           873: used by routines $hit and $miss.
        !           874: .IP "\fB$hit    \fR" 8
        !           875: ($hit \fImover d1 d2 d3 d4 d5 d6 d7 d8 d9 d10\fR) \(-> No return value.
        !           876: Compares ($verb) with the values in builtin vector VECVERB.  When ($verb)
        !           877: is found to match the nth entry in VECVERB, ($move \fImover d[n]\fR) is executed.
        !           878: Note that \fImover\fR is what gets moved to d[n]; this argument is naturally
        !           879: absent from $setv and $miss.
        !           880: .IP "\fB$miss   \fR" 8
        !           881: ($miss \fIr1 r2 r3 r4 r5 r6 r7 r8 r9 r10\fR) \(-> no return value.
        !           882: Compares ($verb) to VECVERB as $hit does.  When a match to the nth
        !           883: entry in VECVERB is found, routine \fIr\fR[n] is called.  An attempt to
        !           884: call routine 0 does nothing.
        !           885: .NH 2
        !           886: String Functions
        !           887: .PP
        !           888: There are two varieties of strings.  Constant strings defined
        !           889: by the \s-2DDL\s+2 programmer are permanent, and have a numeric "value"
        !           890: greater than zero (which is in fact a table index).  Strings
        !           891: typed by the Player as a direct object, and strings produced
        !           892: by the functions $subs and $read are temporary, have a numeric
        !           893: "value" less than zero (which allows the programmer to determine
        !           894: if the direct object is in fact a string), and are purged by
        !           895: having their index values recycled at the beginning of every turn.
        !           896: No more than 200 such strings may be generated on a given turn.
        !           897: String functions (including
        !           898: .B $say
        !           899: ) automatically understand both varieties of strings; the 
        !           900: \s-2DDL\s+2 programmer should not attempt to un-negate
        !           901: direct-object-type strings.
        !           902: .IP "\fB$eqst\fR" 8
        !           903: ($eqst \fIarg1 arg2\fR) \(-> 1 iff the strings specified by the
        !           904: two \fIarg\fRs are equal, zero otherwise.
        !           905: .IP "\fB$subs\fR" 8
        !           906: ($subs \fIstr index length\fR) \(-> a string consisting of the
        !           907: substring of \fIstr\fR, starting at character \fIindex\fR 
        !           908: (with an origin of Zero for the beginning of the string), for
        !           909: the specified \fIlength\fR.  A \fIlength\fR of zero causes
        !           910: all the remaining characters starting at \fIindex\fR to be
        !           911: taken.
        !           912: .IP "\fB$leng\fR" 8
        !           913: ($leng \fIstr\fR) \(-> The length of string \fIstr\fR.
        !           914: .IP "\fB$read\fR" 8
        !           915: ($read) \(-> Causes \s-2DDL\s+2 to pause and wait for input from
        !           916: the Player.  Returns the string the player typed, without the
        !           917: trailing newline.
        !           918: .NH 2
        !           919: Demons and Fuses
        !           920: .IP "\fB$sdem   \fR" 8
        !           921: ($sdem n) \(-> Activates routine n as a Demon, to be executed every
        !           922: turn.  At least one such Demon should exist, to Look at the Player's
        !           923: current location, and to increment the turn counter
        !           924: .IP "\fB$ddem   \fR" 8
        !           925: ($ddem n) \(-> Removes routine n from the active Demon list.  For
        !           926: example, ($ddem Kount) undoes the action of ($sdem Kount).
        !           927: .IP "\fB$sfus   \fR" 8
        !           928: ($sfus rout n) \(-> Causes routine "rout" to be executed (one
        !           929: time only) after n turns.  Such a routine is called a Fuse.
        !           930: .IP "\fB$dfus   \fR" 8
        !           931: ($dfus rout) \(-> Causes routine rout to be taken off the
        !           932: pending fuse list.
        !           933: .IP "\fB$itun   \fR" 8
        !           934: ($itun) \(-> Increments the turn counter.  This is a builtin function
        !           935: because fuses depend upon the turn counter.  The 
        !           936: \s-2DDL\s+2 
        !           937: programmer has the
        !           938: option to "slow time" by refraining from incrementing the turn counter.
        !           939: .IP "\fB$gtun   \fR" 8
        !           940: ($gtun) \(-> Returns the current turn counter value.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.