|
|
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.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.