|
|
1.1 root 1: .RS
2: .ds CF "\(co 1981 UCLA Computer Club
3: .TL
4: A Brief Description of UCLA
5: Dungeon Definition Language (DDL)
6: .AU
7: Bruce Adler
8: Chris Kostanick
9: Michael Stein
10: Michael Urban
11: .AI
12: University of California
13: Los Angeles, CA 90024
14: .AB
15: This document describes Dungeon Definition Language, a meta-adventure
16: specification language. It is designed primarily for the programmer
17: who wishes to create a
18: \s-2DDL\s+2
19: "world", and secondarily for the programmer
20: attempting to implement
21: \s-2DDL\s+2
22: on a new host machine.
23: .AE
24: .bp 1
25: .ds CF "\(co 1981 UCLA Computer Club
26: .NH
27: Introduction.
28: .PP
29: \s-2DDL\s+2
30: is a system of notation for the specification of "worlds". Using
31: \s-2DDL\s+2,
32: a programmer may create Objects, Verbs to act upon those objects,
33: and Routines to describe the behavior of Objects and Verbs. The user
34: of a
35: \s-2DDL\s+2
36: program, known as the Player, types these verbs and the names of
37: objects to manipulate those objects at a high level. Thus, a Player's
38: dialogue with a
39: \s-2DDL\s+2
40: program will appear something like:
41: .IP
42: .DS
43: .SM
44:
45: You are standing outside the north entrance of a large
46: brick building. Inscribed above the doorway, appear the
47: text: 'AARDVARK'S MUSEUM -- GATEWAY TO ADVENTURELAND'.
48: There is a coil of rope here.
49: There is a shovel here.
50: There is a carbide-flame lamp here.
51: There is a copy of a newspaper here.
52: >take rope
53: OK
54: >south
55: You are in a large rotunda of an old museum. Doors lead
56: to the north, south, east, and west, and a narrow stairway
57: in the north-east corner of the room leads down.
58: There is a ball-point pen here.
59: There is a slip of paper here.
60: >take paper
61: OK
62: >take pen
63: OK
64: >e
65: You are in a dimly lit room containing an empty display case.
66: A portion of a vandalized sign above the case reads:
67: 'ARTIFACTS OF ANCIENT INDIA -- Several of these items,
68: including the sacred rhinoceros horn, the deadly ...'.
69: The rest of the sign is unreadable.
70: To the west, you can look through a large door into the rotunda
71: of the museum. On the east wall of the hall there is an outline
72: of an arch.
73: >sign paper
74: In a blinding flash of light, a stone archway appears in the east wall!
75: .NL
76: .DE
77: .PP
78: This sort of behavior will be familiar to users of the celebrated programs,
79: .I "Adventure"
80: and
81: .I "Dungeon"
82: (AKA
83: .I "Zork"
84: ), of Crowther, Woods, Anderson
85: and Blank.
86: While not as sophisticated in many ways as some of these programs,
87: the primary function of
88: \s-2DDL\s+2
89: is to allow a number of interesting
90: puzzles and games to be exchanged among users of disparate machines
91: with a minimum of portability problem.
92: .NH
93: General Flow of Execution.
94: .PP
95: When the
96: \s-2DDL\s+2
97: program begins execution, a special routine which has been
98: coded by the
99: \s-2DDL\s+2
100: programmer is executed. This routine must be given the
101: name START. START will normally initialize demons and set certain initial
102: values. Execution then proceeds in the cyclic fashion described below.
103: .PP
104: When a
105: \s-2DDL\s+2
106: scenario is running,
107: execution proceeds in a series of cycles known as "turns". On
108: each turn, a number of actions takes place.
109: .IP "(1) Demons: " 10
110: Each of the Demon routines currently active is run in order
111: of activation.
112: Demon routines are specified and activated by the
113: \s-2DDL\s+2
114: program by executing
115: the $sdem function.
116: .B Note:
117: The normal action of Looking (executing description routines) which
118: one expects to occur on each turn must be coded by the
119: \s-2DDL\s+2
120: programmer
121: as a Demon.
122: .IP "(2) Fuses: " 10
123: All active Fuse routines are checked to see if they
124: are to be executed on this turn. Those Fuses which have thus "burned down"
125: are then executed (in reverse order of activation) and removed.
126: .IP "(3) Parse: " 10
127: The player types a line of input,
128: and an attempt is made to resolve that input into a Verb, an Indirect Object,
129: and a Direct Object, by means of attendant Prepositions, Articles,
130: and Adjectives. Unambiguous abbreviations for words are recognized
131: by the parser.
132: If an input Noun is ambiguous (because of two objects distinguished by only
133: adjectives),
134: \s-2DDL\s+2
135: routines called DWIMD and DWIMI are used to disambiguate
136: direct and indirect objects respectively. DWIMD and DWIMI each return
137: nonzero if the direct or indirect object is "possibly the one he means"
138: (e.g. if it is in the room, etc)); only if exactly one such object
139: exists with the given Noun name can the parse complete successfuly.
140: any of the input components are found to be missing, the value zero is
141: assumed for that object (and no associated routines are executed).
142: .PP
143: If a syntax error or unknown word is detected, a hopefully informative
144: error message is printed. In addition, unknown words encountered
145: in the input
146: may be saved in a file for perusal by the DDL programmer.
147: .PP
148: The direct object may be enclosed in double-quotes by the Player.
149: Such a direct object is returned as a String to the program. Strings
150: may be detected by the program as having "numeric values" less than
151: zero. Strings may be operated on with the $eqst, $subs, and $leng
152: functions, and the $say procedure.
153: .IP "(4) Pre-action: " 10
154: The PREACT routine (if any)
155: that the
156: \s-2DDL\s+2
157: programmer has associated
158: with the input Verb is executed. These routines typically will check
159: for the availability of the object in question, and so on.
160: .IP "(5) Indirect Object: " 10
161: The ACTION routine associated with the Indirect Object
162: that the Player typed (if any) is executed.
163: .IP "(6) Direct Object: " 10
164: The ACTION routine associated with the Direct Object
165: that the Player typed (if any) is executed.
166: For most specialized actions (like "rub lamp") the particular code
167: is frequently attached to the object.
168: If the Direct Object is a String, the ACTION routine (if any)
169: associated with the object STRING (if such is defined by the
170: programmer) is executed.
171: .IP "(7) Room Action: " 10
172: The ACTION routine associated with the room the Player is
173: in (actually, the LOC of .ME) is executed. Normally, this will be
174: a "transition" routine which will check if the verb is "north", and so on.
175: .B Note:
176: This is the ONLY aspect of "built-in" action which depends in ANY
177: WAY upon the actual state of variables within the "dungeon" itself.
178: .IP "(8) Verb: " 10
179: The ACTION routine associated with the input Verb (if any)
180: is executed. ACTION routines for most Verbs will often be
181: default routines. For example the Action routine for the Verb "rub"
182: might print "Rubbing that object is not useful."
183: .LP
184: If any of these routines terminates with an ($exit 1), the remainder of
185: the current turn is skipped. Furthermore, the
186: \s-2DDL\s+2
187: programmer is responsible
188: for incrementing the Turn Counter (normally in a Demon routine) if Fuses
189: are to be used.
190: .NH
191: Data types.
192: .NH 2
193: Objects.
194: .PP
195: Player machinations are in terms of Objects. All Objects are nodes in
196: a tree, the root node of which is labelled ".ALL". A second special
197: object, ".ME" is considered to represent the Player. Objects will
198: normally be treated either as rooms or portable-type objects, but
199: \s-2DDL\s+2
200: itself
201: does not distinguish these functions; all objects are stored and treated
202: uniformly. It is therefore possible, in principal, to write a
203: \s-2DDL\s+2
204: scenario in which the Player may pick up a room, carry it, and
205: later enter it. Each object possesses the following attributes. If
206: any of these is not specified, it is given the default value of zero.
207: .IP "LOC: " 6
208: The object ID of the parent (location) of the object.
209: .IP "CONT: " 6
210: The object ID of the first child (contents) of the object.
211: .IP "LINK: " 6
212: The object ID of the next sibling (others in the same place) of the
213: object
214: .IP "ADJ: " 6
215: The Adjective ID which uniquely distinguishes this object from others
216: of the same name (if any).
217: .IP "OTHERS: " 6
218: The Object ID of another object with the same name as this object,
219: though with a different adjective.
220: .IP "NAME: " 6
221: The unqualified Noun by which the Player names the object.
222: .IP "PROPS: " 6
223: Up to
224: 25
225: numeric values can be arbitrarily associated with an object by the
226: \s-2DDL\s+2
227: programmer. Properties
228: 1-16
229: may only possess the values 0 or 1. The others may range in value from
230: -32768 to +32767.
231: The last three of these properties have special usages. Their indices
232: are predefined by the compiler.
233: .IP "LDESC (23)" 6
234: The Routine ID of a "Long Description" routine
235: .IP "SDESC (24)" 6
236: The Routine ID of a "Short Description" routine
237: .IP "ACTION (25)" 6
238: The Routine ID of a "Action" routine, to be called if the Player
239: either attempts to do something with that object (specifies it as a
240: Direct or Indirect Object), or while inside that object.
241: .NH 2
242: Verbs.
243: .PP
244: The "commands" typed by the Player must name Verbs which have been
245: defined by the
246: \s-2DDL\s+2
247: programmer. Each Verb is associated with two Routine
248: ID's:
249: .IP "PREACT: " 6
250: The Routine ID of a routine to execute when the verb has been
251: recognized and the remaining input identified, but before any "Action"
252: routines associated with the Objects in that input have been executed.
253: For example, the PREACT routine of "take" might check to see if
254: the direct object is in the room.
255: .IP "ACTION: " 6
256: The Routine ID of a routine to execute after all input object action
257: routines have been called.
258: Our experience has been that such routines end up being "default" routines
259: that typically only say things like "Rubbing that object does nothing."
260: .NH 2
261: Strings.
262: .PP
263: Simple strings may be defined by the
264: \s-2DDL\s+2
265: programmer to be printed. Strings
266: may be up to 255 bytes in length, delimited by double-quote marks.
267: Carriage returns may be embedded in strings freely, or the sequence \\n
268: may be used to represent a carriage return at any point.
269: .NH 2
270: Numbers.
271: .PP
272: \s-2DDL\s+2
273: programers may only specify nonnegative integers up to 32767.
274: However, a routine may compute any integer value from -32768 to +32767.
275: .NH 2
276: Adjectives.
277: .PP
278: Adjectives possess no data, but are uniquely numbered by the
279: \s-2DDL\s+2
280: compiler
281: so as to have unique internal IDs (which begin at the value 1).
282: Adjectives are normally only used to distinguish various objects which
283: have the same Noun name (eg the "red book" and the "blue book").
284: .NH 2
285: Routines
286: .PP
287: Routines represent the actual logical behavior of the Dungeon. A routine
288: consists of one or more calls to builtin or user-defined functions.
289: Internally, a routine may be stored as an interpretive program for a
290: very simple stack machine. The internal representation is up to the
291: implementer.
292: Routines may call one another, and a single
293: routine may call itself recursively.
294: .NH 2
295: Globals
296: .PP
297: 50
298: globals (numbered
299: 0-49)
300: are available to the
301: \s-2DDL\s+2
302: programmer and may contain any integer value. They are named by
303: numeric constants. Such constants are conveniently assigned
304: symbolic names by means of the VAR declaration described below.
305: The last three globals are set each turn to contain the Indirect
306: Object, Direct Object, and Verb typed by the player. The constants
307: Iobj, Dobj, and Verb are predefined by the compiler to refer to those
308: globals.
309: .NH
310: \s-2DDL\s+2
311: Programs
312: .PP
313: .B Note:
314: In the syntactic descriptions below, metavariables such as
315: .I varname
316: refer to user-defined identifiers. These identifiers consist
317: of a string of alphameric characters of arbitrary length.
318: A
319: \s-2DDL\s+2
320: specification consists of one or more
321: \s-2DDL\s+2
322: statements, each terminated
323: by a semicolon. The following statements exist:
324: .sp
325: .IP "VAR \fIvarname, varname\fR,..." 8
326: .PP
327: Declares each
328: .I varname
329: as a new symbol. The symbol
330: is defined as a constant with a value different from each
331: previously declared <varname>. <varname> must not
332: be previously declared.
333: .PP
334: .B "Example: "
335: VAR strength, intell, wisdom;
336: .sp
337: .IP "VERB \fIverbname, verbname\fR,..." 8
338: .PP
339: Declares each
340: .I verbname
341: as a new verb.
342: .I verbname
343: must
344: not be previously assigned.
345: .PP
346: .B "Example: "
347: VERB north,south,east,west;
348: .sp
349: .IP "ADJEC \fIadjectivename, adjectivename\fR,..." 8
350: .PP
351: Creates a new adjective with name
352: .I adjectivename,
353: which must not be previously assigned.
354: .PP
355: .B Example:
356: ADJEC red,green,blue;
357: .sp
358: .IP "NOUN \fInoun\fR[(\fIcontainer\fR)]" 8
359: .PP
360: Creates a new object named
361: .I noun
362: whose
363: initial location is
364: .I
365: container. noun
366: .R
367: may not
368: be previously assigned;
369: .I container
370: must be of
371: type NOUN. If the (\fIcontainer\fR) clause is omitted,
372: the new object is placed in object .ALL .
373: the
374: .I noun
375: may actually be a adjective-noun pair.
376: .PP
377: .B Examples:
378: .DS
379: NOUN red book, blue book;
380: NOUN worm(red book);
381: .DE
382: .sp
383: .IP "ROUTINE \fIroutinename, routinename, ...\fR" 8
384: Declares that the \fIroutinename\fRs listed will be used
385: for Routines later in the program. This is to allow \s-2DDL\s+2,
386: which is intended to be easily implementable, to deal with
387: recursive routines (which have not yet been declared at the
388: time of their definitions). Only routines which are used
389: before being defined need to be declared with this statement.
390: .sp
391: .IP "ARTICLE \fIarticle, article,\fR..." 8
392: .PP
393: Creates each \fIarticle\fR as an article. Articles are recognized
394: by the run-time parser, but are basically "noise" words.
395: .PP
396: .B Example:
397: ARTICLE the;
398: .IP "PREP \fIprep, prep\fR,..." 8
399: .PP
400: Creates each
401: .I prep
402: as a preposition. Prepositions are basically
403: noise words, but are used by the parser to recognize the presence of
404: indirect objects in the Player's input.
405: .PP
406: .B Example:
407: PREP into,on,using,to,at;
408: .sp
409: .IP "\fInoun\fR (\fInumexp\fR) = \fIexp2\fR" 8
410: .PP
411: Property \fInumexp\fR of \fInoun\fR is set to the
412: value of \fIexp2\fR.
413: .I exp2
414: may be a number, a string, a routine name, or a new routine;
415: the numeric value or ID of
416: .I exp2
417: is always placed into the specified property.
418: .PP
419: .B Examples:
420: .DS
421: gem(11)=0; { 11 == Luminous }
422: gem(LDESC) = ($say "There is a bright gem here!");
423: gem(SDESC) = ($say "a bright gem");
424: gem(ACTION) = GmAct;
425: .DE
426: .sp
427: .IP "\fIverb\fR (PREACT | ACTION) = \fIroutine\fR" 8
428: .PP
429: Assigns \fIroutine\fR as the pre-object action or default action of
430: the given \fIverb\fR. The routine may be a predefined routine name or
431: an actual routine.
432: .PP
433: .B Example:
434: .DS
435: rub(ACTION) = ($say "Rubbing ")
436: ($sdisc ($dobj))
437: ($say " seems silly.\\n");
438: .DE
439: .sp
440: .IP "\fIname\fR = \fInumber\fR" 8
441: .PP
442: Assigns \fIname\fR as equivalent to \fInumber\fR. \fIname\fR
443: must not be previously assigned.
444: .PP
445: .B Example:
446: OPEN=11; TRUE=1;
447: .IP "\fIname1\fR = \fIname2\fR" 8
448: .PP
449: Assigns
450: .I name1
451: as a synonym for
452: .I name2.
453: .PP
454: .B Example:
455: n=north;s=south;se=southeast;
456: .IP "(\fInumexp\fR) = \fInumexp2\fR" 8
457: .PP
458: Assigns the global (or VAR) named by \fInumexp\fR to the value
459: given by \fInumexp2\fR.
460: .PP
461: .B Example:
462: (Maxpt)=450;
463: .IP "\fIname\fR = "
464: "\fIstring\fR"
465: .PP
466: Assigns
467: .I name
468: as equivalent to "\fIstring\fR".
469: .B Note:
470: This seems to be rarely, if ever, used. Usually it's just
471: as easy to assign a routine to Say the given string.
472: However, there are other string functions, such as $eqst
473: and $substr, for which it may be useful to predefine strings.
474: .PP
475: .B Example:
476: err="Nothing happens.\\n";
477: MagicWord = "ShaZam";
478: .IP "\fIname\fR = \fIroutine\fR" 8
479: .PP
480: Assigns
481: .I name
482: as equivalent to
483: .I routine
484: .PP
485: .B Example:
486: sayer=($say "Nothing happens.\\n");
487: .IP "INCLUDE ""\fIfilename\fR""" 8
488: .PP
489: .B
490: (\s-2UNIX\s+2 implementation only)
491: .R
492: Causes input to be read from the named file.
493: .RE
494: .NH
495: Routines
496: .PP
497: A routine is a list of one or more "forms". Forms are of three types:
498: .RS
499: .IP "(\fIform1\fB : \fIform, form\fR ... [: \fIelseform, elseform\fR ...])" 8
500: .PP
501: Conditional expression. If
502: .I form1
503: evaluates to
504: nonzero, the subsequent \fIform\fRs are executed in
505: sequence. Otherwise, the list of \fIelseform\fRs is executed in sequence.
506: .B Note:
507: The second colon, and the subsequent \fIelseform\fRs, are optional.
508: .PP
509: .B Example:
510: .PP
511: .DS
512: (TRUE : ($say "Always do me") : ($say "Never do me"))
513: .DE
514: .IP "(WHILE \fIform1\fR : \fIform, form ... \fR)" 8
515: .PP
516: Simple looping construct. If \fIform1\fR evaluates
517: to nonzero, the subsequent \fIform\fRs are evaluated
518: in sequence. This process is repeated until such
519: a time as \fIform1\fR is found to evaluate to zero.
520: .PP
521: .B Example:
522: .PP
523: .DS
524: (WHILE ($eq ($loc .ME) JewlRoom) : (TRYmv .ME Prison))
525: .DE
526: .IP "(\fIfunction arg1 arg2\fR ...)" 8
527: .PP
528: Function call (note that all builtin functions
529: begin with the character $). The \fIfunction\fR is applied
530: to the \fIarg\fRs. An argument may be a number,
531: string, declared name, or another form. However, the function must
532: be a simple identifier, or a form which evaluates to a function
533: identifier (
534: .I
535: e.g.
536: .R
537: ($ldisc xxx)).
538: In addition, three special argument types are recognized:
539: .PP
540: An argument such as "@\fInumber\fR" is interpreted as
541: "contents of global \fInumber\fR".
542: .PP
543: An argument such as "%\fInumber\R" is interpreted as "the value of the \fInumber\R
544: argument to this function".
545: .PP
546: An argument such as "[\fIadj noun\fR]" must be used if the programmer wishes to
547: refer to an object with an associated adjective.
548: .RE
549: .PP
550: .B Examples:
551: .DS
552: .SM
553: VERB north,south,east,west,ne,nw,se,sw,up,down;
554: n=north; s=south; e=east; w=west; u=up; d=down;
555:
556: NOUN rm001,rm002,rm003,rm004,rm005,rm006;
557: NOUN .ME(rm001);
558:
559: ADJECTIVE red,blue;
560: NOUN red ball(rm002),blue ball(rm003);
561:
562: red ball(LDESC) = ($say "There is a red ball here.");
563: red ball(SDESC) = ($say "Red ball.");
564:
565: VAR score;
566: (score) = 0;
567:
568: TAKBT = 16;
569: TRUE = 1; FALSE=0;
570: red ball(TAKBT) = TRUE;
571:
572: ROUTINE takeR; { Declared later }
573:
574: VERB take;
575: take(ACTION) = ( ($and ($prop ($dobj) TAKBT)
576: ($eq ($loc .ME)($loc ($dobj)))):
577: (takeR ($dobj))
578: );
579: takeR = ($move %1 .ME)
580: (($eq %1 [red ball]):
581: ($say "The ball is glowing!")
582: ($setg score ($plus 10 @score)));
583: .NL
584: .DE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.