home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 103 / af103sub.adf / Hugo.LZX / Hugo / Manual.txt < prev    next >
Text File  |  1990-02-22  |  225KB  |  6,968 lines

  1. -----------------------------------------------------------------
  2.                             HUGO v2.3d
  3.  
  4.                         PROGRAMMING MANUAL
  5.  
  6.               Copyright (c) 1995-1997 by Kent Tessman
  7. -----------------------------------------------------------------
  8.  
  9.  
  10. -----------------------------------------------------------------
  11.                          TABLE OF CONTENTS
  12. -----------------------------------------------------------------
  13.  
  14.  
  15. I.  INTRODUCTION
  16.  
  17.      I.a.  Legal notes
  18.      I.b.  Names and acknowledgements
  19.      I.c.  Packing list
  20.      I.d.  Manual conventions
  21.      I.e.  Getting started
  22.      I.f.  Compiler switches
  23.      I.g.  Limit settings
  24.      I.h.  Directories
  25.  
  26.           EXAMPLE:  Command-line compiling
  27.  
  28.      I.i.  The Engine
  29.  
  30.  
  31. II.  A FIRST LOOK AT HUGO
  32.  
  33.      II.a.  Hello, Sailor!
  34.      II.b.  Data types
  35.      II.c.  Comments
  36.      II.d.  Multiple lines
  37.      II.e.  Compiler errors
  38.      II.f.  Compiler directives
  39.  
  40.  
  41. III.  OBJECTS
  42.  
  43.      III.a.  The object tree
  44.      III.b.  Attributes
  45.      III.c.  Properties
  46.      III.d.  Classes
  47.  
  48.  
  49. IV.  HUGO PROGRAMMING
  50.  
  51.      IV.a.  Variables
  52.      IV.b.  Constants
  53.      IV.c.  Printing text
  54.  
  55.           EXAMPLE:  Mixing text styles
  56.  
  57.      IV.d.  More control characters
  58.      IV.e.  Operators and assignments
  59.      IV.f.  Efficient operators
  60.      IV.g.  Arrays and strings
  61.  
  62.           EXAMPLE:  Managing strings
  63.  
  64.      IV.h.  Conditional expressions and program flow
  65.  
  66.  
  67. V.  ROUTINES AND EVENTS
  68.  
  69.      V.a.  Routines
  70.      V.b.  Property routines
  71.  
  72.           EXAMPLE:  "Borrowing" property routines
  73.  
  74.      V.c.  Before and after routines
  75.  
  76.           EXAMPLE:  Building a complex object
  77.  
  78.      V.d.  Init and main
  79.      V.e.  Events
  80.  
  81.           EXAMPLE:  Building a clock event
  82.  
  83.  
  84. VI.  FUSES, DAEMONS, AND SCRIPTS
  85.  
  86.      VI.a.  Fuses and daemons
  87.  
  88.           EXAMPLE:  A simple daemon and simpler fuse
  89.  
  90.      VI.b.  Scripts
  91.      VI.c.  A note about the event_flag global
  92.  
  93.  
  94. VII.  GRAMMAR AND PARSING 
  95.  
  96.      VII.a.  Grammar definition
  97.      VII.b.  The parser
  98.  
  99.  
  100. VIII.  JUNCTION ROUTINES
  101.  
  102.      VIII.a.  Parse
  103.      VIII.b.  ParseError
  104.      VIII.c.  EndGame
  105.      VIII.d.  FindObject
  106.      VIII.e.  SpeakTo
  107.  
  108.  
  109. IX.  THE GAME LOOP
  110.  
  111.  
  112. X.  ADVANCED FEATURES
  113.  
  114.      X.a.  Reading and writing files
  115.  
  116.  
  117. APPENDIX A:  SUMMARY OF KEYWORDS AND COMMANDS
  118.  
  119. APPENDIX B:  THE LIBRARY (HUGOLIB.H)
  120.  
  121.      Globals, constants, and arrays
  122.      Properties
  123.      Routines
  124.  
  125. APPENDIX C:  LIMIT SETTINGS
  126.  
  127. APPENDIX D:  PRECOMPILED HEADERS
  128.  
  129. APPENDIX E:  THE HUGO DEBUGGER
  130.  
  131.  
  132.  
  133. -----------------------------------------------------------------
  134. I.  INTRODUCTION
  135. -----------------------------------------------------------------
  136.  
  137. Hugo is a system for designing, programming, and running
  138. sophisticated interactive fiction, or text adventures.  It is the
  139. result of an attempt to further extend the concepts developed in
  140. earlier, similar systems in order to make interactive fiction
  141. programming less cryptic and more accessible to designers.  Hugo
  142. owes much to the original Infocom format (particularly with regard
  143. to its internal data tables) as well as to Graham Nelson's publicly
  144. distributed Inform compiler (and its excellent grammar definition
  145. and programming style).
  146.  
  147. The best advice to be given for learning Hugo is probably to print
  148. the source listing of SAMPLE.HUG, and refer to it throughout;
  149. examples of almost all of Hugo's features may be found in it.
  150.  
  151.  
  152. -----------------------------------------------------------------
  153. I.a.  LEGAL NOTES
  154. -----------------------------------------------------------------
  155.  
  156. Programs created using the Hugo Compiler are the property of the
  157. individual author.  Note, however, that the library files are
  158. copyright by Kent Tessman, the creator of Hugo, as is the Hugo
  159. Engine.
  160.  
  161. The use of the Hugo library files and the distribution of the Hugo
  162. Engine are authorized so long as all transactions are non-commercial
  163. and free of charge, and that the library files and engine are not
  164. distributed in a modified form.
  165.  
  166. For those interested in the commercial distribution of a program
  167. created with the Hugo Compiler, please contact Kent Tessman for
  168. permission.
  169.  
  170. NOTE:  Since the Hugo Compiler and Engine are provided free of
  171. charge, there is no warranty for their use.
  172.  
  173.  
  174.  
  175. -----------------------------------------------------------------
  176. I.b.  NAMES AND ACKNOWLEDGEMENTS
  177. -----------------------------------------------------------------
  178.  
  179. Those who have taken upon themselves the (sometimes trying, I'm
  180. sure) task of porting Hugo to various platforms are:
  181.  
  182.      David Kinder        Amiga
  183.      Bill Lash           Unix (i.e. Solaris OS, Linux, etc.)
  184.      Colin Turnbull      Acorn Archimedes
  185.  
  186. The author is considerably indebted to them, for all their work as
  187. well as for their input on how to improve the compiler and engine.
  188.  
  189. A few words of appreciation are due Volker Blasius who (now with
  190. help from David Kinder) has had the substantial responsibility of
  191. maintaining the Interactive Fiction Archive at ftp://ftp.gmd.de--one
  192. of the key resources for Hugo programmers and a primary hub of
  193. material for contributors to (and readers of) the newsgroups
  194. rec.arts.int-fiction and rec.games.int-fiction.
  195.  
  196. A good deal of acknowledgement and thanks are due Graham Nelson,
  197. whose Inform language helped give shape to Hugo's early syntax and
  198. structure.
  199.  
  200. Thanks also to those whose comments and suggestions have contributed
  201. to making Hugo as useful and usable as it is:  Dr. Jeff Jenness,
  202. Vikram Ravindran, Jesse McGrew, Paolo Vece, Daniel Cardenas, Cam
  203. Bowes, Mark Bijster, Jose Luis Cebrian, and John Menichelli.
  204.  
  205. Special thanks to Jim Newland and Julian Arnold:  Jim, for his work
  206. on the nefarious plural/identical-objects architecture that found
  207. its way into OBJLIB.H (and actually coaxed that aspect of the object
  208. library into existence)--one of many, many valuable contributions to
  209. Hugo's development; and Julian for asking time and time again
  210. "Wouldn't it be better if...?"
  211.  
  212. Finally, my brother Dean Tessman has given valuable input to the
  213. system's development, particularly with the advent of the Debugger,
  214. and his views on user interfaces and the occasional head-shake
  215. followed by "I don't think that's gonna fly..." are much
  216. appreciated.
  217.  
  218.  
  219. -----------------------------------------------------------------
  220. I.c.  PACKING LIST
  221. -----------------------------------------------------------------
  222.  
  223. A number of files are part of the basic Hugo package:
  224.  
  225. (NOTE:  Throughout this manual, the default naming convention is for
  226. MS-DOS.  As Hugo becomes available for other systems, file naming
  227. conventions may vary, and any machine-specific documentation should
  228. document those variations.)
  229.  
  230.      HC.EXE         Hugo Compiler
  231.      HE.EXE         Hugo Engine
  232.      HD.EXE         Hugo Debugger
  233.      HDHELP.HLP     Debugger help file
  234.  
  235.      HUGOLIB.H      Library definitions and routines
  236.      GRAMMAR.G      Standard grammar definitions
  237.      OBJLIB.H       A library of useful object definitions
  238.                     (included by HUGOLIB.H)
  239.  
  240.      SAMPLE.HUG     Sample game source code
  241.      SHELL.HUG      Source code to build on
  242.  
  243. And two sets of files that, depending on user-specifiable settings,
  244. are optionally included by HUGOLIB.H and GRAMMAR.G:
  245.  
  246.      HUGOFIX.H      Debugging routines
  247.      HUGOFIX.G      Debugging grammar
  248.  
  249.      VERBSTUB.H     Additional verb routines
  250.      VERBSTUB.G     Additional verb grammar
  251.  
  252. (An additional Hugo source file demonstrates the ability to create
  253. precompiled headers:
  254.  
  255.      HUGOLIB.HUG    To create a #linkable version of HUGOLIB.H)
  256.  
  257. The latest release of Hugo is available through anonymous FTP from
  258. ftp.gmd.de in if-archive/programming/hugo.  Distribution of any of
  259. the Hugo files is authorized only with permission of the author.
  260.  
  261. The .HUG, .H, and .G files are text files and must be downloaded as
  262. such; the executables are binary files.
  263.  
  264. (FORMATTING NOTE:  The above files are properly formatted for a
  265. standard tab stop of 8 spaces; if the formatting appears incorrect,
  266. adjust the tab size on your editor.)
  267.  
  268.  
  269. -----------------------------------------------------------------
  270. I.d.  MANUAL CONVENTIONS
  271. -----------------------------------------------------------------
  272.  
  273. The following conventions will (hopefully) be adhered to throughout
  274. this manual in order to distinguish the following from plain text:
  275.  
  276.      <parameter>    for required parameters
  277.  
  278.      [parameter]    for optional parameters
  279.  
  280.      FILE           for specific filenames
  281.  
  282.      KEYWORD        for commands, functions, etc.
  283.  
  284.      ...            for omissions
  285.  
  286. (Filenames and keywords may not appear in all-capitals when set
  287. apart from the regular text of this manual, as in the invocation
  288. examples below.)
  289.  
  290.  
  291. -----------------------------------------------------------------
  292. I.e.  GETTING STARTED
  293. -----------------------------------------------------------------
  294.  
  295. Type
  296.  
  297.      hc
  298.  
  299. without any parameters to get a full listing of available compiler
  300. options and specifications.
  301.  
  302. The MS-DOS syntax for running the compiler is
  303.  
  304.      hc [-switches] <sourcefile[.HUG]> <objectfile>
  305.  
  306. It is not necessary to specify any switches, the name of the
  307. objectfile, or the sourcefile extension.  The bare-bones version of
  308. the compiler invocation is
  309.  
  310.      hc <sourcefile>
  311.  
  312. With no other parameters explicitly described, the compiler assumes
  313. an extension of .HUG.  The default object filename is
  314. <sourcefile>.HEX.
  315.  
  316. Here's how to compile the sample game.  With the compiler
  317. executable, library files, and sample game source code all in the
  318. current directory, type
  319.  
  320.      hc -ls sample.hug
  321.  
  322. or simply
  323.  
  324.      hc -ls sample
  325.  
  326. and after a few seconds (or more, or less, depending on your
  327. processor and configuration) a screenful of statistical information
  328. will appear following the completed compilation (because of the -s
  329. switch).
  330.  
  331. The new file SAMPLE.HEX will have appeared in current directory.  As
  332. well, the -l switch wrote all compile-time output (which would have
  333. included errors, had there been any) to the file SAMPLE.LST.
  334.  
  335.  
  336. -----------------------------------------------------------------
  337. I.f.  COMPILER SWITCHES
  338. -----------------------------------------------------------------
  339.  
  340. A number of switches may be selected via the invocation line.  The
  341. available options are:
  342.  
  343.      -a   Abort compilation on any error
  344.      -d   compile as an .HDX debuggable executable
  345.      -f   Full object summaries
  346.      -h   compile in .HLB precompiled Header format
  347.      -i   display debugging Information
  348.      -l   print Listing to disk as <sourcefile>.LST
  349.      -o   display Object tree
  350.      -p   send output to standard Printer
  351.      -s   print compilation Statistics
  352.      -u   show memory Usage for objectfile
  353.      -x   ignore switches in source code
  354.      -z   inhibit normal compilation messages
  355.  
  356. Most Hugo programming will probably make us of the -l switch in
  357. order to record compile-time errors.
  358.  
  359. The -z switch may, on some configurations, increase compilation
  360. speed by inhibiting normal messaging (i.e. "Compiling...lines of..."
  361. and "...percent complete").
  362.  
  363.  
  364. -----------------------------------------------------------------
  365. I.g.  LIMIT SETTINGS
  366. -----------------------------------------------------------------
  367.  
  368. Also included on the invocation line, after any switches and before
  369. the sourcefile, may be one or more limit settings.  These settings
  370. are for memory management, and limit the number of certain types of
  371. program elements, such as objects and dictionary entries.
  372.  
  373. To list the settings, type:
  374.  
  375.      hc $list
  376.  
  377. To change a non-static limit, type:
  378.  
  379.      hc $<setting>=<new limit> <sourcefile>...
  380.  
  381. For example, to compile the sample game with the maximum number of
  382. dictionary entries doubled from the default limit of 1024, and with
  383. the -l and -s switches set,
  384.  
  385.      hc -ls $MAXDICT=2048 sample
  386.  
  387. If a compile-time error is generated indicating that too many
  388. symbols of a particular type have been declared, it is probably
  389. possible to overcome this simply by recompiling with a higher limit
  390. for that setting specified in the invocation line.
  391.  
  392. See Appendix C for a complete listing of valid limit settings.
  393.  
  394.  
  395. -----------------------------------------------------------------
  396. I.h.  DIRECTORIES
  397. -----------------------------------------------------------------
  398.  
  399. It is possible to specify where the Hugo Compiler will look for
  400. different types of files.  This can be done in the command line via:
  401.  
  402.      hc @<directory>=<real directory>
  403.  
  404. For example, to specify that the source files are to be taken from
  405. the directory C:\HUGO\SOURCE, invoke the compiler with
  406.  
  407.      hc @source=c:\hugo\source <filename>
  408.  
  409. Valid directories are:
  410.  
  411.      source    Source files
  412.      object    Where the new .HEX file will be created
  413.      lib       Library files
  414.      list      .LST files
  415.      temp      Temporary compilation files (if any)
  416.  
  417. Advanced users may take advantage of the ability to set default
  418. directories using environment variables.  (The method for setting an
  419. environment variable may vary from operating system to operating
  420. system.)
  421.  
  422. The HUGO_<NAME> environment variable may be set to the <name>
  423. directory.  For example, the source directory may be set with the
  424. HUGO_SOURCE environment variable.
  425.  
  426. Command-line-specified directories take precedence over those set in
  427. environment variables.  In either case, if the file is not found in
  428. the specified directory, the current directory is searched.
  429.  
  430.  
  431. -----------------------------------------------------------------
  432. EXAMPLE:  COMMAND-LINE COMPILING
  433. -----------------------------------------------------------------
  434.  
  435. On the author's machine, running under MS-DOS, the compiler
  436. executable HC.EXE is in a directory called C:\HUGO.  The library
  437. files are in C:\HUGO\LIB, and the source code for the game Spur is
  438. in C:\HUGO\SPUR.
  439.  
  440. What would the command line look like in order to compile Spur,
  441. including setting compiler flags to include the HugoFix debugging
  442. library and verb stub routines, and printing all debugging
  443. information, the object tree, and statistics to a file?  (Assume
  444. that the current directory is C:\HUGO and that none of the switches
  445. or compiler flags are set in the source.)
  446.  
  447. ANSWER:
  448.  
  449.      hc -iols #debug #verbstubs @source=spur @lib=lib spur
  450.  
  451.  
  452. -----------------------------------------------------------------
  453. I.i.  THE ENGINE
  454. -----------------------------------------------------------------
  455.  
  456. Having compiled the sample game, run it by invoking
  457.  
  458.      he sample
  459.  
  460. Again, it is not necessary to specify the extension.  The engine
  461. assumes .HEX if none is given.
  462.  
  463. (NOTE:  The environment variable HUGO_OBJECT or HUGO_GAMES may hold
  464. the directory that the Hugo Engine searches for the specified .HEX
  465. file.  The location for save files may be specified with HUGO_SAVE. 
  466. All of these are optional.)
  467.  
  468.  
  469.  
  470. -----------------------------------------------------------------
  471. II.  A FIRST LOOK AT HUGO
  472. -----------------------------------------------------------------
  473.  
  474. There are a couple of basic concepts to become oriented to in order
  475. to begin working with Hugo.
  476.  
  477. First of all, most programming in Hugo will involve the creation of
  478. what are called "objects".  Quite literally, these represent the
  479. elements of the game universe:  people, places, and things.
  480.  
  481. The bulk of the rest of a Hugo program is comprised of "routines". 
  482. These are the sections of code made up of commands or statements
  483. that facilitate the actual behavior of the program at different
  484. points in the story.  Routines are less frequently (although more
  485. frequently in other languages) called "functions"--they may be
  486. thought of as performing an operation or series of operations, and
  487. then returning some kind of value as a result.
  488.  
  489. (The idea of return values is an important one and, while sometimes
  490. puzzling to novices, is actually quite uncomplicated.  Often a
  491. particular function will be referred to as "returning true" or
  492. "returning false"--all this means is that it returns either a non-
  493. zero value (usually 1) or a zero value, almost always to indicate
  494. success or failure.  A program will constantly be checking the
  495. return values of a variety of routines and commands to determine if
  496. a particular operation was successful in order to decide what to do
  497. next.  Of course, a return value can be any integer value; a routine
  498. that adds together two supplied values, a and b, may return the sum
  499. a+b.)
  500.  
  501. For those familiar with the common programming languages C and
  502. BASIC, Hugo strongly resembles a hybrid of the two.  Individual
  503. objects and routines--as well as conditional blocks--are enclosed in
  504. braces as in C, but unlike C (and like BASIC), a semicolon is not
  505. required at the end of each line, and the language itself is
  506. considerably less cryptic.  Keywords, variables, routine and object
  507. names, and other tokens are not case-sensitive.
  508.  
  509. The goal in designing Hugo was to make programming as intuitive to
  510. facilitate both initial development and subsequent debugging.
  511.  
  512.  
  513. -----------------------------------------------------------------
  514. II.a.  HELLO, SAILOR!
  515. -----------------------------------------------------------------
  516.  
  517. The grand (recent) tradition of programming texts has an
  518. introduction to a new programming language detailing how to print
  519. the optimistic phrase "Hello, world" as an example of the particular
  520. language's form and substance.
  521.  
  522. In the equally grand tradition of interactive fiction, we'll start
  523. with the rallying cry "Hello, Sailor!".  Don't worry too much about
  524. the syntax below; this is meant mainly as a familiarization with
  525. what Hugo looks like.
  526.  
  527.      routine main
  528.      {
  529.           print "Hello, Sailor!"
  530.           return
  531.      }
  532.  
  533. The entire program consists of one routine.  (Two routines are
  534. normally required for any Hugo program, the other being the Init
  535. routine, which is omitted in this example since there isn't much
  536. required in the way of initialization.)
  537.  
  538. The Main routine is automatically called by the engine.  It from
  539. here that the central behavior of any Hugo program is controlled. 
  540. In this case the task at hand is the printing of "Hello, Sailor!",
  541. followed by an order to return from the routine (i.e. exit it) so
  542. that we don't strand the program waiting for an input, which is the
  543. normal order of Hugo business.
  544.  
  545.  
  546. -----------------------------------------------------------------
  547. II.b.  DATA TYPES
  548. -----------------------------------------------------------------
  549.  
  550. All data in Hugo is represented in terms of 16-bit integers, treated
  551. as signed (-32767 to 32767) or unsigned (0 to 65535) as appropriate. 
  552. The name of any individual data type may contain up to 32
  553. alphanumeric characters (as well as the underscore "_").
  554.  
  555. All of the following are valid data types:
  556.  
  557.      Integer values      0, -10, 16800, -25005
  558.      (constant values that appear in Hugo source code as numbers)
  559.  
  560.      ASCII characters    'A', 'z', '7'
  561.      (constant values equal to the common ASCII value for a
  562.      character; i.e. 65 for 'A')
  563.  
  564.      Objects             suitcase, emptyroom, player
  565.      (constant values representing the object number of the given
  566.      object)
  567.  
  568.      Variables           a, b, score, TEXTCOLOR
  569.      (changeable value-holders that may be set to equal another
  570.      variable or constant value)
  571.  
  572.      Constants           true, false, BANNER
  573.      (constant--obviously--values that are given a name similarly to
  574.      a variable, but are non-modifiable)
  575.  
  576.      Dictionary entries  "a", "the", "basketball"
  577.      (The appearance of "the" in a line of code actually refers to
  578.      the location in the dictionary table where "the" is stored.)
  579.  
  580.      Array elements      ranking[1]
  581.      (a series of one or more changeable values that may be
  582.      referenced from a common base point)
  583.  
  584.      Array addresses     ranking
  585.      (the base point--see above)
  586.  
  587.      Properties          nouns, short_desc, found_in
  588.      (variable attachments of data relating specifically to objects)
  589.  
  590.      Attributes          open, light, transparent
  591.      (less complex attachments of data describing an object, which
  592.      may be specified as either having or not having the given
  593.      attribute)
  594.  
  595. Most of these types are relatively straightforward, representing in
  596. most cases a simple value.  Dictionary entries are addresses in the
  597. dictionary table, with the null string "" having the value 0.  Array
  598. addresses (as opposed to separate array elements) represent the
  599. address at which the array begins in the array table.  Properties
  600. and attributes treated as discrete values represent the number of
  601. that property or attribute, assigned sequentially as the individual
  602. property or attribute is defined.
  603.  
  604. As mentioned, routines also return values, as do engine functions,
  605. so that
  606.  
  607.      FindLight(room)
  608.  
  609. and
  610.  
  611.      parent(object)
  612.  
  613. are also valid integer data types.
  614.  
  615. Routine addresses are also stored as 16-bit integers.  However,
  616. those versed in such calculations will notice that if such a value
  617. was treated as an absolute address, then any addressable executable
  618. code would be limited to 64K in size.  Such is not the case, since
  619. the routine address is actually an indexed representation of the
  620. absolute address.
  621.  
  622. NOTE:  The 16-bit format of a routine address (or the address of a
  623. property routine, to be discussed below), can obtained via the
  624. address operator "&", as in:
  625.  
  626.      x = &Routine
  627.      x = &object.property
  628.  
  629. (where x is a variable).
  630.  
  631.  
  632. -----------------------------------------------------------------
  633. II.c.  COMMENTS
  634. -----------------------------------------------------------------
  635.  
  636. There are two types of comments.  Comments on a single line begin
  637. with a '!'.  Anything following on the line is ignored.  Multiple-
  638. line comments are begun with !\ and ended with \!.
  639.  
  640.      ! A comment on a single line
  641.  
  642.      !\ A multiple-line
  643.         comment \!
  644.  
  645. The !\ combination must come at the start of a line to be
  646. significant; it cannot be preceded by any other statements or
  647. remarks.  Similarly, the \! combination must come at the end of a
  648. line.
  649.  
  650.  
  651. -----------------------------------------------------------------
  652. II.d.  MULTIPLE LINES
  653. -----------------------------------------------------------------
  654.  
  655. If any single command is too long to fit on one line, it may be
  656. split across several lines by ending all but the last with the
  657. control character "\".
  658.  
  659.      "This is an example string."
  660.  
  661. and
  662.      x = 5 + 6 * higher(a, b)
  663.  
  664. are the same as
  665.  
  666.      "This is an example \
  667.       string."
  668.  
  669.      x = 5 + 6 * \
  670.           higher(a, b)
  671.  
  672. The space at the end of the first line is necessary because the
  673. compiler automatically trims leading spaces from the second line.
  674.  
  675. String constants, such as in the above print statement, are an
  676. exception in that they do not require the "\" character at the end
  677. of each line.
  678.  
  679.      print "The engine will properly
  680.      print this text, assuming a
  681.      single space at the end of each
  682.      line."
  683.  
  684. will result in:
  685.  
  686.      The engine will properly print this text, assuming a single
  687.      space at the end of each line.
  688.  
  689. Care must be taken, however, to ensure that the closing quotes are
  690. not left off the string constant.  Failing that, the compiler will
  691. likely generate a "Closing brace missing" error when it overruns the
  692. object/routine/event boundary looking for a resolution to the odd
  693. number of quotation marks.
  694.  
  695. Also, most lines ending in a comma, "and", or "or" will
  696. automatically fall through to the next line (if they occur in a line
  697. of code).  In other words,
  698.  
  699.      x[0] = 1, 2, 3,     ! array assignment of x[0] through x[4]
  700.           4, 5
  701.  
  702. and
  703.  
  704.      if a = 5 and 
  705.           b = "tall"
  706.  
  707. translate into
  708.  
  709.      x[0] = 1, 2, 3, 4, 5
  710.  
  711. and
  712.  
  713.      if a = 5 and b = "tall"
  714.  
  715. This is provided primarily so that lengthy lines and complex
  716. expressions do not have to run off the right-hand side of the screen
  717. during editing, nor do they continually need to be extended using
  718. "\" and the end of each line.
  719.  
  720. (NOTE:  Multiple lines that are not strictly code, such as property
  721. assignments in object definitions--to be discussed--must still be
  722. joined with "\", as in
  723.  
  724.      nouns "plant", "flower", "marigold", \
  725.           "fauna", "greenery"
  726.  
  727. and similar cases, even if they end in a comma.)
  728.  
  729. There is a complement to the "\" control character:  the ":"
  730. character allows multiple lines to be put together on a single line,
  731. i.e.
  732.  
  733.      x = 5 : y = 1
  734.  
  735. or
  736.  
  737.      if i = 1:  print "Less than three."
  738.  
  739. Which the compiler translates to
  740.  
  741.      x = 5
  742.      y = 1
  743.  
  744. and
  745.  
  746.      if i = 1
  747.           {print "Less than three."}
  748.  
  749. (See sections below on code formatting to see exactly what these
  750. constructions represent.)
  751.  
  752.  
  753. -----------------------------------------------------------------
  754. II.e.  COMPILER ERRORS
  755. -----------------------------------------------------------------
  756.  
  757. A compiler error is generally of one of two types.  A fatal error
  758. looks like this:
  759.  
  760.      FATAL ERROR:  <message>
  761.  
  762. and halts compiler execution.
  763.  
  764. A non-fatal error typically looks like:
  765.  
  766.      <FILENAME>:  <location>
  767.      (...the offending code...)
  768.      ERROR:  <message>
  769.  
  770. It prints the section of code that caused the error, followed by an
  771. explanation of the problem.  Compilation will generally continue
  772. unless the -a switch has been set.
  773.  
  774. NOTE:  The section of offending code may not be printed exactly as
  775. it appears in the source, since the compiler often paraphrases and
  776. rebuilds the source code into a more rigid format before building
  777. the line.
  778.  
  779. Also, the compiler may issue warnings in the form:
  780.  
  781.      WARNING:  <message>
  782.  
  783. Compilation will continue, but this is an indication that the
  784. compiler suspects a problem at compile-time.
  785.  
  786. If the -g switch has been set during invocation to generate generic-
  787. format errors, error output looks like:
  788.  
  789.      filename(line):  Error:  <error message>
  790.  
  791. (The usefulness of this is that some editors recognize the above
  792. type of error for line-seeking within a given file.)
  793.  
  794.  
  795. -----------------------------------------------------------------
  796. II.f.  COMPILER DIRECTIVES
  797. -----------------------------------------------------------------
  798.  
  799. A number of special commands may be used to determine a.) how the
  800. source code is read by the compiler, or b.) what special output will
  801. be generated at compile time.
  802.  
  803. To set switches within the source code so that they do not have to
  804. be specified each time the compiler is invoked for that particular
  805. program, the line
  806.  
  807.      #switches -<sequence>
  808.  
  809. will set the switches specified by <sequence>, where <sequence> is
  810. a string of characters representing valid switches, without any
  811. separators between characters.
  812.  
  813. Many programmers may find it useful to make
  814.  
  815.      #switches -ils
  816.  
  817. the first line in every new program, which will automatically print
  818. out debugging information, a statistical summary, and any errors to
  819. the .LST list file.
  820.  
  821. Using
  822.  
  823.      #version <version>[.<revision>]
  824.  
  825. specifies that the file is to be used with version
  826. <version>.<revision> of the compiler.  If the file and compiler
  827. version are mismatched, a warning will be issued.
  828.  
  829. To include the contents of another file at the specified point in
  830. the current file, use
  831.  
  832.      #include "<filename>"
  833.  
  834. where <filename> is the full path and name of the file to be read. 
  835. When <filename> has been read completely, the compiler resumes with
  836. the statement immediately following the INCLUDE command.
  837.  
  838. (A file or set of files can be compiled into a precompiled header
  839. using the -h switch, and then linked using #link instead of
  840. #include.  See Appendix D on Precompiled Headers.)
  841.  
  842. A useful tool for managing Hugo source code is the ability to use
  843. compiler flags for conditional compilation.  A compiler flag is
  844. simply a user-defined marker that can control which sections of the
  845. source code are compiled.  In this way, a programmer can develop
  846. add-ons to a program that can be included or excluded at will.  For
  847. example, the library files HUGOLIB.H and GRAMMAR.G check to see if
  848. a flag called DEBUG has been set previously (as it is in
  849. SAMPLE.HUG).  Only if it has do they include the HUGOFIX.H and
  850. HUGOFIX.G files.
  851.  
  852. To set and clear flags, use
  853.  
  854.      #set <flagname>
  855.  
  856. and
  857.  
  858.      #clear <flagname>
  859.  
  860. respectively.
  861.  
  862. Then, check to see if a flag is set or not (and include or exclude
  863. the specified block of source code) by using
  864.  
  865.      #ifset <flagname>
  866.           ...conditional block of code...
  867.      #endif
  868.  
  869. or
  870.  
  871.      #ifclear <flagname>
  872.           ...conditional block of code...
  873.      #endif
  874.  
  875. Conditional compilation constructions may be nested up to 16 levels
  876. deep.
  877.  
  878. (Remember also that compiler flags can be specified in the
  879. invocation line as #<flag name>.)
  880.  
  881. Finally, the #message directive can be used as
  882.  
  883.      #message "<text>"
  884.  
  885. to output <text> when (or if) that statement is processed during the
  886. first compilation pass.
  887.  
  888. Including "error" or "warning" before "<text>" as in
  889.  
  890.      #message error "<text>"
  891.  
  892. or
  893.  
  894.      #message warning "<text>"
  895.  
  896. will force the compiler to issue an error or warning, respectively,
  897. as it prints "<text>".
  898.  
  899. It is also possible to include inline limit settings, such as
  900.  
  901.      $<setting>=<limit>
  902.  
  903. in the same way as in the invocation line.  However, an error will
  904. be issued if, for example, an attempt is made to reset MAXOBJECTS if
  905. one or more objects have already been defined.
  906.  
  907.  
  908.  
  909. -----------------------------------------------------------------
  910. III.  OBJECTS
  911. -----------------------------------------------------------------
  912.  
  913. Objects are the building blocks of any Hugo program.  Anything that
  914. must be accessible to a player during the game--including items,
  915. rooms, other characters, and even directions--must be defined as an
  916. object.
  917.  
  918. The basic object definition looks like this:
  919.  
  920.      object <objectname> "object name"
  921.      {
  922.           ...
  923.      }
  924.  
  925. As an example, a suitcase object might be defined as:
  926.  
  927.      object suitcase "suitcase"
  928.      {}
  929.  
  930. The enclosing braces are needed even if the object definition has no
  931. body.  The only data attached to the suitcase object are--from right
  932. to left--a name, an identifier, and membership in the basic object
  933. class.
  934.  
  935. The compiler assigns the object labelled <objectname> the next
  936. sequential object number.  That is, if the first-defined object is
  937. the "nothing" object (object 0), then the next-defined object,
  938. whatever it is, is given the object number 1; the one after that is
  939. 2, etc.  This is academic, however, as a programmer need never know
  940. what object number a particular object is--except for certain
  941. debugging situations--and can always refer to an object by its label
  942. <objectname>.
  943.  
  944.  
  945. -----------------------------------------------------------------
  946. III.a.  THE OBJECT TREE
  947. -----------------------------------------------------------------
  948.  
  949. In order for objects to have a position in the game, i.e. to be in
  950. a room or contained in another object or beside another object, they
  951. must occupy a position in the object tree.  The object tree is a map
  952. which represents the relationships between all objects in the game. 
  953. The total number of objects is held in the global variable objects.
  954.  
  955. The nothing object is defined in the library as object 0.  This is
  956. the root of the object tree, upon which all other objects are based.
  957.  
  958. When referring to object numbers, this manual is generally referring
  959. to the name given the object in the source code:  i.e. <objectname>. 
  960. The compiler automatically assigns each object an object number, and
  961. refers to it whenever a specified <objectname> is encountered.
  962.  
  963. (NOTE:  When using the standard library routines, ensure that no
  964. objects (or classes, to be discussed later) are defined before
  965. HUGOLIB.H is included.  Problems will arise if the first-defined
  966. object--object 0--is not the "nothing" object.)
  967.  
  968. Here is an example of an object tree:
  969.  
  970.      Nothing
  971.      |
  972.      Room
  973.      |
  974.      Table-----Chair-----Book------Player
  975.      |                   |
  976.      Bowl                Bookmark
  977.      |
  978.      Spoon     
  979.  
  980. A number of functions can be used to read the object tree.
  981.  
  982.      parent
  983.      sibling
  984.      child
  985.      youngest
  986.      elder
  987.      eldest  (same as child)
  988.      younger (same as sibling)
  989.  
  990. and
  991.  
  992.      children
  993.  
  994. Each function takes a single object as its argument, so that
  995.  
  996.      parent(Table) = Room
  997.      parent(Bookmark) = Book
  998.      parent(Player) = Room
  999.      child(Bowl) = Spoon
  1000.      child(Room) = Table
  1001.      child(Chair) = 0 (Nothing)
  1002.      sibling(Table) = Chair
  1003.  
  1004.      sibling(Player) = 0 (Nothing)
  1005.      youngest(Room) = Player
  1006.      youngest(Spoon) = 0 (Nothing)
  1007.      elder(Chair) = Table
  1008.      elder(Table) = 0 (Nothing)
  1009.  
  1010. and
  1011.  
  1012.      children(Room) = 4
  1013.      children(Table) = 1
  1014.      children(Chair) = 0
  1015.  
  1016. (In keeping with the above explanation of object numbers and
  1017. <objectname>, the functions in the first set actually return an
  1018. integer number that refers to a particular <objectname>.)
  1019.  
  1020. To better understand how the object tree represents the physical
  1021. world, the table, the chair, the book, and the player are all in the
  1022. room.      The bookmark is in the book.  The bowl is on the table,
  1023. and the spoon is on the bowl.  The Hugo library will assume that the
  1024. player object in the example is standing; if the player were seated,
  1025. the object tree might look like:
  1026.  
  1027.      Nothing
  1028.      |
  1029.      Room
  1030.      |
  1031.      Table-----Chair-----Book
  1032.      |         |         |
  1033.      ...       Player    ...
  1034.  
  1035. and
  1036.  
  1037.      child(Chair) = Player
  1038.      parent(Player) = Chair
  1039.      children(Chair) = 1
  1040.  
  1041. (Try compiling SAMPLE.HUG with the -o switch in order to see the
  1042. object tree for the sample game.  Or, if the DEBUG flag was set
  1043. during compilation, use the HugoFix command
  1044.  
  1045.      $ot
  1046.  
  1047. or
  1048.  
  1049.      $ot <object>
  1050.  
  1051. during play to view the current state of the object tree during
  1052. play.)
  1053.  
  1054. Logical tests can also be evaluated with regard to objects and
  1055. children.  The structure
  1056.  
  1057.      <object> [not] in <parent>
  1058.  
  1059. will return true if <object> is in <parent> (or false if NOT is
  1060. used).
  1061.  
  1062. To initially place an object in the object tree, use
  1063.  
  1064.      in <parent>
  1065.  
  1066. in the object definition, or, alternatively
  1067.  
  1068.      nearby <object>
  1069.  
  1070. or simply
  1071.  
  1072.      nearby
  1073.  
  1074. to give the object the same parent as <object> or, if <object> is
  1075. not specified, the same parent as the last-defined object.
  1076.  
  1077. If no such specification is given, the parent object defaults to
  1078. 0--the nothing object as defined in the library.  All normal room
  1079. objects have 0 as their parent.
  1080.  
  1081. Therefore, the expanded basic case of an object definition is
  1082.  
  1083.      object <objectname> "object name"
  1084.      {
  1085.           in <parent object>
  1086.           ...
  1087.      }
  1088.  
  1089. (Ensure that the opening brace "{" does not come on the same line as
  1090. the "object" specifier.
  1091.  
  1092.      object <objectname> "object name" {...
  1093.  
  1094. is not permitted.)
  1095.  
  1096. The table in the example presumably had a definition like
  1097.  
  1098.      object table "Table"
  1099.      {
  1100.           in room
  1101.           ...
  1102.      }
  1103.  
  1104. To put the suitcase object defined earlier into the empty room in
  1105. SHELL.HUG
  1106.  
  1107.      object suitcase "suitcase"
  1108.      {
  1109.           in emptyroom
  1110.      }
  1111.  
  1112. Objects can later be moved around the object tree using the MOVE
  1113. command as in
  1114.  
  1115.      move <object> to <new parent>
  1116.  
  1117. Which, essentially, disengages <object> from its old parent, makes
  1118. the sibling of <object> the sibling of <object>'s elder, and moves
  1119. <object> (along with all its possessions) to the new parent.
  1120.  
  1121. Therefore, in the original example, the command
  1122.  
  1123.      move bowl to player
  1124.  
  1125. would result in altering the object tree to this:
  1126.  
  1127.      Nothing
  1128.      |
  1129.      Room
  1130.      |
  1131.      Table-----Chair-----Book------Player
  1132.                          |         |
  1133.                          Bookmark  Bowl
  1134.                                    |
  1135.                                    Spoon
  1136.  
  1137. There is also a command to remove an object from its position in the
  1138. tree (although it may be returned later):
  1139.  
  1140.      remove <object>
  1141.  
  1142. which is the same as
  1143.  
  1144.      move <object> to 0
  1145.  
  1146.  
  1147. -----------------------------------------------------------------
  1148. III.b.  ATTRIBUTES
  1149. -----------------------------------------------------------------
  1150.  
  1151. Attributes are essentially qualities that every object either does
  1152. or doesn't have.  They are most useful for qualifying or
  1153. disqualifying objects for or from consideration in any given
  1154. instance.
  1155.  
  1156. An attribute is defined as
  1157.  
  1158.      attribute <attribute name>
  1159.  
  1160. Up to 128 attributes may be defined.  Those defined in HUGOLIB.H
  1161. include:
  1162.  
  1163.      known          if an object is known to the player
  1164.      moved          if an object has been moved
  1165.      visited        if a room has been visited
  1166.      static         if an object cannot be taken
  1167.      plural         for plural objects (i.e. some hats)
  1168.      living         if an object is a character
  1169.      female         if a character is female
  1170.      unfriendly     if a character is unfriendly
  1171.      openable       if an object can be opened
  1172.      open           if it is open
  1173.      lockable       if an object can be locked
  1174.      locked         if it is locked
  1175.      light          if an object is or provides light
  1176.      readable       if an object can be read
  1177.      switchable     if an object can be turned on or off
  1178.      switchedon     if it is on
  1179.      clothing       for objects that can be worn
  1180.      worn           if the object is being worn
  1181.      mobile         if the object can be rolled, etc.
  1182.      enterable      if an object is enterable
  1183.      container      if an object can hold other objects
  1184.      platform       if other objects can be placed on it
  1185.                     (NOTE:  container and platform are
  1186.                      mutually exclusive)
  1187.      hidden         if an object is not to be listed
  1188.      quiet          if container or platform is quiet (i.e. the
  1189.                      initial listing of contents is suppressed)
  1190.      transparent    if object is not opaque
  1191.      already_listed if object has been pre-listed (i.e. before
  1192.                      a WhatsIn listing)
  1193.      workflag       for system use
  1194.      special        for miscellaneous use
  1195.  
  1196. Some of these attributes are actually the same attribute with
  1197. different names.  This is accomplished via
  1198.  
  1199.      attribute <attribute2> alias <attribute1>
  1200.  
  1201. where <attribute1> has already been defined.  For example, the
  1202. library equates visited with moved (since, presumably, they will
  1203. never apply to the same object), so:
  1204.  
  1205.      attribute visited alias moved
  1206.  
  1207. In this case, an object which is visited is also, by default, moved. 
  1208. It is expected that attributes which are aliased will never both
  1209. need to be checked under the same circumstances.
  1210.  
  1211. Attributes are given to an object during its definition as follows:
  1212.  
  1213.      object <objectname> "object name"
  1214.      {
  1215.           is [not] <attribute1>, [not] <attribute2>, ...
  1216.           ...
  1217.      }
  1218.  
  1219. NOTE:  The NOT keyword in the object definition is important when
  1220. using a class instead of the basic object definition, where the
  1221. class may have predefined attributes that are undesirable for the
  1222. current object.
  1223.  
  1224. Even if an object was not given a particular attribute in its object
  1225. definition, it may be given that attribute at any later point in the
  1226. program with the command
  1227.  
  1228.      <object> is [not] <attribute>
  1229.  
  1230. where the NOT keyword clears the attribute instead of setting it.
  1231.           
  1232. Attributes can also be read using the IS and IS NOT structures.  As
  1233. a function,
  1234.  
  1235.      <object> is [not] <attribute>
  1236.  
  1237. returns true (1) if <object> is (or is not, if NOT is specified)
  1238. <attribute>.  Otherwise, it returns false (0).
  1239.  
  1240. To give the suitcase object the appropriate attributes, expand the
  1241. object definition to include
  1242.  
  1243.      object suitcase "suitcase"
  1244.      {
  1245.           in emptyroom
  1246.           is openable, not open
  1247.           ...
  1248.      }
  1249.  
  1250. Now, the following equations hold true:
  1251.  
  1252.      suitcase is openable = 1
  1253.      suitcase is open = 0
  1254.      suitcase is locked = 0
  1255.  
  1256.  
  1257. -----------------------------------------------------------------
  1258. III.c.  PROPERTIES
  1259. -----------------------------------------------------------------
  1260.  
  1261. Properties are considerably more complex than attributes.  First,
  1262. not every object may have every property; in order for an object to
  1263. have a property, it must be specified in the object definition.
  1264.  
  1265. As well, properties are not simple on/off flags.  They are sets of
  1266. valid data associated with an object, where the values may represent
  1267. almost anything, including object numbers, dictionary addresses,
  1268. integer values, and addresses of executable code.  The maximum
  1269. number of attached values is undefined, but manageability and
  1270. efficiency suggest eight or less.
  1271.  
  1272. These are some valid properties (using property names defined in
  1273. HUGOLIB.H):
  1274.  
  1275.      nouns "tree", "bush", "shrub", "plant"
  1276.  
  1277.      size 20
  1278.  
  1279.      found_in livingroom, entrancehall
  1280.  
  1281.      long_desc
  1282.           {"Exits lead north and west.  A door is set
  1283.            in the southeast wall."}
  1284.  
  1285.      short_desc
  1286.      {
  1287.           "There is a box here.  It is ";
  1288.           if self is open
  1289.                print "open";
  1290.           else
  1291.                print "closed";
  1292.           print "."
  1293.      }
  1294.  
  1295.      before
  1296.      {
  1297.           object DoGet
  1298.           {
  1299.                if Acquire(player, self)
  1300.                     {"You pick up ";
  1301.                     print Art(self); "."}
  1302.                else
  1303.                     return false
  1304.           }
  1305.      }
  1306.  
  1307. The nouns property contains 4 dictionary addresses; the size
  1308. property is a single integer value; the found_in property holds two
  1309. object numbers; and the long and short description properties are
  1310. both single values representing the address of the attached routine.
  1311.  
  1312. The before property is a special case.  This complex property is
  1313. defined by the compiler and handled differently by the engine than
  1314. a normal property routine.  In this case, the property value
  1315. representing the routine address is only returned if the globals
  1316. object and verbroutine contain the object in question and the
  1317. address of the DoGet routine, respectively.  If there is a match,
  1318. the routine is executed before DoGet.  (There is also an after
  1319. routine, which is checked after the verb routine has been called.)
  1320.  
  1321. (Note for clarity:  the Art routine from HUGOLIB.H prints the
  1322. appropriate article, if any, followed by the name of the object. 
  1323. The Acquire routine returns true only if the first objectþs holding
  1324. property plus the size property of the second object does not exceed
  1325. the capacity property of the first object.)
  1326.  
  1327. All of this may be a little confusing for now.  There will be more
  1328. on property routines later.  For now, think of a property as simply
  1329. containing a value (or set of values).
  1330.  
  1331. A property is defined similiarly to an attribute as
  1332.  
  1333.      property <property name>
  1334.  
  1335. A default value may be defined for the property using
  1336.  
  1337.      property <property name> <default value>
  1338.  
  1339. where <default value> is a constant or dictionary word.  For objects
  1340. without a given property, attempting to find that property will
  1341. result in the default value.  If no default is explicitly declared,
  1342. it is 0.
  1343.  
  1344. The list of properties defined in HUGOLIB.H is:
  1345.  
  1346.      name                the basic object name
  1347.      before              pre-verb routines
  1348.      after               post-verb routines
  1349.      noun                noun(s) for referring to object
  1350.      adjective           adjective(s) for describing object
  1351.      article             "a", "an", "the", "some", etc.
  1352.      preposition         "in", "inside", "outside of", etc.
  1353.      pronoun             appropriate for the object in question
  1354.      short_desc          basic "X is here" description
  1355.      initial_desc        supersedes short_desc
  1356.      long_desc           detailed description
  1357.      found_in            in case of multiple locations
  1358.      type                to identify the type of object
  1359.      n_to
  1360.      ne_to
  1361.      e_to
  1362.      se_to
  1363.      s_to
  1364.      sw_to               (for rooms only, where an exit leads)
  1365.      w_to
  1366.      nw_to
  1367.      u_to
  1368.      d_to
  1369.      in_to
  1370.      out_to
  1371.      cant_go             message if a direction is invalid
  1372.      size                for holding/inventory
  1373.      capacity             "     "        "
  1374.      holding              "     "        "
  1375.      reach               for limiting object accessiblity
  1376.      list_contents       for overriding normal listing
  1377.      door_to             for handling "Enter <object>"
  1378.      key_object          if lockable, the proper key
  1379.      when_open           supersedes short_desc 
  1380.      when_closed             "          "
  1381.      ignore_response     for characters
  1382.      order_response       "      "
  1383.      contains_desc       instead of basic "inside X are..."
  1384.      inv_desc            for special inventory descriptions
  1385.      desc_detail         parenthetical detail for object listing
  1386.      parse_rank          for differentiating like-named objects
  1387.      exclude_from_all    for interpreting "all" in inputs
  1388.      misc                for miscellaneous use
  1389.  
  1390. (For a detailed description of how each property is used, see
  1391. Appendix B:  The Library.)
  1392.  
  1393. Property names may again be aliased by
  1394.  
  1395.      property <property2> alias <property1>
  1396.  
  1397. where <property1> has already been defined.
  1398.  
  1399. The library aliases (among others) the following:
  1400.  
  1401.      nouns alias noun
  1402.      adjectives alias adjective
  1403.      prep alias preposition
  1404.      pronouns alias pronoun
  1405.  
  1406. A property is expressed as
  1407.  
  1408.      <object>.<property>
  1409.  
  1410. The number of elements to the property with more than a single value
  1411. can be found via
  1412.  
  1413.      <object>.#<property>
  1414.  
  1415. and a single element is expressed as
  1416.  
  1417.      <object>.<property> #<element number>
  1418.  
  1419. NOTE:  <object>.<property> is simply the shortened version of     
  1420. <object>.<property> #1.
  1421.  
  1422. To add some properties to the suitcase object, expand the object
  1423. definition to
  1424.  
  1425.      object suitcase "big green suitcase"
  1426.      {
  1427.           in emptyroom             ! done earlier
  1428.           is openable, not open    !
  1429.  
  1430.           nouns "suitcase", "case", "luggage"
  1431.           adjective "big", "green", "suit"
  1432.           article "a"
  1433.           size 25
  1434.           capacity 100
  1435.      }
  1436.  
  1437. Based on the engine rules for object identification, the suitcase
  1438. object may now be referred to by the player as "big green suitcase",
  1439. "big case", or "green suitcase" among other combinations.  Even "big
  1440. green" and "suit" may be valid, provided that these don't also refer
  1441. to other objects within valid scope such as "a big green apple" or
  1442. "your suit jacket".
  1443.  
  1444. (NOTE:  The basic form for identification by the parser is
  1445.  
  1446.      <adjective 1> <adj. 2> <adj. 3> <adj. 4> <noun>
  1447.  
  1448. where the maximum number of words is 5, and any subset of these
  1449. elements is allowable.  However, the noun must come last, and only
  1450. one noun is recognized, so that
  1451.  
  1452.      <noun> <noun>  and  <noun> <adjective>
  1453.  
  1454. as in 
  1455.  
  1456.      "luggage case" and "suitcase green"
  1457.  
  1458. are not recognized.)
  1459.  
  1460. One occasional source of befuddling code that doesn't behave the way
  1461. the programmer intended is not allowing enough slots for a property
  1462. on a given object.  That is, if an object is originally defined with
  1463. the property
  1464.  
  1465.      found_in kitchen
  1466.  
  1467. and later, the program tries to set
  1468.  
  1469.      <object>.found_in #2 = livingroom
  1470.  
  1471. it will have no substantial effect.  That is, there will be no space
  1472. initialized in <object>'s property table for a second value under
  1473. found_in.  Trying to read <object>.found_in #2 will return a value
  1474. of 0--a non-existent property--not the number of the livingroom
  1475. object.
  1476.  
  1477. To overcome this, if it is known that eventually a second (or third,
  1478. or fourth, or ninth) value is going to be set--even if only one
  1479. value is defined at the outset--use
  1480.  
  1481.      found_in kitchen, 0[, 0, 0,...]
  1482.  
  1483. in the object definition.
  1484.  
  1485. (A useful shortcut for initializing multiple zero values is to use
  1486.  
  1487.      found_in #4
  1488.  
  1489. instead of
  1490.  
  1491.      found_in 0, 0, 0, 0
  1492.  
  1493. in the object definition.)
  1494.  
  1495. As might be expected, combinations of properties are read left-to-
  1496. right, so that
  1497.  
  1498.      location.n_to.name
  1499.  
  1500. is understood as
  1501.  
  1502.      (location.n_to).name
  1503.  
  1504.  
  1505. -----------------------------------------------------------------
  1506. III.d.  CLASSES
  1507. -----------------------------------------------------------------
  1508.  
  1509. Classes are essentially objects that are specifically intended to be
  1510. used as prototypes for one or more similar objects.  Here is how a
  1511. class is defined:
  1512.  
  1513.      class <classname> ["<optional name>"]
  1514.      {
  1515.           ...
  1516.      }
  1517.  
  1518. with the body of the definition being the same as that for an object
  1519. definition, where the properties and attributes defined are to be
  1520. the same for all members of the class.
  1521.  
  1522. For example:
  1523.  
  1524.      class box
  1525.      {
  1526.           noun "box"
  1527.           long_desc
  1528.                "It looks like a regular old box."
  1529.           is openable, not open
  1530.      }
  1531.  
  1532.      box largebox "large box"
  1533.      {
  1534.           article "a"
  1535.           adjectives "big", "large"
  1536.           is open
  1537.      }
  1538.  
  1539.      box greenbox "green box"
  1540.      {
  1541.           article "a"
  1542.           adjective "green"
  1543.           long_desc
  1544.                "It looks like a regular old box, except green."
  1545.      }
  1546.  
  1547. (Beginning the long_desc property routine on the line below the
  1548. property name is understood by the compiler as:
  1549.  
  1550.      long_desc
  1551.      {
  1552.           "It looks..."
  1553.      }
  1554.  
  1555. Since the property is only one line--a single printing command--the
  1556. braces are unnecessary.)
  1557.  
  1558. The definition of an object in a class is begun with the name of the
  1559. prototype object instead of "object".  All properties and attributes
  1560. of the class are inherited (except for its position in the object
  1561. tree), unless they have been explicitly defined in the new object.
  1562.  
  1563. That is, although the box class is defined without the open
  1564. attribute, the largebox object will begin the game as open, since
  1565. this is in the largebox defition.  It will begin the game as
  1566. openable, as well, as this is inherited from the box class.
  1567.  
  1568. And while the largebox object will have the long_desc of the box
  1569. class, the greenbox object replaces the default property routine
  1570. with a new description.  (An exception to this is an $ADDITIVE
  1571. property, to be discussed later, where new properties are added to
  1572. those of previous classes.)
  1573.  
  1574. Since a class is basically an object, it is possible to define an
  1575. object using a previous object as a class even though the previous
  1576. object was not explicitly defined as a class.  Therefore,
  1577.  
  1578.      largebox largeredbox "large red box"
  1579.      {
  1580.           adjectives "big", "large", "red"
  1581.      }
  1582.  
  1583. is perfectly valid.
  1584.  
  1585. Occasionally, it may be necessary to have an object or class inherit
  1586. from more than one previously defined class.  This can be done using
  1587. the "inherits" instruction.
  1588.  
  1589.      <class1> <objectname> "name"
  1590.      {
  1591.           inherits <class2>[, <class3>,...]
  1592.           ...
  1593.      }
  1594.  
  1595. or even
  1596.  
  1597.      object <objectname> "name"
  1598.      {
  1599.           inherits <class1>, <class2>[, <class3>,...]
  1600.           ...
  1601.      }
  1602.  
  1603. The precedence of inheritance is in the order of occurrence.  In
  1604. either example, the object inherits first from <class1>, then from
  1605. <class2>, and so on.
  1606.  
  1607. The Hugo Object Library (OBJLIB.H) contains a number of useful class
  1608. definitions for things like rooms, characters, scenery, vehicles,
  1609. etc.  Sometimes, however, it may be desirable to use a different
  1610. definition for, say, the room class while keeping all the others in
  1611. the Object Library.
  1612.  
  1613. Instead of actually editing the OBJLIB.H file, use:
  1614.  
  1615.      replace <class> ["<optional name>"]
  1616.      {
  1617.           (...completely new object definition...)
  1618.      }
  1619.  
  1620. where <class> is the name of a previously defined object or class,
  1621. such as "room".  All subsequent references to <class> will use this
  1622. object instead of the previously defined one.  (Note that this means
  1623. that the replacement must come BEFORE any uses of the class for
  1624. other objects.)
  1625.  
  1626.  
  1627. -----------------------------------------------------------------
  1628. IV.  HUGO PROGRAMMING
  1629. -----------------------------------------------------------------
  1630.  
  1631. -----------------------------------------------------------------
  1632. IV.a.  VARIABLES
  1633. -----------------------------------------------------------------
  1634.  
  1635. Hugo supports two kinds of variables:  global and local.  Either
  1636. type simply holds a 16-bit integer, so a variable can hold a simple
  1637. value, an object number, a dictionary address, a routine address, or
  1638. any other standard Hugo data type through an assignment such as:
  1639.  
  1640.      a = 1
  1641.      nextobj = parent(obj)
  1642.      temp_word = "the"
  1643.      
  1644. Global variables are visible throughout the program.  They must be
  1645. defined similarly to properties and attributes as
  1646.  
  1647.      global <global variable name>[ = <starting value>]
  1648.  
  1649. Local variables, on the other hand, are recognized only within the
  1650. routine in which they are defined.  They are defined using
  1651.  
  1652.      local <local variable name>[ = <starting value>]
  1653.  
  1654. Global variables must of course have a unique name, different from
  1655. that of any other data object; local variables, on the other hand,
  1656. may share the names of local variables in other routines.
  1657.  
  1658. In either case, global or local, the default starting value is 0 if
  1659. no other value is given.  For example,
  1660.  
  1661.      global time_of_day = 1100
  1662.  
  1663. is equal to 1100 when the program is run, and is visible at any
  1664. point in the program, by any object or routine.  On the other hand,
  1665. the variables
  1666.  
  1667.      local a, max = 100, t
  1668.  
  1669. are visible only within the block of code where they are defined,
  1670. and are initialized to 0, 100, and 0, respectively, each time that
  1671. section of code (be it a routine, property routine, event, etc.) is
  1672. run.
  1673.  
  1674. The compiler defines a set of engine globals:  global variables that
  1675. are referenced directly by the engine, but which may otherwise be
  1676. treated like any other global variables.  These are:
  1677.  
  1678.      object         direct object of a verb action
  1679.      xobject        indirect object
  1680.      self           self-referential object
  1681.      words          total number of words in command
  1682.      player         the player object
  1683.      actor          the player, or character obj. (for scripts)
  1684.      verbroutine    specified by the command
  1685.      endflag        if not false (0), run EndGame routine
  1686.      prompt         for input; default is ">"
  1687.      objects        the total number of objects
  1688.      linelength     the maximum number of characters in a line
  1689.      pagelength     the maximum number of lines in the window
  1690.  
  1691. The object and xobject routines are set up by the engine depending
  1692. on what command is entered by the player.  The self global is
  1693. undefined except when an object is being referenced (as in a
  1694. property routine).  In that case, it is set to the number of that
  1695. object.  The player variable holds the number of the object that the
  1696. player is controlling; the verbroutine variable holds the address of
  1697. the routine specified in the grammar table and corresponding to the
  1698. entered command; the endflag variable must be 0 unless something has
  1699. occurred to end the game; and the prompt variable represents the
  1700. dictionary word appearing at the start of an input line.
  1701.  
  1702. The objects, linelength, and pagelength variables can be set by the
  1703. player, but to no useful effect.  The engine will reset them to the
  1704. "real" value whenever they are referenced.
  1705.  
  1706. (NOTE:  Setting endflag to a non-zero value forces an IMMEDIATE
  1707. break from the game loop.  Statements following the endflag
  1708. assignment even in the same function are not executed; control is
  1709. passed directly to the engine, which calls the EndGame routine.)
  1710.  
  1711.  
  1712. -----------------------------------------------------------------
  1713. IV.b.  CONSTANTS
  1714. -----------------------------------------------------------------
  1715.  
  1716. Constants are simply labels that represent a non-modifiable value.
  1717.  
  1718.      constant FIRST_NAME "John"
  1719.      constant LAST_NAME "Smith"
  1720.  
  1721.      print LAST_NAME; ", "; FIRST_NAME
  1722.  
  1723. outputs:
  1724.  
  1725.      Smith, John
  1726.  
  1727. Constants can, like any other Hugo data type, be integers,
  1728. dictionary entries, object numbers, etc.
  1729.  
  1730. (It is not absolutely necessary that a constant be given a definite
  1731. value if the constant is to be used as some sort of flag or marker,
  1732. etc.  Therefore,
  1733.  
  1734.      constant THIS_RESULT
  1735.      constant THAT_RESULT
  1736.  
  1737. will have unique values from each other, as well as from any other
  1738. constant defined without a definite value.)
  1739.  
  1740. Sometimes it may be useful to enumerate a series of constants in
  1741. sequence.  Instead of defining them all individually, it is possible
  1742. to use:
  1743.  
  1744.      enumerate start = 1
  1745.      {
  1746.           MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
  1747.      }
  1748.  
  1749. giving:
  1750.  
  1751.      MONDAY = 1, TUESDAY = 2, WEDNESDAY = 3, THURSDAY = 4,
  1752.      FRIDAY = 5
  1753.  
  1754. The start value is optional.  If omitted, it is 0.  Also, it is
  1755. possible to change the current value at any point (therefore also
  1756. affecting all following values).
  1757.  
  1758.      enumerate
  1759.      {
  1760.           A, B, C = 5, D, E
  1761.      }
  1762.  
  1763. gives:  A = 0, B = 1, C = 5, D = 6, E = 7.
  1764.  
  1765. Finally, it is possible to alter the step value of the enumeration
  1766. using the "step" keyword followed by "+x", "-x", "*x", or "/x",
  1767. where x is a constant integer value.  To count by twos:
  1768.  
  1769.      enumerate step *2
  1770.      {
  1771.           A = 1, B, C, D
  1772.      }
  1773.  
  1774. gives:  A = 1, B = 2, C = 4, D = 8.
  1775.  
  1776. NOTE:  Enumeration of global variables is also possible, using the
  1777. "global" specifier, as in:
  1778.  
  1779.      enumerate globals
  1780.      {
  1781.           <global1>, <global2>,...
  1782.      }
  1783.  
  1784. Otherwise the specifier "constants" is implied as the default.
  1785.  
  1786.  
  1787. -----------------------------------------------------------------
  1788. IV.c.  PRINTING TEXT
  1789. -----------------------------------------------------------------
  1790.  
  1791. Text can be printed using two different methods.  The first is the
  1792. basic PRINT command, the simplest form of which is
  1793.  
  1794.      print "<string>"
  1795.  
  1796. where <string> consists of a series of alphanumeric characters and
  1797. punctuation.
  1798.  
  1799. The backslash control character ("\") is handled specially.  It
  1800. modifies how the character following it in a string is treated.
  1801.  
  1802.      \"   inserts quotation marks
  1803.      \\   insert a literal backslash character
  1804.      \_   insert a forced space, overriding left-justification for
  1805.           the rest of the string
  1806.      \n   insert a newline
  1807.  
  1808. As usual, a single "\" at the end of a line signals that the line
  1809. continues with the following line.
  1810.  
  1811. Examples:
  1812.  
  1813.      print "\"Hello!\""
  1814.  
  1815.           "Hello!"
  1816.  
  1817.      print "Print a...\n...newline"
  1818.  
  1819.           Print a...
  1820.           ...newline
  1821.  
  1822.      print "One\\two\\three"
  1823.  
  1824.           One\two\three
  1825.  
  1826.      print "      Left-justified"
  1827.      print "\_    Not left-justified"
  1828.  
  1829.           Left-justified
  1830.                Not left-justified
  1831.  
  1832.      print "This is a \
  1833.             single line."
  1834.  
  1835.           This is a single line.
  1836.  
  1837. (Although
  1838.  
  1839.      print "This is a
  1840.           single line."
  1841.  
  1842. will produce the same result, since the line break occurs within
  1843. quotation marks.)
  1844.  
  1845. NOTE:  These control-character combinations are valid for printing
  1846. only; they are not treated as literals, as in, for example,
  1847. expressions involving dictionary entries.
  1848.  
  1849. After each of the above print commands, a newline is printed.  To
  1850. avoid this, append a semicolon (";") to the end of the print
  1851. statement.
  1852.  
  1853.      print "This is a ";
  1854.      print "single line."
  1855.  
  1856.           This is a single line.
  1857.  
  1858. Print statements may also contain data types, or a combination of
  1859. data types and strings.  The command
  1860.  
  1861.      print "The "; object.name; " is closed."
  1862.  
  1863. will print the word located at the dictionary address specified by
  1864. object.name, so that if object.name points to the word "box", the
  1865. resulting output would be:
  1866.  
  1867.      The box is closed.
  1868.  
  1869. To capitalize the first letter of the specified word, use the
  1870. CAPITAL modifier.
  1871.  
  1872.      print "The "; capital object.name; " is closed."
  1873.  
  1874.           The Box is closed.
  1875.  
  1876. To print the data type as a value instead of referencing the
  1877. dictionary, use the NUMBER modifier.  For example, if the variable
  1878. time_left holds the value 5,
  1879.  
  1880.      print "There are "; number time_left; " seconds remaining."
  1881.  
  1882.           There are 5 seconds remaining.
  1883.  
  1884. If NUMBER were not used, the engine would try to find a word at the
  1885. dictionary address 5, and the result will likely be garbage.
  1886.  
  1887. NOTE:  Mainly for debugging purposes, the modifier HEX prints the
  1888. data type as a hexadecimal number instead of a decimal one.  If the
  1889. variable val equals 127,
  1890.  
  1891.      print number val; " is "; hex val; " in hexadecimal."
  1892.  
  1893.           127 is 7F in hexadecimal.
  1894.  
  1895. The second way to print text is from the text bank, from which
  1896. sections are loaded from disk only when they are needed by the
  1897. program.  This method is provided so that lengthy blocks of
  1898. text--such as description and narration--do not take up valuable
  1899. space in memory.  The command consists simply of a quoted string
  1900. without any preceding statement.
  1901.  
  1902.      "This string would be written to disk."
  1903.  
  1904.           This string would be written to disk.
  1905.  
  1906. or
  1907.  
  1908.      "So would this one ";
  1909.      "and this one."
  1910.  
  1911.           So would this one and this one.
  1912.  
  1913. Notice that a semicolon at the end of the statement still overrides
  1914. the newline.  The in-string control-character combinations are still
  1915. usable with these print statements, but since each command is a
  1916. single line, data types and other modifiers may not be compounded. 
  1917. Because of that,
  1918.  
  1919.      "\"Hello,\" he said."
  1920.  
  1921. will write
  1922.  
  1923.      "Hello," he said.
  1924.  
  1925. to the .HEX file text bank, but
  1926.  
  1927.      "There are "; number time_left; " seconds remaining."
  1928.  
  1929. is illegal.
  1930.  
  1931. The color of text may be changed using the COLOR command (also
  1932. usable with the U.K. spelling "colour").  The format is
  1933.  
  1934.      color <foreground>[, <background>[, <input color>]]
  1935.  
  1936. where the background color is not necessary.  If no background color
  1937. is specified, the current one is assumed).
  1938.  
  1939. The input color is also not necessary--this refers to the color of
  1940. player input.
  1941.  
  1942. The standard color set with corresponding values and constant labels
  1943. is:
  1944.  
  1945.      COLOR          CONSTANT VALUE      LABEL
  1946.  
  1947.      Black               0              BLACK
  1948.      Blue                1              BLUE
  1949.      Green               2              GREEN
  1950.      Cyan                3              CYAN
  1951.      Red                 4              RED
  1952.      Magenta             5              MAGENTA
  1953.      Brown               6              BROWN
  1954.      White               7              WHITE
  1955.      Dark gray           8              DARK_GRAY
  1956.      Light blue          9              LIGHT_BLUE
  1957.      Light green         10             LIGHT_GREEN
  1958.      Light cyan          11             LIGHT_CYAN
  1959.      Light red           12             LIGHT_RED
  1960.      Light magenta       13             LIGHT_MAGENTA
  1961.      Yellow              14             YELLOW
  1962.      Bright white        15             BRIGHT_WHITE
  1963.  
  1964.      Default foreground  16             DEF_FOREGROUND
  1965.      Default background  17             DEF_BACKGROUND
  1966.  
  1967. (The labels are defined in HUGOLIB.H; when using the library, it is
  1968. never necessary to refer to a color by its numerical value.)
  1969.  
  1970. It is expected that, regardless of the system, any color will print
  1971. visibly on any other color.  However, it is suggested for
  1972. practicality that white (and less frequently bright while) be used
  1973. for most text-printing.
  1974.  
  1975. Magenta printing on a cyan background is accomplished by
  1976.  
  1977.      color MAGENTA, CYAN
  1978.  
  1979. or
  1980.  
  1981.      color 5, 3               ! if not using HUGOLIB.H
  1982.  
  1983. A current line can be filled--with blank spaces in the current
  1984. color--to a specified column (essentially a tab stop) using the
  1985. PRINT TO structure as follows:
  1986.  
  1987.      print "Time:"; to 40; "Date:"
  1988.  
  1989. where the value following TO does not exceed the maximum line length
  1990. in the engine global linelength.
  1991.  
  1992. The resulting output will be something like:
  1993.  
  1994.      Time:                              Date:
  1995.  
  1996. Text can be specifically located using the LOCATE command via
  1997.  
  1998.      locate <column>, <row>
  1999.  
  2000. where
  2001.  
  2002.      locate 1, 1
  2003.  
  2004. places text output at the top left corner of the screen.  Once
  2005. again, <column> must not exceed the linelength global.  The <row>
  2006. must not exceed the pagelength.
  2007.  
  2008.  
  2009. -----------------------------------------------------------------
  2010. IV.d.  MORE CONTROL CHARACTERS
  2011. -----------------------------------------------------------------
  2012.  
  2013. As listed above, the following are valid control characters that may
  2014. be embedded in printed strings:
  2015.  
  2016.      \"   quotation marks
  2017.      \\   a literal backslash character
  2018.      \_   a forced space, overriding left-justification for the rest
  2019.           of the string
  2020.      \n   a newline
  2021.  
  2022. The next set of control characters control the appearance of printed
  2023. text by turning on and off boldface, italic, proportional, and
  2024. underlined printing.  Not all computers and operating systems are
  2025. able to provide all types of printed output; however, the engine can
  2026. be relied upon to properly process any formatting--i.e.
  2027. proportionally printed text will still look fine even on a system
  2028. that has only a fixed-width font, such as MS-DOS (although, of
  2029. course, it won't be proportionally spaced).
  2030.  
  2031.      \B   boldface on
  2032.      \b   boldface off
  2033.      \I   italics on
  2034.      \i   italics off
  2035.      \P   proportional printing on
  2036.      \p   proportional printing off
  2037.      \U   underlining on
  2038.      \u   underlining off
  2039.  
  2040. (Print style can also be changed using the Font routine in
  2041. HUGOLIB.H.  Font-change constants can be combined as in:
  2042.  
  2043.      Font(BOLD_ON | ITALICS_ON | PROP_OFF)
  2044.  
  2045. where the valid constants are BOLD_ON, BOLD_OFF, ITALICS_ON,
  2046. ITALICS_OFF, UNDERLINE_ON, UNDERLINE_OFF, PROP_ON, and PROP_OFF.)
  2047.  
  2048. Special characters can also be printed via control characters.  Note
  2049. that these characters are contained in the extended ASCII character
  2050. set; if a particular system is incapable of displaying it, it will
  2051. display the normal-ASCII equivalent.  (The following examples,
  2052. appearing in parentheses, may not display properly on all computers
  2053. and printers.)
  2054.  
  2055.      \`        accent grave   followed by a, e, i, o, or u
  2056.                               e.g. "\`a" will print an 'a' with an
  2057.                               accent grave (…)
  2058.  
  2059.      \'        accent acute   followed by a, e, i, o, u, or E
  2060.                               e.g. "\'E" will print an 'E' with an
  2061.                               accent acute ()
  2062.  
  2063.      \~...     tilde          where '...' is an n or N
  2064.                               e.g. "\~n" will print an 'n' with a
  2065.                               tilde (¤)
  2066.  
  2067.      \^...     circumflex     where '...' is a, e, i, o, or u
  2068.                               e.g. "\^i" will print an 'i' with a
  2069.                               circumflex (Œ)
  2070.  
  2071.      \:        umlaut         followed by a, e, i, o, u, y, O, U
  2072.                               e.g.  "\:u" will print a 'u' with an
  2073.                               umlaut ()
  2074.  
  2075.      \,        cedilla        followed by c or C
  2076.                               e.g.  "\,c" will print a 'c' with a
  2077.                               cedilla (‡)
  2078.  
  2079.      \< or \>  Spanish quotation marks       (® ¯)
  2080.      \!        upside-down exclamation point (­)
  2081.      \?        upside-down question mark     (¨)
  2082.      \ae       ae ligature                   (‘)
  2083.      \AE       AE ligature                   (’)
  2084.      \c        cents symbol                  (›)
  2085.      \L        British pound                 (œ)
  2086.      \Y        Japanese Yen                  ()
  2087.      \-        em dash                       (Ä)
  2088.  
  2089.      \#xxx     any ASCII character where xxx represents the three-
  2090.                digit ASCII number of the character to be printed
  2091.                e.g. "\#065" will print an 'A' (ASCII 65)
  2092.  
  2093. NOTE:  Because non- or extended-ASCII character values may not be
  2094. the same on every system, it is recommended to always use
  2095. control-character combinations to print these characters instead of
  2096. typing them directly from the keyboard (on systems where this is
  2097. possible).
  2098.  
  2099.  
  2100. -----------------------------------------------------------------
  2101. EXAMPLE:  MIXING TEXT STYLES
  2102. -----------------------------------------------------------------
  2103.  
  2104.      ! Sample routine to print various typefaces and colors:
  2105.  
  2106.      #include "hugolib.h"
  2107.  
  2108.      routine PrintingSample
  2109.      {
  2110.           print "Text may be printed in \Bboldface\b,
  2111.                \Iitalics\i, \Uunderlined\u, or \Pproportional\p
  2112.                typefaces."
  2113.  
  2114.           color RED                ! or color 4
  2115.           print "\nGet ready.  ";
  2116.           color YELLOW             ! color 14
  2117.           print "Get set.  ";
  2118.           color GREEN              ! color 2
  2119.           print "Go!"
  2120.      }
  2121.  
  2122. The output will be:
  2123.  
  2124.      Text may be printed in boldface, italics, underlined, or
  2125.      proportional typefaces.
  2126.  
  2127.      Get ready.  Get set.  Go!
  2128.  
  2129. with "boldface", "italics", "underlined", and "proportional" printed
  2130. in their respective typefaces.  "Get ready", "Get set", and "Go!"
  2131. will all appear on the same line in three different colors.
  2132.  
  2133. Note that not all computers will be able to print all typefaces. 
  2134. The basic MS-DOS port, for example, uses color changes instead of
  2135. actual typeface changes, and does not support proportional printing.
  2136.  
  2137.  
  2138. -----------------------------------------------------------------
  2139. IV.e.  OPERATORS AND ASSIGNMENTS
  2140. -----------------------------------------------------------------
  2141.  
  2142. Hugo allows use of all standard math operators:
  2143.  
  2144.      +    addition
  2145.      -    subtraction
  2146.      *    multiplication
  2147.      /    integer division
  2148.  
  2149. Comparisions are also valid as operators, returning Boolean true or
  2150. false (1 or 0) so that
  2151.  
  2152.      2 + (x = 1)
  2153.      5 - (x > 1)
  2154.  
  2155. evaluate respectively to 3 and 5 if x is 1, and 2 and 4 if x is 2 or
  2156. greater.
  2157.  
  2158. Valid relational operators are
  2159.  
  2160.      =    equal to
  2161.      ~=   not equal to
  2162.      <    less than
  2163.      >    greater than
  2164.      <=   less than or equal to
  2165.      >=   greater than or equal to
  2166.  
  2167. Logical operators (AND, OR, and NOT) are also allowed.
  2168.  
  2169.      (x and y) or (a and b)
  2170.      (j + 5) and not ObjectisLight(k)
  2171.  
  2172. AND returns true if both values are non-zero.  OR returns true if
  2173. either is non-zero.  NOT returns true only if the following value is
  2174. zero.
  2175.  
  2176.      1 and 1 = 1
  2177.      1 and 0 = 0
  2178.      5 and 3 = 1
  2179.      0 and 9 = 0
  2180.      0 and 169 and 1 = 0
  2181.      1 and 12 and 1233 = 1
  2182.  
  2183.      1 or 1 = 1
  2184.      35 or 0 = 1
  2185.      0 or 0 = 0
  2186.  
  2187.      not 0 = 1
  2188.      not 1 = 0
  2189.      not 8 = 0
  2190.  
  2191.      1 and 7 or (14 and not 0) = 1
  2192.      (0 or not 1) and 3 = 0
  2193.  
  2194. Additionally, bitwise operators are provided:
  2195.  
  2196.      1 & 1 = 1      (Bitwise and)
  2197.      1 | 0 = 1      (Bitwise or)
  2198.      ~0 = -1        (Bitwise not/inverse)
  2199.  
  2200. (A detailed explanation of bitwise operations is a little beyond the
  2201. scope of this manual; programmers may occasionally use the "|"
  2202. operator to combine bitmask-type parameters for certain library
  2203. functions, but only advanced users should have to worry about
  2204. employing bitwise operators to any great extent in practical
  2205. programming.)
  2206.  
  2207. Any Hugo data type can appear in an expression, including routines,
  2208. attribute tests, properties, constants, and variables.  Standard
  2209. mathematical rules for order of significance in evaluating an
  2210. expression apply, so that parenthetical sub-expressions are
  2211. evaluated first, followed by multiplication and division, followed
  2212. by addition and subtraction.
  2213.  
  2214. Some sample combinations are:
  2215.  
  2216.      10 + object.size         ! numerical constant and property
  2217.      object is openable + 1   ! attribute test and constant
  2218.      FindLight(location) + a  ! routine return val. and variable
  2219.      1 and object is light    ! const., logical test, and attrib.
  2220.  
  2221. Expressions can be evaluated and assigned to either a variable or a
  2222. property.
  2223.  
  2224.      <variable> = <expression>
  2225.  
  2226.      <object>.<property> [#<element>] = <expression>
  2227.  
  2228. In certain cases, the compiler may allow a statement where the left-
  2229. hand side of the assignment is non-modifiable.  I.e.
  2230.  
  2231.      Function() = <expression>
  2232.  
  2233. or
  2234.  
  2235.      <object>.#<property> = <expression>
  2236.  
  2237. may be compiled, but such statements will force a run-time error
  2238. from the Hugo Engine.
  2239.  
  2240.  
  2241. -----------------------------------------------------------------
  2242. IV.f.  EFFICIENT OPERATORS
  2243. -----------------------------------------------------------------
  2244.  
  2245. Something like
  2246.  
  2247.      number_of_items = number_of_items + 1
  2248.      if number_of_items > 10
  2249.      {
  2250.           print "Too many items!"
  2251.      }
  2252.  
  2253. can be coded more simply as
  2254.  
  2255.      if ++number_of_items > 10
  2256.      {
  2257.           print "Too many items!"
  2258.      }
  2259.  
  2260. The "++" operator increases the following variable by one before
  2261. returning the value of the variable.  Similarly, "--" can precede a
  2262. variable to decrease the value by one before returning it.  Since
  2263. these operators act before the value is returned, they are called
  2264. "pre-increment" and "pre-decrement".
  2265.  
  2266. If "++" or "--" comes AFTER a variable, the value of the variable is
  2267. returned and then the value is increased or decreased, respectively. 
  2268. In these usages, the operators are called "post-increment" and
  2269. "post-decrement".
  2270.  
  2271. For example,
  2272.  
  2273.      while ++i < 5       ! pre-increment
  2274.      {
  2275.           print number i; " ";
  2276.      }
  2277.  
  2278. will output:
  2279.  
  2280.      1 2 3 4
  2281.  
  2282. But
  2283.  
  2284.      while i++ < 5       ! post-increment
  2285.      {
  2286.           print number i; " ";
  2287.      }
  2288.  
  2289. will output:
  2290.  
  2291.      1 2 3 4 5
  2292.  
  2293. Since in the second example, the variable is increased before
  2294. getting the value, while in the second example, it is increased
  2295. after checking it.
  2296.  
  2297. It is also possible to use the operators "+=", "-=", "*=", and "/=". 
  2298. These can also be used to modify a variable at the same time its
  2299. value is being checked.  All of these, however, operate before the
  2300. value in question is returned.
  2301.  
  2302.      x = 5
  2303.      y = 10
  2304.      print "x = "; number x*=y; ", y = "; number y
  2305.  
  2306. Result:
  2307.  
  2308.      x = 50, y = 10
  2309.  
  2310. When the compiler is processing any of the above lines, the
  2311. efficient operator takes precedence over a normal (i.e., single-
  2312. character) operator.
  2313.  
  2314. For example,
  2315.  
  2316.      x = y + ++z
  2317.  
  2318. is actually compiled as
  2319.  
  2320.      x = y++ + z
  2321.  
  2322. since the "++" is compiled first.  To properly code this line with
  2323. a pre-increment on the z variable instead of a post-increment on y:
  2324.  
  2325.      x = y + (++z)
  2326.  
  2327.  
  2328. -----------------------------------------------------------------
  2329. IV.g.  ARRAYS AND STRINGS
  2330. -----------------------------------------------------------------
  2331.  
  2332. Prior to this point, little has been said about arrays.  Arrays are
  2333. sets of values that share a common name, and where the elements are
  2334. referenced by number.  Arrays are defined by
  2335.  
  2336.      array <arrayname> [<array size>]
  2337.  
  2338. where <array size> must be a numerical constant.
  2339.  
  2340. An array definition reserves a block of memory of <array size> 16-
  2341. bit words, so that, for example,
  2342.  
  2343.      array test_array[10]
  2344.  
  2345. initializes 10 16-bit words (or 20 8-bit bytes) for the array.
  2346.  
  2347. Keep in mind that <array size> determines the size of the array, NOT
  2348. the maximum element number.  Elements begin counting at 0, so that
  2349. test_array, with 10 elements, has members numbered from 0 to 9. 
  2350. Trying to access test_array[10] or higher would return a meaningless
  2351. value.  (Trying to assign it by mistake would likely overwrite
  2352. something important, like the next-defined array.)
  2353.  
  2354. To prevent such out-of-bounds array reading/writing, an array's
  2355. length may be read via:
  2356.  
  2357.      array[]
  2358.  
  2359. where no element number is specified.  Using the above example,
  2360.  
  2361.      print test_array[]
  2362.  
  2363. would result in "10".
  2364.  
  2365. Array elements can be assigned more than one at a time, as in
  2366.  
  2367.      <arrayname> = <element1>, <element2>, ...
  2368.  
  2369. where <element1> and <element2> can be expressions or single values.
  2370.  
  2371. Elements need not be all of the same type, either, so that
  2372.  
  2373.      test_array[0] = (10 + 5) * x, "Hello!", FindLight(location)
  2374.  
  2375. is perfectly legal (although perhaps not perfectly useful).  More
  2376. common is a usage like
  2377.  
  2378.      names[0] = "Ned", "Sue", "Bob", "Maria"
  2379.  
  2380. or
  2381.  
  2382.      test_array[2] = 5, 4, 3, 2, 1
  2383.  
  2384. The array can then be accessed by
  2385.  
  2386.      print names[0]; " and "; names[3]
  2387.  
  2388.           Ned and Maria
  2389.  
  2390. or
  2391.  
  2392.      b = test_array[3] + test_array[5]
  2393.  
  2394. which would set the variable b to 4 + 2, or 6.
  2395.  
  2396. Because array space is statically allocated by the compiler, all
  2397. arrays must be declared at the global level.  Local arrays are
  2398. illegal, as are entire arrays passed as arguments.  However, single
  2399. elements of arrays are valid arguments.
  2400.  
  2401. Significantly, it is possible to pass an array address as an
  2402. argument, and the routine can then access the elements of the array
  2403. using the ARRAY modifier.  For example, if items is an array
  2404. containing:
  2405.  
  2406.      items[0] = "apples"
  2407.      items[1] = "oranges"
  2408.      items[2] = "socks"
  2409.  
  2410. The following:
  2411.  
  2412.      routine Test(v)
  2413.      {
  2414.           print array v[2]
  2415.      }
  2416.  
  2417. can be called using
  2418.  
  2419.      Test(items)
  2420.  
  2421. to produce the output "socks", even though v is an argument (i.e.
  2422. local variable), and not an array.  The line "print array v[2]"
  2423. tells the engine to treat v as an array address, not as a discrete
  2424. value.
  2425.  
  2426. Array strings are also possible, and Hugo provides a way to store a
  2427. dictionary entry in an array as a series of ASCII characters using
  2428. the STRING command:
  2429.  
  2430.      string(<array address>, <dictionary entry>, <max. length>)
  2431.  
  2432. (The <max. length> provision is required because the engine has no
  2433. way of checking for array boundaries.)
  2434.  
  2435. For example,
  2436.  
  2437.      string(a, word[1], 10)
  2438.  
  2439. will store up to 10 characters from word[1] into a.
  2440.  
  2441. NOTE:  It is expected in the preceding example that a would have at
  2442. least 11 elements, since STRING expects to store a terminating 0 or
  2443. null character after the string itself.
  2444.  
  2445. For example,
  2446.  
  2447.      x = string(a, word[1], 10)
  2448.  
  2449. will store up to 10 characters of word[1] in the array a, and return
  2450. the length of the stored string to the variable x.
  2451.  
  2452. (The token PARSE$ may be used in place of the dictionary entry
  2453. address;  see the section below on "Junction Routines:  ParseError"
  2454. for a description.)
  2455.  
  2456. The library defines the functions StringCopy, StringEqual,
  2457. StringLength, and StringPrint, which are extremely useful when
  2458. dealing with string arrays.
  2459.  
  2460. StringCopy copies one string array to another array.
  2461.  
  2462.      StringCopy(<new array>, <old array>[, <length>])
  2463.  
  2464. For example,
  2465.  
  2466.      StringCopy(a, b)
  2467.  
  2468. copies the contents of b to a, while
  2469.  
  2470.      StringCopy(a, b, 5)
  2471.  
  2472. copies only 5 characters of b to a.
  2473.  
  2474.      x = StringEqual(<string1>, <string2>)
  2475.      x = StringCompare(<string1>, <string2>)
  2476.  
  2477. StringEqual returns true only if the two specified string arrays are
  2478. identical.  StringCompare returns 1 if <string1> is lexically
  2479. greater than <string2>, -1 if <string1> is lexically less than
  2480. <string2>, and 0 if the two strings are identical.
  2481.  
  2482. StringLength returns the length of a string array, as in:
  2483.  
  2484.      len = StringLength(a)
  2485.  
  2486. and StringPrint prints a string array (or part of it).
  2487.  
  2488.      StringPrint(<array address>[, <start>, <end>)
  2489.  
  2490. For example, if a contains "presto",
  2491.  
  2492.      StringPrint(a)
  2493.  
  2494. will print "presto", but
  2495.  
  2496.      StringPrint(a, 1, 4)
  2497.  
  2498. will print "res".  (The <start> parameter in the first example
  2499. defaults to 0, not 1--the first numbered element in an array is 0.)
  2500.  
  2501. An interesting side-effect of being able to pass array addresses as
  2502. arguments is that it is possible to "cheat" the address, so that,
  2503. for example,
  2504.  
  2505.      StringCopy(a, b+2)
  2506.  
  2507. will copy b to a, beginning with the third letter of b (since the
  2508. first letter of b is b[0]).
  2509.  
  2510. It should also be kept in mind that string arrays and dictionary
  2511. entries are two entirely separate animals, and that comparing them
  2512. directly is using StringCompare is not possible.  That is, while a
  2513. dictionary entry is a simple value representing an address, a string
  2514. array is a series of values each representing a character in the
  2515. string.
  2516.  
  2517. The library provides the following to overcome this:
  2518.  
  2519.      StringDictCompare(<array>, <dict. entry>)
  2520.  
  2521. which returns the same values (1, -1, 0) as StringCompare, depending
  2522. on whether the string array is lexically greater than, less than, or
  2523. equal to the dictionary entry.
  2524.  
  2525. (There is a complement to the STRING command, the DICT function,
  2526. that dynamically creates a new dictionary entry at runtime.  Its
  2527. syntax is:
  2528.  
  2529.      x = dict(<array>, <maxlen>)
  2530.      x = dict(parse$, <maxlen>)
  2531.  
  2532. where the contents of <array> or parse$ are written into the
  2533. dictionary, to a maximum of <maxlen> characters, and the address of
  2534. the new word is returned.
  2535.  
  2536. However, since this requires extending the actual length of the game
  2537. file, it is necessary to provide for this during compilation. 
  2538. Inserting
  2539.  
  2540.      $MAXDICTEXTEND=<number>
  2541.  
  2542. at the start of the source file will write a buffer of <number>
  2543. empty bytes at the end of the dictionary.  (MAXDICTEXTEND is, by
  2544. default, 0.)
  2545.  
  2546. Dynamic dictionary extension is used primarily in situations where
  2547. the player may be able to, for example, name an object, then refer
  2548. to that object by the new name.  In this case, the new words will
  2549. have to exist in the dictionary, and must be written using DICT.
  2550.  
  2551. However, a guideline for programmers is that there should be a limit
  2552. to how many new words the player can cause to be created, so that
  2553. the total length of the new entries never exceeds <number>, keeping
  2554. in mind that the length of an entry is the number of characters plus
  2555. one (the byte representing the actual length).  That is, the word
  2556. "test" requires 5 bytes.)
  2557.  
  2558.  
  2559. -----------------------------------------------------------------
  2560. EXAMPLE:  MANAGING STRINGS
  2561. -----------------------------------------------------------------
  2562.  
  2563.      #include "hugolib.h"
  2564.  
  2565.      array s1[32]
  2566.      array s2[10]
  2567.      array s3[10]
  2568.  
  2569.      routine StringTests
  2570.      {
  2571.           local a, len
  2572.  
  2573.           a = "This is a sample string."
  2574.           len = string(s1, a, 31)
  2575.           string(s2, "Apple", 9)
  2576.           string(s3, "Tomato", 9)
  2577.  
  2578.           print "a = \""; a; "\""
  2579.           print "(Dictionary address:  "; number a; ")"
  2580.           print "s1 contains \""; StringPrint(s1); "\""
  2581.           print "(Array address:  "; number s1;
  2582.           print ", length = "; number len; ")"
  2583.           print "s2 is \""; StringPrint(s2);
  2584.           print "\", s3 is \""; StringPrint(s3); "\""
  2585.  
  2586.           "\nStringCompare(s1, s2) = ";
  2587.           print number StringCompare(s1, s2)
  2588.           "StringCompare(s1, s3) = ";
  2589.           print number StringCompare(s1, s3)
  2590.      }
  2591.  
  2592. The output will be:
  2593.  
  2594.      a = "This is a sample string."
  2595.      (Dictionary address = 887)
  2596.      s1 contains "This is a sample string."
  2597.      (Array address = 1625, length = 24)
  2598.      s2 is "Apple", s3 is "Tomato"
  2599.  
  2600.      StringCompare(s1, s2) = 1
  2601.      StringCompare(s1, s3) = -1
  2602.  
  2603. As is evident above, a dictionary entry does not need to be a single
  2604. word; any piece of text which must be treated as a value gets
  2605. entered into the dictionary table.
  2606.  
  2607. The argument 31 in the first call to the STRING function allows up
  2608. to 31 characters from a to be copied to s1, but since the length of
  2609. a is only 24 characters, only 25 values (including the terminating
  2610. 0) get copied, and the string length of s1 is returned in len.
  2611.  
  2612. Since "A(pple)" is lexically less than "T(his...)", comparing the
  2613. two returns -1.  As "To(mato)" is lexically greater than
  2614. "Th(is...)", StringCompare returns 1.
  2615.  
  2616.  
  2617. -----------------------------------------------------------------
  2618. IV.h.  CONDITIONAL EXPRESSIONS AND PROGRAM FLOW
  2619. -----------------------------------------------------------------
  2620.  
  2621. Program flow can be controlled using a variety of constructions,
  2622. each of which is built around an expression that evaluates to false
  2623. (zero) or non-false (non-zero).
  2624.  
  2625. The most basic of these is the IF statement.
  2626.  
  2627.      if <expression>
  2628.           {...conditional code block...}
  2629.  
  2630. NOTE:  The enclosing braces are not necessary if the code block is
  2631. a single line.  Note also that the conditional block may begin (and
  2632. even end) on the same line as the IF statement provided that braces
  2633. are used.
  2634.  
  2635.      if <expression>
  2636.           ...single line...
  2637.  
  2638.      if <expression> {...conditional code block...}
  2639.  
  2640. If braces are not used for a single line, the compiler automatically
  2641. inserts them, although special care must be taken when constructing
  2642. a block of code nesting several single-line conditionals.
  2643.  
  2644. While
  2645.  
  2646.      if <expression1>
  2647.           if <expression2>
  2648.                ...conditional code block...
  2649.  
  2650. may be properly interpreted,
  2651.  
  2652.      if <expression1>
  2653.           for (...<expression2>...)
  2654.                if <expression3>
  2655.                     ...conditional code block...
  2656.  
  2657. will not be.  The compiler will misunderstand the end of the FOR
  2658. loop construction because the enclosing conditional code block
  2659. expects to end with the FOR expression.  In turn the FOR expression
  2660. does not properly differentiate the end of the conditional loop. 
  2661. The result would likely be a stack overflow error in the engine
  2662. because the engine will continually nest the execution of recursive
  2663. FOR loops until it runs out of stack space.
  2664.  
  2665. The proper way to structure that same section of code would be:
  2666.  
  2667.      if <expression1>
  2668.      {
  2669.           for (...<expression2>...)
  2670.           {
  2671.                if <expression3>
  2672.                     ...conditional code block...
  2673.           }
  2674.      }
  2675.  
  2676. NOTE:  The best advice is to rely on braces to clarify code
  2677. structure whenever using such complex constructions.  This applies
  2678. particularly to mixing IF, FOR, WHILE, and DO-WHILE expressions,
  2679. especially when recursive function calls are involved.  While the
  2680. results may appear as intended, the method to produce them is
  2681. incorrect, and any long-running such construction is almost
  2682. guaranteed to crash the stack.
  2683.  
  2684. More elaborate uses of IF involve the use of ELSEIF and ELSE.
  2685.  
  2686.      if <expression1>
  2687.           ...first conditional code block...
  2688.      elseif <expression2>
  2689.           ...second conditional code block...
  2690.      elseif <expression3>
  2691.           ...third conditional code block...
  2692.      ...
  2693.      else
  2694.           ...default code block...
  2695.  
  2696. In this case, the engine evaluates each expression until it finds
  2697. one that is true, and then executes it.  Control then passes to the
  2698. next non-if/elseif/else statement following the conditional
  2699. construction.  If no true expression is found, the default code
  2700. block is executed.  If, for example, <expression1> evaluates to a
  2701. non-false value, then none of the following expressions are tested.
  2702.  
  2703. Of course, all three (IF, ELSEIF, and ELSE) need not be used every
  2704. time, and simple IF-ELSEIF and IF-ELSE combinations are perfectly
  2705. valid.
  2706.  
  2707. In certain cases, the IF statement may not lend itself perfectly to
  2708. clarity, and the SELECT-CASE construction may be more appropriate. 
  2709. The general form is:
  2710.  
  2711.      select <variable>
  2712.           case <value1>[, <value2>, ...]
  2713.                ...first conditional code block...
  2714.           case <value3>[, <value4>, ...]
  2715.                ...second conditional code block...
  2716.           ...
  2717.           case else
  2718.                ..default code block...
  2719.  
  2720. In this case, the engine quickly performs an evaluation that is
  2721. essentially
  2722.  
  2723.      if <variable> = <value1> [or <variable> = <value2> ...]
  2724.  
  2725. There is no limit on the number of values (separated by commas) that
  2726. can appear on a line following CASE.  The same rules for bracing
  2727. multiple-line code blocks apply as with IF (as well as for every
  2728. other type of conditional block).
  2729.  
  2730. NOTE:  Cases do not "fall through" to the following case.  Think of
  2731. cases following the first as being ELSEIF statements rather than IF
  2732. statements; once a true case has been found, subsequent cases are
  2733. ignored.  (This is, in fact, the way the compiler codes them, and
  2734. indeed how they will appear using runtime tracing.)
  2735.  
  2736. Basic loops may be coded using WHILE and DO-WHILE.
  2737.  
  2738.      while <expression>
  2739.           ...conditional code block...
  2740.  
  2741.      do
  2742.           ...conditional code block...
  2743.      while <expression>
  2744.  
  2745. Each of these executes the conditional code block as long as
  2746. <expression> holds true.  It is assumed that the code block somehow
  2747. alters expression so that at some point it will become false;
  2748. otherwise the loop will execute endlessly.
  2749.  
  2750.      while x <= 10
  2751.           x = x + 1
  2752.  
  2753.      do
  2754.           {x = x + 1
  2755.           print "x is "; number x}
  2756.      while x <= 10
  2757.  
  2758. The only difference between the two is that if <expression> is false
  2759. at the outset, the WHILE code block will never run.  The DO-WHILE
  2760. code block will run at least once even if <expression> is false at
  2761. the outset.
  2762.  
  2763. The most complex loop construction uses the FOR statement.
  2764.  
  2765.      for (<assignment>; <expression>; <modifier>)
  2766.           ...conditional code block...
  2767.  
  2768. For example:
  2769.  
  2770.      for (i=1; i<=15; i=i+1)
  2771.           print "i is "; number i
  2772.  
  2773. First, the engine executes the assignment setting i = 1.  Then, it
  2774. executes the print statement.  Next, it checks to see if the
  2775. expression holds true (if i is less than or equal to 15).  If it
  2776. does, it executes the print statement and the modifying assignment
  2777. that increments i.  It continues the loop until the expression tests
  2778. false.
  2779.  
  2780. Not all elements of the FOR construction are necessary.  For
  2781. example, the assignment may be omitted, as in
  2782.  
  2783.      for (; i<=15; i=i+1)
  2784.  
  2785. and the engine will simply use the existing value of i.
  2786.  
  2787. With
  2788.  
  2789.      for (i=1;;i=i+1)
  2790.  
  2791. The loop will execute endlessly, unless some other means of exit is
  2792. provided.
  2793.  
  2794. The modifying expression does not have to be an expression.  It may
  2795. be a routine that modifies a global variable, for example, which is
  2796. then tested by the FOR loop.
  2797.  
  2798. (A second form of the FOR loop is:
  2799.  
  2800.      for <var> in <object>
  2801.           ...conditional code block...
  2802.  
  2803. which loops through all the children of <object> (if any), setting
  2804. the variable <var> to the object number of each child in sequence,
  2805. so that
  2806.  
  2807.      for i in suitcase
  2808.           print i.name
  2809.  
  2810. will print the names of each object in the suitcase object.)
  2811.      
  2812. The easiest way to picture the first form of a Hugo FOR loop is that
  2813.  
  2814.      for (<assignment>; <expression>; <modifier>)
  2815.           ...conditional code block...
  2816.  
  2817. translates to the equivalent of
  2818.  
  2819.      <assignment>
  2820.      [while] <expression>
  2821.      {
  2822.           ...conditional code block...
  2823.           <modifier>
  2824.      }
  2825.  
  2826. which in turn translates the equivalent of
  2827.  
  2828.      <assignment>
  2829.      :<label1>
  2830.      [if] <expression>
  2831.      {
  2832.           ...conditional code block...
  2833.           <modifier>
  2834.           jump <label1>
  2835.      }
  2836.  
  2837. (On the other hand, that isn't a particularly easy way to picture
  2838. anything, and, in its awkwardness, perhaps justifies the existence
  2839. of non-threatening WHILE, DO-WHILE, and FOR loops).     
  2840.  
  2841. The benefit in knowing how a Hugo loop breaks down into a slip knot
  2842. of IFs and JUMPs is that it is easier to monitor program flow using
  2843. the Hudo Debugger (see Appendix E).
  2844.  
  2845. As is now obvious by the above (possibly confusing) illustration,
  2846. Hugo supports JUMP commands and labels.  A label is simply a user-
  2847. specified token preceded by a colon (":") at the beginning of a
  2848. line.  The label name must be a unique token in the program.
  2849.  
  2850. Use caution with JUMP, particularly when looping back to the same
  2851. conditional statment over and over again.  Each time an IF, SELECT-
  2852. CASE, WHILE, DO-WHILE, or FOR statement executes, Hugo pushes data
  2853. onto the stack; recklessly doing this over and over again will
  2854. topple the stack and crash the engine.
  2855.  
  2856. In general, it may be best to try if at all possible to avoid using
  2857. JUMP whenever possible.
  2858.  
  2859. It is also important to recognize--particularly with SELECT and
  2860. WHILE or DO-WHILE statements--that the expression is tested each
  2861. time the loop executes, or, in the case of a SELECT statement, for
  2862. each corresponding case.  The significance of this is seen in the
  2863. following example
  2864.  
  2865.      select test.prop_routine
  2866.           case 1
  2867.                {...}
  2868.           case 2
  2869.                {...}
  2870.           case 3
  2871.                {...}
  2872.  
  2873. where prop_routine returns a value from 1 to 3.  The property
  2874. routine will be executed 3 separate times, once for each CASE
  2875. statement.  If prop_routine has some other effect, such as modifying
  2876. a global variable or printing output, then this will also occur 3
  2877. times.
  2878.  
  2879. If such an effect would be undesirable, try
  2880.  
  2881.      local test_val                ! set up a local variable
  2882.      test_val = test.prop_routine  ! and assign it
  2883.      select test_val
  2884.           case 1
  2885.                {...}
  2886.           ...
  2887.  
  2888. so that test.prop_routine is called only once.
  2889.  
  2890. A similar case would be where
  2891.  
  2892.      select random(3)
  2893.           case 1:  {...}
  2894.           case 2:  {...}
  2895.           case 3:  {...}
  2896.  
  2897. would result in something akin to:
  2898.  
  2899.      if random(3) = 1:      {...}
  2900.      elseif random(3) = 2:  {...}
  2901.      elseif random(3) = 3:  {...}
  2902.  
  2903. In other words, a different random value would be evaluated each
  2904. time.  A better choice would be:
  2905.  
  2906.      local b
  2907.      b = random(3)
  2908.      select b
  2909.           case 1:  {...}
  2910.           ...
  2911.  
  2912. One final keyword is important in program flow, and that is BREAK. 
  2913. At any point during a loop, it may be necessary to exit immediately
  2914. (and probably prematurely).  BREAK passes control to the statement
  2915. immediately following the current loop.
  2916.  
  2917. In the example
  2918.  
  2919.      do
  2920.      {
  2921.           while <expression2>
  2922.           {
  2923.                ...
  2924.                if <expression3>
  2925.                     break
  2926.                ...
  2927.           }
  2928.           ...
  2929.      }
  2930.      while <expression1>
  2931.  
  2932. the BREAK causes the immediately running WHILE <expression2> loop to
  2933. terminate, even if <expression2> is true.  However, the external DO-
  2934. WHILE <expression3> loop continues to run.
  2935.  
  2936. It has been previously stated that lines ending in "and" or "or" are
  2937. continued onto the next line in the case of long conditional
  2938. expressions.  A second useful provision is the ability to use a
  2939. comma to separate options within a conditional expression.  As a
  2940. result,
  2941.  
  2942.      if word[1] = "one", "two", "three"
  2943.      while object is open, not locked
  2944.      if a ~= 1, 2, 3
  2945.  
  2946. are translated into
  2947.  
  2948.      if word[1] = "one" or word[1] = "two" or word[1] = "three"
  2949.      while object is open and object is not locked
  2950.      if suitcase not in livingroom, garage
  2951.      if a ~= 1 and a ~= 1 and a ~= 3
  2952.  
  2953. respectively.
  2954.  
  2955. Note that with an "=" or "in" comparison, a comma results in an "or"
  2956. comparison.  With "~=" or an attribute comparison, the result is an
  2957. "and" comparison.
  2958.  
  2959.  
  2960.  
  2961. -----------------------------------------------------------------
  2962. V.  ROUTINES AND EVENTS
  2963. -----------------------------------------------------------------
  2964.  
  2965. -----------------------------------------------------------------
  2966. V.a.  ROUTINES
  2967. -----------------------------------------------------------------
  2968.  
  2969. Routines are blocks of code that may be called at any point in a
  2970. program.  A routine may or may not return a value, and it may or may
  2971. not require a list of parameters (or arguments).  (A number of
  2972. routines have occurred in previous examples, but here is the formal
  2973. explication.)
  2974.  
  2975. A routine is defined as
  2976.  
  2977.      routine <routinename> [(<argument1>, <argument2>, ...)]
  2978.      {
  2979.           ...
  2980.      }
  2981.  
  2982. once again ensuring the the opening brace ("{") comes on a new line
  2983. following the "routine" specifier.
  2984.  
  2985. (NOTE:  To substitute a new routine for an existing one with the
  2986. same name (such as in a library file), define the new one using
  2987. REPLACE instead of ROUTINE.
  2988.  
  2989.      replace <routinename> [(<argument1>, <argument2>, ...)]
  2990.  
  2991. For example,
  2992.  
  2993.      routine TestRoutine(obj)
  2994.      {
  2995.           print "The "; obj.name; " has a size of ";
  2996.           print obj.size; "."
  2997.           return obj.size
  2998.      }
  2999.  
  3000. takes a single value as an argument, assigns it to a local variable
  3001. obj, executes a simple printing sequence, and returns the property
  3002. value:  obj.size.  The RETURN keyword exits the current routine, and
  3003. returns a value if specified.
  3004.  
  3005. Both
  3006.  
  3007.      return
  3008.  
  3009. and
  3010.  
  3011.      return <expression>
  3012.  
  3013. are valid.  If no expression is given, the routine returns 0.  If no
  3014. RETURN statement at all is encountered, the routine continues until
  3015. the closing brace ("}"), then returns 0.
  3016.  
  3017. TestRoutine can be called several ways:
  3018.  
  3019.      TestRoutine(suitcase)
  3020.  
  3021. will (assuming the suitcase object as been defined as previously
  3022. illustrated) print
  3023.  
  3024.      "The big green suitcase has a size of 25."
  3025.  
  3026. The return value will be ignored.  On the other hand,
  3027.  
  3028.      x = TestRoutine(suitcase)
  3029.  
  3030. will print the same output, but will assign the return value of
  3031. TestRoutine to the variable x.
  3032.  
  3033. Now, unlike C and similar languages, Hugo does not require that
  3034. routines follow a strict prototype.  Therefore, both
  3035.  
  3036.      TestRoutine
  3037.  
  3038. and
  3039.  
  3040.      TestRoutine(suitcase, 5)
  3041.  
  3042. are valid calls for the above routine.
  3043.  
  3044. In the first case, the argument obj defaults to 0, since no value is
  3045. passed.  The parentheses are not necessary if no arguments are
  3046. passed.  In the second case, the value 5 is passed to TestRoutine,
  3047. but ignored.
  3048.  
  3049. Arguments are always passed by value, not by reference or address. 
  3050. A local variable in one routine can never be altered by another
  3051. routine.  What this means is that, for example, in the following
  3052. routines:
  3053.  
  3054.      routine TestRoutine
  3055.      {
  3056.           local a
  3057.  
  3058.           a = 5
  3059.           Double(a)
  3060.           print number a
  3061.      }
  3062.  
  3063.      routine Double(a)
  3064.      {
  3065.           a = a * 2
  3066.      }
  3067.  
  3068. Calling TestRoutine would print "5" and not "10" because the local
  3069. variable a in Double is only a copy of the variable passed to it as
  3070. an argument.
  3071.  
  3072. These two routines would, on the other hand, print "10":
  3073.  
  3074.      routine TestRoutine
  3075.      {
  3076.           local a
  3077.  
  3078.           a = 5
  3079.           a = Double(a)
  3080.           print number a
  3081.      }
  3082.  
  3083.      routine Double(a)
  3084.      {
  3085.           return a * 2
  3086.      }
  3087.  
  3088. The local a in TestRoutine is reassigned with the return value from
  3089. Double.
  3090.  
  3091. An interesting side-effect of a null (0) return value can be seen
  3092. using the PRINT command.  Consider the The routine in HUGOLIB.H,
  3093. which prints an object's definite article (i.e. "the", if
  3094. appropriate), followed by the object's name property.
  3095.  
  3096.      print "You open "; The(object); "."
  3097.  
  3098. might result in
  3099.  
  3100.      You open the suitcase.
  3101.  
  3102. Note that the above PRINT command itself really only prints
  3103.  
  3104.      "You open "
  3105.  
  3106. and
  3107.  
  3108.      "."
  3109.  
  3110. It is the The routine that prints
  3111.  
  3112.      the suitcase
  3113.  
  3114. Since The returns 0 (the null string, or ""), the PRINT command is
  3115. actually displaying
  3116.  
  3117.      "You open ", "", and "."
  3118.  
  3119. where the null string ("") is preceded on the output line by The's
  3120. printing of "the " and the object name.
  3121.  
  3122.  
  3123. ----------------------------------------------------------------
  3124. V.b.  PROPERTY ROUTINES
  3125. ----------------------------------------------------------------
  3126.  
  3127. Property routines are slightly more complex than those described so
  3128. far, but follow the same basic rules.  Normally, a property routine
  3129. runs when the program attempts to get the value of a property that
  3130. contains a routine.
  3131.  
  3132. That is, instead of
  3133.  
  3134.      size 10
  3135.  
  3136. an object may contain the property
  3137.  
  3138.      size
  3139.      {
  3140.           return x + 5
  3141.      }
  3142.  
  3143. Trying to read object.size in either case will return an integer
  3144. value.
  3145.  
  3146. Here's another example.  Normally, if <object> is the current room,
  3147. then <object>.n_to would contain the object number of the room to
  3148. the north.  The library checks <object>.n_to to see if a value
  3149. exists for it; if none does, the move is invalid.
  3150.  
  3151. Consider this:
  3152.  
  3153.      n_to office
  3154.  
  3155. and
  3156.  
  3157.      n_to
  3158.           {"The office door is locked."}
  3159.  
  3160. or
  3161.  
  3162.      n_to
  3163.      {
  3164.           "The office door is locked.  ";
  3165.           return false
  3166.      }
  3167.  
  3168. In the first case, an attempt on the part of the player to move
  3169. north would result in parent(player) being changed to the office
  3170. object.  In the second case, a custom invalid-move message would be
  3171. displayed.  In the third case, the custom invalid-move message would
  3172. be displayed, but then the library would continue as if it had not
  3173. found a n_to property for <object>, and it would print the standard
  3174. invalid-move message (without a newline, thanks to the semicolon):
  3175.  
  3176.      "The office door is locked.  You can't go that way."
  3177.  
  3178. NOTE:  While normal routines return false (or 0) by default,
  3179. property routines return true (or 1) by default.
  3180.  
  3181. (For those wondering why the true return value in the second case
  3182. doesn't prompt a move to object number 1, the library DoGo routine
  3183. assumes that there will never be a room object numbered one.)
  3184.  
  3185. Property routines may be run directly using the RUN command:
  3186.  
  3187.      run <object>.<property>
  3188.  
  3189. If <object> does not have <property>, or if <object>.<property> is
  3190. not a routine, nothing happens.  Otherwise, the property routine
  3191. executes.  Property routines do not take arguments.
  3192.  
  3193. Remember that at any point in a program, an existing property may be
  3194. changed using
  3195.  
  3196.      <object>.<property> = <value>
  3197.  
  3198. A property routine may be changed using
  3199.  
  3200.      <object>.<property> =
  3201.      {
  3202.           ...
  3203.      }
  3204.  
  3205. where the new routine must be enclosed in braces.
  3206.  
  3207. It is entirely possible to change what was once a property routine
  3208. into a simple value, or vice-versa, providing that space for the
  3209. routine (and the required number of elements) was allowed for in the
  3210. original object definition.  Even if a property routine is to be
  3211. assigned later in the program, the property itself must still be
  3212. defined at the outset.  A simple
  3213.  
  3214.      <property> 0
  3215.  
  3216. or
  3217.  
  3218.      <property> {return false}
  3219.  
  3220. will suffice.
  3221.  
  3222. There is, however, one drawback to this re-assignment of property
  3223. values to routines and vice-versa.  A property routine is given a
  3224. "length" of one 16-bit word, which is the property address.  When
  3225. assigning a value or set of values to a property routine, the engine
  3226. behaves as if the property was originally defined for this object
  3227. with only one word of data, since it has no way of knowing the
  3228. original length of the property data.
  3229.  
  3230. For example, if the original property specification in the object
  3231. definition was:
  3232.  
  3233.      found_in bedroom, livingroom, garage
  3234.  
  3235. and at some point the following was executed:
  3236.  
  3237.      found_in = {return basement}
  3238.  
  3239. then the following would not subsequently work:
  3240.  
  3241.      found_in #3 = attic
  3242.  
  3243. because the engine now believes <object>.found_in to have only one
  3244. 16-bit word of data attached to it.
  3245.  
  3246. Finally, keep in mind that whenever calling a property routine, the
  3247. global variable self is normally set to the object number.  To avoid
  3248. this, such as when "borrowing" a property from another object from
  3249. within a different object, reference the property via
  3250.  
  3251.      <object>..<property>
  3252.  
  3253. using ".." instead of the normal property operator.
  3254.  
  3255.  
  3256. -----------------------------------------------------------------
  3257. EXAMPLE:  "BORROWING" PROPERTY ROUTINES
  3258. -----------------------------------------------------------------
  3259.  
  3260. Consider a situation where a class provides a particular property
  3261. routine.  Normally, that routine is inherited by all objects defined
  3262. using that class.  But there may arise a situation where one of
  3263. those objects must have a variation or expansion on the original
  3264. routine.
  3265.  
  3266.      class food
  3267.      {
  3268.           bites_left 5
  3269.           eating
  3270.           {
  3271.                self.bites_left = self.bites_left - 1
  3272.                if self.bites_left = 0
  3273.                     remove self         ! all gone
  3274.           }
  3275.      }
  3276.  
  3277.      food health_food
  3278.      {
  3279.           eating
  3280.           {
  3281.                actor.health = actor.health + 1
  3282.                run food..eating
  3283.           }
  3284.      }
  3285.  
  3286. (Assuming that bites_left, eating, and health are defined as
  3287. properties, with eating being called whenever a food object is
  3288. eaten.)
  3289.  
  3290. In this case, it would be inconvenient to have to retype the entire
  3291. food.eating routine for the health_food object just because the
  3292. latter must also increase actor.health.  Using ".." calls
  3293. food.eating with self set to health_food, not the food class, so
  3294. that food.eating affects health_food.
  3295.  
  3296.  
  3297. -----------------------------------------------------------------
  3298. V.c.  BEFORE AND AFTER ROUTINES
  3299. -----------------------------------------------------------------
  3300.  
  3301. The Hugo Compiler predefines two special properties:  before and
  3302. after.  They are unique in that not only are they always routines,
  3303. but they are much more complex (and versatile) than a standard
  3304. property routine.
  3305.  
  3306. Complex properties like before and after are defined with
  3307.  
  3308.      property <property name> $complex <default value>
  3309.  
  3310. as in:
  3311.  
  3312.      property before $complex
  3313.      property after  $complex
  3314.  
  3315. Here is the syntax for the before property:
  3316.  
  3317.      before
  3318.      {
  3319.           <usage1> <verbroutine1>[, <verbroutine2>,...]
  3320.           {
  3321.                ...
  3322.           }
  3323.           <usage2> <verbroutine3>[, <verbroutine4>,...]
  3324.           {
  3325.                ...
  3326.           }
  3327.           ...
  3328.      }
  3329.  
  3330. (The after property is the same, substituting "after" for "before".)
  3331.  
  3332. The <usage> specifier is a value against which the specified object
  3333. is matched.  Most commonly, it is "object", "xobject", "location",
  3334. "actor", "parent(object)", etc.  The <verbroutine> is the name of a
  3335. verb routine to which the usage in question applies.
  3336.  
  3337. If <object>.before is checked, with the global verbroutine set to
  3338. one of the specified verbroutines in the before property, and 
  3339. <usage> in that instance is "object", then the following block of
  3340. code is executed.  If no match is found, <object>.before returns
  3341. false.
  3342.  
  3343. Here is a clearer example using the suitcase object we have been
  3344. developing:
  3345.  
  3346.      before
  3347.      {
  3348.           object DoEat
  3349.           {
  3350.                "You can't eat the suitcase!"
  3351.           }
  3352.      }
  3353.  
  3354.      after
  3355.      {
  3356.           object DoGet
  3357.           {
  3358.                "With a vigorous effort, you pick up the suitcase."
  3359.           }
  3360.           xobject DoPutIn
  3361.           {
  3362.                "You put ";
  3363.                The(object)
  3364.                " into the suitcase."
  3365.           }
  3366.      }
  3367.  
  3368. Each of these examples will return true, thereby overriding the
  3369. engine's default operation (see the section on "The Game Loop").  In
  3370. order to fool the engine into continuing normally, as if no before
  3371. or after property has been found, return false from the property
  3372. routine.
  3373.  
  3374.      after
  3375.      {
  3376.           object DoGet
  3377.                {"Fine.  ";
  3378.                return false}
  3379.      }
  3380.  
  3381. will result in:
  3382.  
  3383.      >get suitcase
  3384.      Fine.  Taken.
  3385.  
  3386. Since the after routine returns false, and the library's default
  3387. response for a successful call to DoGet is "Taken."
  3388.  
  3389. It is important to remember that, unlike other property routines,
  3390. before and after routines are additive; i.e. a before (or after)
  3391. routine defined in an inherited class or object is not overwritten
  3392. by a new property routine in the new object.  Instead, the
  3393. definition for the routine is--in essence--added onto.  An additive
  3394. property is defined using the $ADDITIVE qualifier, as in:
  3395.  
  3396.      property <property name> $additive <default value>
  3397.  
  3398. All previously inherited before/after subroutines are carried over. 
  3399. However, the processing of a before/after property begins with the
  3400. present object, progressing backward through the object's ancestry
  3401. until a usage/verb-routine match is found; once a match is made, no
  3402. further preceding class inheritances are processed (unless the
  3403. property routine in question returns false).
  3404.  
  3405. NOTE:  To force a before or after property routine to apply to ANY
  3406. verbroutine, do not specify a verbroutine.  (This has changed from
  3407. Hugo v2.1 and earlier, where it was necessary to specify the Parse
  3408. routine in place of a verbroutine.)
  3409.  
  3410. For example,
  3411.  
  3412.      before
  3413.      {
  3414.           xobject
  3415.           {
  3416.                ...
  3417.           }
  3418.      }
  3419.  
  3420. The specified routine will be run whenever the object in question is
  3421. the xobject of ANY valid input.
  3422.  
  3423. If this non-specific block occurs before any block(s) specifying
  3424. verbroutines, then the following blocks, if matched, will run as
  3425. well so long as the block does not return true.  If the non-specific
  3426. block comes after any other blocks, then it will run only if no
  3427. other object/verbroutine combination is matched.
  3428.  
  3429. A drawback of this non-specification is that all verbroutines are
  3430. matched--both verbs and xverbs.  This can be particularly
  3431. undesirable in the case of location before/after properties, where
  3432. a non-specific response will be triggered even for "save",
  3433. "restore", etc.
  3434.  
  3435. To get around this, the library provides a function AnyVerb, which
  3436. takes an object as its argument and returns that object number if
  3437. the current verbroutine is not within the group of xverbs; otherwise
  3438. it returns false.  Therefore, it can be used via:
  3439.  
  3440.      before
  3441.      {
  3442.           AnyVerb(location)
  3443.           {
  3444.                ...
  3445.           }
  3446.      }
  3447.  
  3448. instead of
  3449.  
  3450.      before
  3451.      {
  3452.           location
  3453.           {
  3454.                ...
  3455.           }
  3456.      }
  3457.  
  3458. The former will execute the conditional block of code whenever the
  3459. location global matches the current object and the current
  3460. verbroutine is not an xverb.  The latter (without using AnyVerb),
  3461. will run for verbs and xverbs.  (The reason for this, simply put, is
  3462. that the location global always equals the location global(!).  But
  3463. AnyVerb(location) will only equal the location global if the
  3464. verbroutine is not an xverb.)
  3465.  
  3466.  
  3467. -----------------------------------------------------------------
  3468. EXAMPLE:  BUILDING A COMPLEX OBJECT
  3469. -----------------------------------------------------------------
  3470.  
  3471. At this point, enough material has been covered to develop a
  3472. comprehensive example of a functional object that will serve as a
  3473. summary of concepts introduced so far, as well as providing
  3474. instances of a number of common properties from HUGOLIB.H.
  3475.  
  3476.      object woodcabinet "wooden cabinet"
  3477.      {
  3478.           in emptyroom
  3479.           article "a"
  3480.           nouns "cabinet", "shelf", "shelves", "furniture", \
  3481.                "doors", "door"
  3482.           adjectives "wooden", "wood", "fine", "mahogany"
  3483.  
  3484.           short_desc
  3485.                "A wooden cabinet sits along one wall."
  3486.           when_open
  3487.                "An open wooden cabinet sits along one wall."
  3488.           long_desc
  3489.           {
  3490.                "The cabinet is made of fine mahogany wood,
  3491.                hand-crafted by a master cabinetmaker.  In front
  3492.                are two doors (presently ";
  3493.                if self is open
  3494.                     print "open";
  3495.                else:  print "closed";
  3496.                print ")."
  3497.           }
  3498.           contains_desc
  3499.                "Behind the open doors of the cabinet you
  3500.                can see";      ! note the semicolon--no line feed
  3501.  
  3502.           key_object cabinetkey    ! a cabinetkey object must
  3503.                                    ! also be created
  3504.  
  3505.           holding 0                ! starts off empty
  3506.           capacity 100
  3507.  
  3508.           before
  3509.           {
  3510.                object DoLookUnder
  3511.                     {"Nothing there but dust."}
  3512.                object DoGet
  3513.                     {"The cabinet is far too heavy to lift!"}
  3514.           }
  3515.           after
  3516.           {
  3517.                object DoLock
  3518.                     {"With a twist of the key, you lock the
  3519.                          cabinet up tight."}
  3520.           }
  3521.  
  3522.           is container, openable, not open, lockable, static
  3523.      }
  3524.  
  3525. And for a challenge:  how could the cabinet be converted into, say,
  3526. a secret passage into another room?
  3527.  
  3528. ANSWER:
  3529.  
  3530. Add a door_to property, such as:
  3531.  
  3532.           door_to secondroom  ! a new room object
  3533.  
  3534. The cabinet can now be entered via:  "go cabinet", "get into
  3535. cabinet", "enter cabinet", etc.
  3536.  
  3537.  
  3538. -----------------------------------------------------------------
  3539. V.d.  INIT AND MAIN
  3540. -----------------------------------------------------------------
  3541.  
  3542. At least two routines are typically part of every Hugo problem: 
  3543. INIT and MAIN.  (The latter is required.  The compiler will issue an
  3544. error if no Main routine exists.)
  3545.  
  3546. INIT, if it exists, is called once at the start of the program (as
  3547. well as during a RESTART command).  The routine should configure all
  3548. variables, objects, and arrays needed to begin the game.
  3549.  
  3550. MAIN is called every turn.  It should take care of general game
  3551. management such as moving ahead the counter, as well as running
  3552. events and scripts.
  3553.  
  3554.  
  3555. -----------------------------------------------------------------
  3556. V.e.  EVENTS
  3557. -----------------------------------------------------------------
  3558.  
  3559. Events are useful for bringing a game to life, so that little
  3560. quirks, behaviors, and occurrences can be provided for with little
  3561. difficulty.
  3562.  
  3563. Events are also routines, but their special characteristic is that
  3564. they may be attached to a particular object, and they are run as a
  3565. group by the RUNEVENTS command.
  3566.  
  3567. Events are defined as
  3568.  
  3569.      event
  3570.      {
  3571.           ...
  3572.      }
  3573.  
  3574. for global events, and
  3575.  
  3576.      event [in] <object>
  3577.      {
  3578.           ...
  3579.      }
  3580.  
  3581. for events attached to a particular object.  (The "in" is optional,
  3582. but may be useful for legibility.)  If an event is attached to an
  3583. object, it is run only when that object has the same grandparent as
  3584. the player object (where grandparent refers to the last object
  3585. before 0, the nothing object).
  3586.  
  3587. NOTE:  If the event is not a global event, the self global is set to
  3588. the number of the object to which the event is attached.
  3589.  
  3590.  
  3591. -----------------------------------------------------------------
  3592. EXAMPLE:  BUILDING A CLOCK EVENT
  3593. -----------------------------------------------------------------
  3594.  
  3595. Suppose that there is a clock object in a room.  Here is a possible
  3596. routine:
  3597.  
  3598.      event clock
  3599.      {
  3600.           local minutes, hours
  3601.  
  3602.           hours = counter / 60
  3603.           minutes = counter - (hours * 60)
  3604.  
  3605.           if minutes = 0
  3606.           {
  3607.                print "The clock chimes ";
  3608.                select hour
  3609.                     case 1:  print "one";
  3610.                     case 2:  print "two";
  3611.                     case 3:  print "three";
  3612.                     .
  3613.                     .
  3614.                     .
  3615.                     case 12:  print "twelve";
  3616.                print " o'clock."
  3617.           }
  3618.      }
  3619.  
  3620. Whenever the player and the clock are in the same room (when a
  3621. RUNEVENTS command is given), the event will run.
  3622.  
  3623. Now, suppose the clock should be audible throughout the entire
  3624. house--i.e. at any point in the game map.  Simply changing the event
  3625. definition to
  3626.  
  3627.      event                    ! no object is given
  3628.      {
  3629.           ...
  3630.      }
  3631.  
  3632. will make the event a global one.
  3633.  
  3634.  
  3635.  
  3636. -----------------------------------------------------------------
  3637. VI.  FUSES, DAEMONS, AND SCRIPTS
  3638. -----------------------------------------------------------------
  3639.  
  3640. While all of the above mentioned elements of Hugo are programmed
  3641. into the internal code of the engine, the means of running fuses,
  3642. daemons, and scripts are written entirely in Hugo itself and
  3643. contained in the library (HUGOLIB.H).
  3644.  
  3645.  
  3646. -----------------------------------------------------------------
  3647. VI.a.  FUSES AND DAEMONS
  3648. -----------------------------------------------------------------
  3649.  
  3650. A daemon is the traditional name for a recurring activity.  Hugo
  3651. handles daemons as special events attached to objects that may be
  3652. activated or deactivated (i.e. moved in and out of the scope of
  3653. RUNEVENTS).
  3654.  
  3655. Since the daemon class is defined in the library, define a daemon
  3656. itself using
  3657.  
  3658.      daemon <name>
  3659.      {}
  3660.  
  3661. The body of the daemon definition is empty.  It is only needed to
  3662. attach the daemon event to, so the daemon definition must be
  3663. followed by
  3664.  
  3665.      event <name>
  3666.      {
  3667.           ...
  3668.      }
  3669.  
  3670. Activate it by
  3671.  
  3672.      Activate(<name>)
  3673.  
  3674. which moves the specified daemon object into scope of the player. 
  3675. This way, whenever a RUNEVENTS command is given (as it should be in
  3676. the Main routine), the event attached to <name> will run.
  3677.  
  3678. Deactivate the daemon using
  3679.  
  3680.      Deactivate(<name>)
  3681.  
  3682. which removes the daemon object from scope.
  3683.  
  3684. It can be seen here that a daemon is actually a special type of
  3685. object which is moved in and out of the scope of RUNEVENTS, and that
  3686. it is the event attached to the daemon that actually contains the
  3687. code.
  3688.  
  3689. A fuse is the traditional name for a timer--i.e. any event set to
  3690. happen after a certain period of time.  The fuse itself is a
  3691. slightly more complex version of a daemon object, containing two
  3692. additional properties as well as in_scope:
  3693.  
  3694.      timer     - the number of turns before the fuse event runs
  3695.      tick      - a routine that decrements timer and returns the 
  3696.                number of turns remaining (i.e. the value of timer)
  3697.  
  3698. Similarly to a daemon, define a fuse in two steps
  3699.  
  3700.      fuse <name>
  3701.      {}
  3702.  
  3703.      event <name>
  3704.      {
  3705.           ...
  3706.           if not self.tick
  3707.           {
  3708.                ...
  3709.           }
  3710.      }
  3711.  
  3712. and turn it on or off by
  3713.  
  3714.      Activate(<name>, <setting>)
  3715.  
  3716. or
  3717.  
  3718.      Deactivate(<name>)
  3719.  
  3720. where <setting> is the initial value of the timer property.
  3721.  
  3722. Note that it is up to the event itself to run the timer and check
  3723. for its expiration.  The line
  3724.  
  3725.      if not self.tick
  3726.  
  3727. runs the tick property--which decrements the timer--and executes the
  3728. following conditional block if self.timer is 0.
  3729.  
  3730.  
  3731. -----------------------------------------------------------------
  3732. EXAMPLE:  A SIMPLE DAEMON AND SIMPLER FUSE
  3733. -----------------------------------------------------------------
  3734.  
  3735. The most basic daemon would be something like a sleep counter, which
  3736. measures how far a player can go beginning from a certain rested
  3737. state.
  3738.  
  3739. Assume that the player's amount of rest is kept in a property called
  3740. rest, which decreases by 2 each turn.
  3741.  
  3742.      daemon gettired
  3743.      {}
  3744.  
  3745.      event gettired
  3746.      {
  3747.           player.rest = player.rest - 2
  3748.           if player.rest < 0
  3749.                player.rest = 0
  3750.  
  3751.           select player.rest
  3752.                case 20
  3753.                     "You're getting quite tired."
  3754.                case 10
  3755.                     "You're getting \Ivery\i tired."
  3756.                case 0
  3757.                     "You fall asleep!"
  3758.      }
  3759.  
  3760. Start and stop the daemon with Activate(gettired) and
  3761. Deactivate(gettired).
  3762.  
  3763. Now, as for a fuse, why not construct the most obvious example: 
  3764. that of a ticking bomb?  (Assume that there exists another physical
  3765. bomb object; tickingbomb is only the countdown fuse.)
  3766.  
  3767.      fuse tickingbomb
  3768.      {}
  3769.  
  3770.      event tickingbomb
  3771.      {
  3772.           if not self.tick
  3773.           {
  3774.                if Contains(location, bomb)
  3775.                     "You vanish in a nifty KABOOM!"
  3776.                else
  3777.                     "You hear a distant KABOOM!"
  3778.                remove bomb
  3779.           }
  3780.      }
  3781.  
  3782. Start it (with a countdown of 25 turns) and stop it with
  3783. Activate(tickingbomb, 25) and Deactivate(tickingbomb).
  3784.  
  3785.  
  3786. -----------------------------------------------------------------
  3787. VI.b.  SCRIPTS
  3788. -----------------------------------------------------------------
  3789.  
  3790. Scripts are considerably more complex than fuses and daemons.  The
  3791. purpose of a script (also called a character script) is to allow an
  3792. object--usually a character--to follow a sequence of actions turn-
  3793. by-turn, independent of the player.
  3794.  
  3795. Up to 16 scripts may be running at once.  It is up the the
  3796. programmer not to overflow this limit.
  3797.  
  3798. A script is represented by two arrays:  SCRIPTDATA and SETSCRIPT. 
  3799. The latter was named for programming clarity than for what it
  3800. actually contains.  Here's why:
  3801.  
  3802. To define a script, use the following notation:
  3803.  
  3804.      setscript[Script(<object>, <number>)] = &CharRoutine, obj,
  3805.                                              &CharRoutine, obj,
  3806.                                              ...
  3807.  
  3808. (remembering that a hanging comma at the end of a line of code is a
  3809. signal to the compiler that the line continues onto the next
  3810. unbroken.)
  3811.  
  3812. Notice that SETSCRIPT is actually an array, taking its starting
  3813. element from the return value of the SCRIPT routine, which has
  3814. <object> and <number> as its arguments.
  3815.  
  3816. SCRIPT returns a pointer within the large SETSCRIPT array where the
  3817. <number> steps of a script for <object> may reside.  A single script
  3818. may have up to 32 steps.  A step in a script consists of a routine
  3819. and an object--both are required, even if the routine does not
  3820. require an object.  (Use the nothing object (0); see the CharWait
  3821. routine in HUGOLIB.H for reference.)
  3822.  
  3823. The custom in HUGOLIB.H is that character script routines use the
  3824. prefix "Char" although this is not required.  Currently, routines
  3825. provided include:
  3826.  
  3827.      CharMove       (requiring a direction object)
  3828.      CharWait       (using the nothing object)
  3829.      CharGet        (requiring a takeable object)
  3830.      CharDrop       (requiring an object held by the character)
  3831.  
  3832. as well as the special routine
  3833.  
  3834.      LoopScript     (using the nothing object)
  3835.  
  3836. which indicates that a script will continually execute.  (It is the
  3837. responsibility of the programmer to ensure that the ending position
  3838. of the character or object is suitable to loop back to the beginning
  3839. if LoopScript is used.  That is, if the script consists of a complex
  3840. series of directions, the character should always return to the same
  3841. starting point.)
  3842.  
  3843. The sequence of routines and objects for each script is stored in
  3844. the SETSCRIPT array.
  3845.  
  3846. Scripts are run using the RunScripts routine, similar to RUNEVENTS,
  3847. the only difference being that RUNEVENTS is an engine command while
  3848. RunScripts is contained entirely in HUGOLIB.H.
  3849.  
  3850. The line
  3851.  
  3852.      RunScripts
  3853.  
  3854. will run all active object/character scripts, one turn at a time,
  3855. freeing the space used by each once it has run its course.
  3856.  
  3857. Here is a sample script for a character named "Ned":
  3858.  
  3859.      setscript[Script(ned, 4)] =   &CharMove, s_obj,
  3860.                                    &CharGet, cannonball,
  3861.                                    &CharMove, n_obj,
  3862.                                    &CharDrop, cannonball
  3863.  
  3864. Ned will go south, retrieve the cannonball object, and bring it
  3865. north again.  (The character script routines provided in the library
  3866. are relatively basic; for example, CharGet assumes that the
  3867. specified object will be there when the character comes to get
  3868. it.) 
  3869.  
  3870. Other script-management routines in HUGOLIB.H include:
  3871.  
  3872.      CancelScript(obj)   to immediately halt execution of the
  3873.                          script for <obj>
  3874.  
  3875.      PauseScript(obj)    to temporarily pause execution of the
  3876.                          script for <obj>
  3877.  
  3878.      ResumeScript(obj)   to resume execution of a paused script
  3879.  
  3880.      SkipScript(obj)     skips the script for <obj> during the next
  3881.                          call to RunScripts only
  3882.  
  3883. The RunScripts routine also checks for before and after properties. 
  3884. It continues with the default action--i.e. the character action
  3885. routine specified in the script--if it finds a false value.
  3886.  
  3887. To override a default character action routine, include a before
  3888. property for the character object using the following form:
  3889.  
  3890.      before
  3891.      {
  3892.           actor CharRoutine
  3893.           {
  3894.                ...
  3895.           }
  3896.      }
  3897.  
  3898. where CharRoutine is CharWait, CharMove, CharGet, CharDrop, etc.
  3899.  
  3900.  
  3901.  
  3902. -----------------------------------------------------------------
  3903. VI.c.  A NOTE ABOUT THE event_flag GLOBAL:
  3904. -----------------------------------------------------------------
  3905.  
  3906. The library routines--particularly the DoWait... verb
  3907. routines--expect the event_flag global variable to be set to a non-
  3908. false value if something happens (i.e. in an event or script) so
  3909. that the player may be notified and given the opportunity to quit
  3910. waiting.  For instance, the character script routines in HUGOLIB.H
  3911. set event_flag whenever a character does something in the same
  3912. location as the player.
  3913.  
  3914. If HUGOLIB.H is to be used, the convention of setting event_flag
  3915. after every significant event should be adhered to.
  3916.  
  3917.  
  3918.  
  3919. -----------------------------------------------------------------
  3920. VII.  GRAMMAR AND PARSING 
  3921. -----------------------------------------------------------------
  3922.  
  3923. -----------------------------------------------------------------
  3924. VII.a.  GRAMMAR DEFINITION
  3925. -----------------------------------------------------------------
  3926.  
  3927. Every valid player command must specified.  More precisely, each
  3928. usage of a particular verb must be detailed in full by the source
  3929. code.
  3930.  
  3931. Grammar definitions must ALWAYS come at the start of a program,
  3932. preceding any objects or executable code.  That is, if several
  3933. additional grammar files are to be included, or new grammar is to be
  3934. explicitly defined in the source code, it must be done before any
  3935. files containing executable code are included, or any routines,
  3936. objects, etc. are defined.
  3937.  
  3938. The syntax used is:
  3939.  
  3940.      [x]verb "<verb1>" [, "<verb2>", "<verb3>",...]
  3941.      * <syntax specification 1>              <VerbRoutine1>
  3942.      * <syntax specification 2>              <VerbRoutine2>
  3943.      ...
  3944.  
  3945. Now, what does that mean?  Here are some examples from the library
  3946. grammar file GRAMMAR.G:
  3947.  
  3948. verb "get"
  3949.      *                                             DoVague
  3950.      * "up"/"out"/"off"                           DoExit
  3951.      * "outof"/"offof"/"off" object               DoExit
  3952.      * "in"/"on" object                           DoEnter
  3953.      * multinotheld "from"/"off" parent           DoGet
  3954.      * multinotheld "offof"/"outof" parent        DoGet
  3955.      * multinotheld                               DoGet
  3956.  
  3957. verb "take"
  3958.      *                                            DoVague
  3959.      * "off" multiheld                            DoTakeOff
  3960.      * multiheld "off"                            DoTakeOff
  3961.      * multinotheld                               DoGet
  3962.      * multinotheld "from"/"off" parent           DoGet
  3963.      * multinotheld "offof"/"outof" parent        DoGet
  3964.  
  3965. xverb "save"
  3966.      *                                             DoSave
  3967.      * "game"                                      DoSave
  3968.  
  3969. verb "read", "peruse"
  3970.      *                                             DoVague
  3971.      * readable                                    DoRead
  3972.  
  3973. verb "unlock"
  3974.      *                                             DoVague
  3975.      * lockable                                    DoUnLock
  3976.      * lockable "with" held                        DoUnLock
  3977.  
  3978. Each VERB or XVERB header begins a new verb definition.  An XVERB is
  3979. a special signifier that indicates that the engine should not call
  3980. the MAIN routine after successful completion of the action.  XVERB
  3981. is typically used with non-action, housekeeping-type verbs such as
  3982. saving, restoring, quitting, and restarting.
  3983.  
  3984. Next in the header comes one or more verb words.  Each of the
  3985. specified words will share the following verb grammar EXACTLY.  This
  3986. is why "get" and "take" in the above examples are defined
  3987. separately, instead of as
  3988.  
  3989.      verb "get", "take"
  3990.  
  3991. In this way, the commands
  3992.  
  3993.      get up
  3994.  
  3995. and
  3996.  
  3997.      take off hat
  3998.  
  3999. are allowable, while
  4000.  
  4001.      take up
  4002.  
  4003. and
  4004.  
  4005.      get off hat
  4006.  
  4007. won't make any sense.
  4008.  
  4009. Each line beginning with an asterisk ("*") is a separate valid usage
  4010. of the verb being defined.  (Every player input line must begin with
  4011. a verb.  Exceptions, where a command is directed to an object as in
  4012.  
  4013.      Ned, get the ball
  4014.  
  4015. will be dealt with later.)
  4016.  
  4017. Up to two objects and any number of dictionary words may make up a
  4018. syntax line.  The objects must be separated by at least one
  4019. dictionary word.
  4020.  
  4021. Valid object specifications are:
  4022.  
  4023.      object         any visible object (the direct object)
  4024.      xobject        the indirect object
  4025.      <attribute>    any visible object that is <attribute>
  4026.      parent         an xobject that is the parent of the object
  4027.      held           any object possessed by the player object
  4028.      notheld        an object explicitly not held
  4029.      anything       any object, held or not, visible or not
  4030.      multi          multiple visible objects
  4031.      multiheld      multiple held objects
  4032.      multinotheld   multiple notheld objects
  4033.      number         a positive integer number
  4034.      word           any dictionary word
  4035.      string         a quoted string
  4036.      (RoutineName)  a routine name, in parentheses
  4037.      (objectname)   a single object name, in parentheses
  4038.  
  4039. (If a number is specified in the grammar syntax, it will be passed
  4040. to the verbroutine in the object global.  If a string is specified,
  4041. it will be passed in the engine's parse$ variable, which can then be
  4042. turned into a string array using the STRING function.)
  4043.  
  4044. Dictionary words that may be used interchangeably are separated by
  4045. a slash ("/").
  4046.  
  4047. Two or more dictionary words in sequence must be specified
  4048. separately.  That is, in the input line:
  4049.  
  4050.      take hat out of suitcase
  4051.  
  4052. the syntax line
  4053.  
  4054.      * object "out" "of" container
  4055.  
  4056. will be matched, while
  4057.  
  4058.      * object "out of" container
  4059.  
  4060. would never be recognized, since the engine will automatically parse
  4061. "out" and "of" as two separate words; the parser will never find a
  4062. match for "out of".
  4063.  
  4064. Regarding object specification within the syntax line:  Once the
  4065. direct object has been found, the remaining object in the input line
  4066. will be stored as the xobject.  That is, in the example immediately
  4067. above, a valid object in the input line with the attribute container
  4068. will be treated as the indirect object by the verb routine.
  4069.  
  4070. NOTE:  An important point to remember when mixing dictionary words
  4071. and objects within a syntax line is that, unless directed
  4072. differently, the parser may confuse a word-object combination with
  4073. an invalid object name.  Consider the following:
  4074.  
  4075.      verb "pick"
  4076.           * object                 DoGet
  4077.           * "up" object            DoGet
  4078.  
  4079. This definition will result in something like
  4080.  
  4081.      >pick up box
  4082.      You haven't seen any "up box", nor are you likely to in the
  4083.      near future even if such a thing exists.
  4084.  
  4085. (assuming that "up" has been defined elsewhere as part of a
  4086. different object name, as in OBJLIB.H), because the processor
  4087. processes the syntax
  4088.  
  4089.      * object
  4090.  
  4091. and determines that an invalid object name is being used; it never
  4092. gets to 
  4093.  
  4094.      * "up" object
  4095.  
  4096. The proper verb definition would be ordered like
  4097.  
  4098.      verb "pick"
  4099.           * "up" object            DoGet
  4100.           * object                 DoGet
  4101.  
  4102. so that both "pick <object>" and "pick up <object>" are valid player
  4103. commands.
  4104.  
  4105. To define a new grammar condition that will take precedence over an
  4106. existing one--such as in GRAMMAR.G--simply define the new condition
  4107. first (i.e. before including GRAMMAR.G).
  4108.  
  4109. A single object may be specified as the only valid object for a
  4110. particular syntax:
  4111.  
  4112.      verb "rub"
  4113.           * (magic_lamp)           DoRubMagicLamp
  4114.  
  4115. will produce a "You can't do that with..." error for any object
  4116. other than the magic_lamp object.
  4117.  
  4118. Using a routine name to specify an object is slightly tricky:  the
  4119. engine calls the given routine with the object specified in the
  4120. input line as its argument; if the routine returns true, the object
  4121. is valid--if not, a parsing error is expected to have been printed
  4122. by the routine.
  4123.  
  4124.  
  4125. -----------------------------------------------------------------
  4126. VII.b.  THE PARSER
  4127. -----------------------------------------------------------------
  4128.  
  4129. Immediately after an input line is received, the engine calls the
  4130. parser, and the first step taken is to identify any invalid words,
  4131. i.e. words that are not in the dictionary table.
  4132.  
  4133. NOTE:  One non-dictionary word or phrase is allowed in an input
  4134. line, providing it is enclosed in quotation marks ("").  If the
  4135. command is successfully parsed and matched, this string is passed to
  4136. parse$.  More than one non-dictionary word or phrase (even if the
  4137. additional phrases are enclosed in quotes) are not allowed.
  4138.  
  4139. The next step is to break the line down into individual words. 
  4140. Words are separated by spaces and basic punctuation (including "!"
  4141. and "?") which are removed.  All characters in an input line are
  4142. converted to lower case.
  4143.  
  4144. The next step is to process the three types of special words which
  4145. may be defined in the source code.
  4146.  
  4147. REMOVALS are the simplest.  These are simply words that are to be
  4148. automatically removed from any input line, and are basically limited
  4149. to words such as "a" and "the" which would, generally speaking, only
  4150. make grammar matching more complicated and difficult.
  4151.  
  4152. The syntax for defining a removal is:
  4153.  
  4154.      removal "<word1>"[, "<word2>", "word<3>",...]
  4155.  
  4156. as in
  4157.  
  4158.      removal "a", "an", "the"
  4159.  
  4160. SYNONYMS are slightly more complex.  These are words that will never
  4161. be found in the parsed input line; they are replaced by the
  4162. specified word for which they are a synonym.
  4163.  
  4164.      synonym "<synonym>" for "<word>"
  4165.  
  4166. as in
  4167.  
  4168.      synonym "myself" for "me"
  4169.  
  4170. The above example will replace every occurrence of "myself" in the
  4171. input line with "me".  Usage of synonyms will likely not be
  4172. extensive, since of course it is possible to, particularly in the
  4173. case of object nouns and adjectives specify synonymous words which
  4174. are still treated as distinct.
  4175.  
  4176. COMPOUNDS are the final type of special word, specified as:
  4177.  
  4178.      compound "<word1>", "<word2>"
  4179.  
  4180. as in
  4181.  
  4182.      compound "out", "of"
  4183.  
  4184. so that the input line
  4185.  
  4186.      get hat out of suitcase
  4187.  
  4188. would be parsed to
  4189.  
  4190.      get hat outof suitcase
  4191.  
  4192. Depending on the design of grammar tables for certain syntaxes, the
  4193. use of compounds may make grammar definition more straightforward,
  4194. so that by using the above compound, 
  4195.  
  4196.      verb "get"
  4197.      * multinotheld "outof"/"offof"/"from" parent
  4198.  
  4199. is possible, and likely more desirable to
  4200.  
  4201.      verb "get"
  4202.      * multinotheld "out"/"off" "of" parent
  4203.      * multinotheld "from" parent
  4204.  
  4205. When the parser has finished processing the input line, the result
  4206. is a specially defined (by the Hugo Engine) array called word, where
  4207. the number of valid elements is held in the global variable words.
  4208.  
  4209. Therefore, in
  4210.  
  4211.      get the hat from the table
  4212.  
  4213. the parser--using the removals defined in HUGOLIB.H--will produce
  4214. the following results:
  4215.  
  4216.      word[1] = "get"
  4217.      word[2] = "hat"
  4218.      word[3] = "from"
  4219.      word[4] = "table"
  4220.  
  4221.      words = 4
  4222.  
  4223. NOTE:  Multiple-command input lines are also allowed, provided that
  4224. the individual commands are separated by a period (".").
  4225.  
  4226.      get hat.  go n.  go e.
  4227.  
  4228. would become
  4229.  
  4230.      word[1] = "get"
  4231.      word[2] = "hat"
  4232.      word[3] = ""
  4233.      word[4] = "go"
  4234.      word[5] = "n"
  4235.      word[6] = ""
  4236.      word[7] = "go"
  4237.      word[8] = "e"
  4238.      word[9] = ""
  4239.  
  4240.      words = 9
  4241.  
  4242. (See the Parse routine in HUGOLIB.H for an example of how
  4243.  
  4244.      get hat then go n
  4245.  
  4246. is translated into:
  4247.  
  4248.      word[1] = "get"
  4249.      word[2] = "hat"
  4250.      word[3] = ""
  4251.      word[4] = "go"
  4252.      word[5] = "n")
  4253.  
  4254. A maximum of thirty-two words is allowed.  The period is in each
  4255. case converted to the null dictionary entry ("", address = 0), which
  4256. is a signal to the engine that processing of the current command
  4257. should end here.
  4258.  
  4259. NOTE:  The parsing and grammar routines also recognize several
  4260. system words, each in the format "~word".  These are:
  4261.  
  4262.      ~and      referring to:  multiple specific objects
  4263.      ~all          "     "    multiple objects in general
  4264.      ~any          "     "    any one of a list of objects
  4265.      ~except       "     "    an excluded object
  4266.      ~oops     to correct an error in the previous input line
  4267.  
  4268. To allow an input line to access any of these system words, a
  4269. synonym must be defined, such as
  4270.  
  4271.      synonym "and" for "~and"
  4272.  
  4273. The library defines several such synonyms.
  4274.  
  4275.  
  4276.  
  4277. -----------------------------------------------------------------
  4278. VIII.  JUNCTION ROUTINES
  4279. -----------------------------------------------------------------
  4280.  
  4281. Because, simply put, the engine is unaware of such things as
  4282. attributes, properties, and objects in anything but a technical
  4283. sense, there are provided a number of routines to facilitate
  4284. communication between the engine and the program proper.
  4285.  
  4286. Along with these, there are certain global variables and properties
  4287. that are pre-defined by the compiler and accessed by the engine. 
  4288. These are:
  4289.  
  4290. GLOBALS:  object         the direct object of a verb
  4291.           xobject        the indirect object
  4292.           self           self-referential object
  4293.           words          total number of words
  4294.           player         the player object
  4295.           location       location of the player
  4296.           verbroutine    the verb routine address
  4297.           endflag        if not false (0), call EndGame
  4298.           prompt         for input line
  4299.  
  4300. PROPERTIES:    name      basic object name
  4301.                before    pre-verb routines
  4302.                after     post-verb routines
  4303.                noun      noun(s) for referring to object
  4304.                adjective adjective(s) for referring to object
  4305.                article   "a", "an", "the", "some", etc.
  4306.                
  4307.                (As well as the aliases nouns and adjectives
  4308.                for noun and adjective, respectively)
  4309.  
  4310. Junction routines are not required.  The engine has built-in default
  4311. routines, although these will likely not be satisfactory for most
  4312. programmers.  Therefore, HUGOLIB.H contains each of the following
  4313. routines which fully implement all the features of the library.  If
  4314. a different routine is desired in place of a provided one, the
  4315. routine should be substituted with REPLACE. 
  4316.  
  4317.  
  4318. -----------------------------------------------------------------
  4319. VIII.a.  PARSE
  4320. -----------------------------------------------------------------
  4321.  
  4322. The Parse routine, if one exists, is called by the engine parser. 
  4323. Here, the program itself may modify the input line before grammar
  4324. matching is attempted.  What happens is:
  4325.  
  4326.      1.  The input line is split into words (by the engine).
  4327.      2.  The Parse routine, if it exists, is called.
  4328.      3.  Control returns to the engine for grammar matching.
  4329.  
  4330. For example, the Parse routine in HUGOLIB.H takes care of such
  4331. things as pronouns ("he", "she", "it", "them") and repeating the
  4332. last legal command (with "again" or simply "g").
  4333.  
  4334. Returning true from the Parse routine calls the engine parser again;
  4335. returning false continues normally.  This is useful in case the
  4336. Parse routine has changed the input line substantially, requiring a
  4337. reconfiguration of the already split words.
  4338.  
  4339. NOTE:  Since the library's Parse routine is rather extensive, a
  4340. provision is made for a PreParse routine--which in the library is
  4341. defined as being empty--which may more easily be REPLACED for
  4342. additional parsing.
  4343.  
  4344.  
  4345. -----------------------------------------------------------------
  4346. VIII.b.  PARSEERROR
  4347. -----------------------------------------------------------------
  4348.  
  4349. The ParseError routine is called whenever a command is invalid. 
  4350. ParseError is called in the form
  4351.  
  4352.      ParseError(<errornumber>, <object>)
  4353.  
  4354. where <object> is the object number (if any) of the object involved
  4355. in the error.
  4356.  
  4357. NOTE:  The engine also sets up a special variable called PARSE$,
  4358. usable only in a print statement (or in conjunction with STRING),
  4359. which represents the illegal component of an input line, whether it
  4360. is the verb itself, an object name, a partial object name, or any
  4361. other word combination.  For example:
  4362.  
  4363.      print "The illegal word was:  "; parse$; "."
  4364.  
  4365. The default responses provided by the engine parse error routine
  4366. are:
  4367.  
  4368.      ERROR NUMBER   RESPONSE
  4369.  
  4370.           0         "What?"
  4371.  
  4372.           1         "You can't use the word <parse$>."
  4373.  
  4374.           2         "Better start with a verb."
  4375.  
  4376.           3         "You can't <parse$> multiple objects."
  4377.  
  4378.           4         "Can't do that."
  4379.  
  4380.           5         "You haven't seen any <parse$>, nor are you
  4381.                     likely to in the near future even if such a
  4382.                     thing exists."
  4383.  
  4384.           6         "That doesn't make any sense."
  4385.  
  4386.           7         "You can't use multiple objects like that."
  4387.  
  4388.           8         "Which <parse$> do you mean,...?"
  4389.  
  4390.           9         "Nothing to <parse$>."
  4391.  
  4392.           10        "You haven't seen anything like that."
  4393.  
  4394.           11        "You don't see that."
  4395.  
  4396.           12        "You can't do that with the <parse$>."
  4397.  
  4398.           13        "You'll have to be a little more specific."
  4399.  
  4400.           14        "You don't see that there."
  4401.  
  4402.           15        "You don't have that."
  4403.  
  4404.           16        "You'll have to make a mistake first."
  4405.  
  4406.           17        "You can only correct one word at a time."
  4407.  
  4408. The ParseError routine in HUGOLIB.H provides several customized
  4409. responses that take into account such things as, for example,
  4410. whether or not an object is a character or not, and if so, if it is
  4411. male or female, etc.
  4412.  
  4413. If the ParseError routine does not provide a response for a
  4414. particular <errornumber>, it should return false.  Returning false
  4415. is a signal that the engine should continue with the default
  4416. message.
  4417.  
  4418. NOTE:  If custom error messages are desired for user parsing
  4419. routines, REPLACE the routine CustomError with a new routine (called
  4420. with the same parameters as ParseError), providing that
  4421. <errornumber> is greater than or equal to 100.
  4422.  
  4423.  
  4424. -----------------------------------------------------------------
  4425. VIII.c.  ENDGAME
  4426. -----------------------------------------------------------------
  4427.  
  4428. The EndGame routine is called immediately whenever the global
  4429. variable endflag is non-zero, regardless of whether or not the
  4430. current function has not yet been terminated.
  4431.  
  4432. HUGOLIB.H's EndGame routine behaves according to the value to which
  4433. endflag is set:
  4434.  
  4435.      endflag   RESULT
  4436.  
  4437.         1      Player wins
  4438.  
  4439.         2      Player's demise
  4440.  
  4441.        (3      Other ending--not provided for by default
  4442.                PrintEndGame routine)
  4443.  
  4444. Returning false from Endgame terminates the game completely;
  4445. returning non-false restarts.
  4446.  
  4447. NOTE:  To modify only the message displayed at the end of the game
  4448. (defaults:  "*** YOU'VE WON THE GAME! ***" and "*** YOU ARE DEAD
  4449. ***"), REPLACE the PrintEndGame routine.
  4450.  
  4451.  
  4452. -----------------------------------------------------------------
  4453. VIII.d.  FINDOBJECT
  4454. -----------------------------------------------------------------
  4455.  
  4456. The FindObject routine takes into account all the relevant
  4457. properties, attributes, and object hierarchy to determine whether or
  4458. not a particular object is available.  For example, the child of a
  4459. parent object may be available if the parent is a platform, but
  4460. unavailable if the parent is a container (and closed)--although
  4461. internally, the object hierarchy is the same.
  4462.  
  4463. FindObject is called via:
  4464.  
  4465.      FindObject(<object>, <location>)
  4466.  
  4467. where <object> is the object in question, and <location> is the
  4468. object where its availability is being tested.  (Usually <location>
  4469. is a room, unless a different parent has been specified in the input
  4470. line.)
  4471.  
  4472. FindObject returns true (1) if the object is available, false (0) if
  4473. unavailable.  It returns 2 if the object is visible but not
  4474. physically accessible.
  4475.  
  4476. The FindObject routine in HUGOLIB.H considers not only the location
  4477. of <object> in the object tree, but also tests the attributes of the
  4478. parent to see if it is open or closed.  As well, it checks the
  4479. found_in property, in case <object> has been assigned multiple
  4480. locations instead of an explicit parent, and then scans the in_scope
  4481. property of the object (if one exists).
  4482.  
  4483. Finally, the default behavior of FindObject requires that a player
  4484. have encountered an object for it to be valid in an action, i.e. it
  4485. must have the known attribute set.  To override this, REPLACE the
  4486. routine ObjectisKnown with a routine that returns an unconditional
  4487. true value.
  4488.  
  4489. There is one special case in which the engine expects the FindObject
  4490. routine to be especially helpful:  that is if the routine is called
  4491. with <location> equal to 0.  This occurs whenever the engine needs
  4492. to determine if an object is available AT ALL--regardless of any
  4493. rules normally governing object availability--such as when an
  4494. "anything" grammar token is encountered, or the engine needs to
  4495. disambiguate two or more seemingly identical objects.
  4496.  
  4497.  
  4498. -----------------------------------------------------------------
  4499. VIII.e.  SPEAKTO
  4500. -----------------------------------------------------------------
  4501.  
  4502. The SpeakTo routine is called whenever an input line begins with a
  4503. valid object name instead of a verb.  This is so the player may
  4504. direct commands to (usually) characters in the game.  For example:
  4505.  
  4506.      Professor Plum, drop the lead pipe
  4507.  
  4508. It is up to the SpeakTo routine to properly interpret the
  4509. instruction.
  4510.  
  4511. SpeakTo is called via:
  4512.  
  4513.      SpeakTo(<character>)
  4514.  
  4515. where <character> in the above example would be the Professor Plum
  4516. object.
  4517.  
  4518. The globals object, xobject, and verbroutine are all set up as
  4519. normal.  For the above example, then, these would be
  4520.  
  4521.      object         leadpipe
  4522.      xobject        nothing
  4523.      verbroutine    &DoDrop
  4524.  
  4525. when SpeakTo is called.
  4526.  
  4527. HUGOLIB.H's SpeakTo routine provides basic interpretation of
  4528. questions, so that
  4529.  
  4530.      Professor Plum, what about the lead pipe?
  4531.  
  4532. may be directed to the proper verb routine, as if the player had
  4533. typed:
  4534.  
  4535.      ask Professor Plum about the lead pipe
  4536.  
  4537. Imperative commands are, such as
  4538.  
  4539.      Colonel Mustard, stand up
  4540.  
  4541. are first directed to the order_response property of the character
  4542. object in question.  It is subsequently up to
  4543. <character>.order_response to analyze verbroutine (as well as object
  4544. and xobject, if applicable) to see if the request is a valid one. 
  4545. If no response is provided, order_response should return false.
  4546.  
  4547.      order_response
  4548.      {
  4549.           if verbroutine = &DoGet
  4550.                "I would, but my back is too sore."
  4551.           else
  4552.                return false
  4553.      }
  4554.  
  4555.  
  4556. -----------------------------------------------------------------
  4557. XI.  THE GAME LOOP
  4558. -----------------------------------------------------------------
  4559.  
  4560. This the paradigm that the Hugo Engine follows during program
  4561. execution:
  4562.  
  4563. (INIT:    The Init routine is called only when the program is first
  4564.           run, or when a RESTART command is issued.)
  4565.  
  4566. MAIN:     At the start of the game loop, the engine calls the Main
  4567.           routine.  The routine should--as in the provided sample
  4568.           programs--take care of advancing the turn counter,
  4569.           executing the RUNEVENTS command, and calling such library
  4570.           routines as RunScripts and PrintStatusLine.
  4571.  
  4572. INPUT:    Keyboard input is received.
  4573.  
  4574. PARSING:  The input line is checked for validity, synonyms and other
  4575.           special words are checked, and the user Parse routine (if
  4576.           any) is called.
  4577.  
  4578. GRAMMAR MATCHING:
  4579.           The engine attempts to match the input line with a valid
  4580.           verb and syntax in the grammar table.  If no match is
  4581.           found, the engine loops back to INPUT.
  4582.  
  4583.           Otherwise, a successful grammar match results in at least
  4584.           the verbroutine global being set, as well as potentially
  4585.           object and xobject.
  4586.  
  4587.      BEFORE ROUTINES:
  4588.                If any objects were specified in the input line,
  4589.                their before properties are checked in the following
  4590.                order, for each object:
  4591.  
  4592.                     player.before
  4593.                     location.before
  4594.                     xobject.before      (if applicable)
  4595.                     object.before       (if applicable)
  4596.  
  4597.                If any of these property routines returns true, the
  4598.                engine skips the verb routine.
  4599.  
  4600.           VERB ROUTINE:
  4601.                     If no before property routine returns true, the
  4602.                     verb routine is run.
  4603.  
  4604.                     If an action is successfully completed, the
  4605.                     verb routine should return true.  Returning
  4606.                     false negates any remaining commands in the
  4607.                     input line.
  4608.  
  4609.                     The engine does not run any after property
  4610.                     routines for object or xobject; that is up to
  4611.                     the verb routine.  It does run both
  4612.                     player.after and location.after if the
  4613.                     verbroutine returns true.
  4614.  
  4615. When finished, the engine loops back to MAIN:, calling the Main
  4616. routine only if the last verb matched was not an XVERB.
  4617.  
  4618. Setting the global endflag at any point to a non-zero value will
  4619. terminate the game loop and run the EndGame junction routine.
  4620.  
  4621. NOTE:  Undo information recalled by UNDO is saved each turn only
  4622. during the Main routine (including any commands or functions called
  4623. within, such as events, fuses and daemons, or character scripts) and
  4624. verb routines (unless the verb was an xverb).  It is therefore
  4625. recommended that no other routines change any signficant game data,
  4626. because it will not be recoverable with UNDO.
  4627.  
  4628.  
  4629.  
  4630. -----------------------------------------------------------------
  4631. X.  ADVANCED FEATURES
  4632. -----------------------------------------------------------------
  4633.  
  4634. -----------------------------------------------------------------
  4635. X.a.  READING AND WRITING FILES
  4636. -----------------------------------------------------------------
  4637.  
  4638. There may be times when it will be useful to store data in a file
  4639. for later recovery.  The most basic way of doing this involves
  4640.  
  4641.      x = save
  4642.  
  4643. and 
  4644.  
  4645.      x = restore
  4646.  
  4647. where the SAVE and RESTORE functions return a true value to x if
  4648. successful, or a false value if for some reason they fail.  In
  4649. either case, the entire set of game data--including object
  4650. locations, variable values, arrays, attributes, etc.--is saved or
  4651. restored, respectively.
  4652.  
  4653. Other times, it may be desirable to save only certain values.  For
  4654. example, a particular game may allow a player to create certain
  4655. player characteristics that can be restored in the same game or in
  4656. different games.  (This tends toward the idea behind many
  4657. role-playing games.)
  4658.  
  4659. To accomplish this, use the WRITEFILE and READFILE operations.
  4660.  
  4661. The structure
  4662.  
  4663.      writefile <filename>
  4664.      {
  4665.           ...
  4666.      }
  4667.  
  4668. will, at the start of the writefile block, open <filename> for
  4669. writing and position the filename to the start of the (empty) file. 
  4670. (If the file exists, it will be cleared.)  At the conclusion of the
  4671. block, the file will be closed again.
  4672.  
  4673. Within a writefile block, write individual values using
  4674.  
  4675.      writeval <value1>[, <value2>, ...]
  4676.  
  4677. where one or more values can be specified.
  4678.  
  4679. To read the file, use the structure
  4680.  
  4681.      readfile <filename>
  4682.      {
  4683.           ...
  4684.      }
  4685.  
  4686. which will contain the assignment
  4687.  
  4688.      x = readval
  4689.  
  4690. for each value to be read, where x can be any storage type such as
  4691. a variable, property, etc.
  4692.  
  4693. For example,
  4694.  
  4695.      local count, test
  4696.  
  4697.      count = 10
  4698.      writefile "testfile"
  4699.      {
  4700.           writeval count, "telephone", 10
  4701.           test = FILE_CHECK
  4702.           writeval test
  4703.      }
  4704.      if test ~= FILE_CHECK    ! an error has occurred
  4705.      {
  4706.           print "An error has occurred."
  4707.      }
  4708.  
  4709. will write the variable count, the dictionary entry "telephone", and
  4710. the value 10 to "testfile".  Then,
  4711.  
  4712.      local a, b, c, test
  4713.  
  4714.      readfile "testfile"
  4715.      {
  4716.           a = readval
  4717.           b = readval
  4718.           c = readval
  4719.           test = readval
  4720.      }
  4721.      if test ~= FILE_CHECK    ! an error has occurred
  4722.      {
  4723.           print "Error reading file."
  4724.      }
  4725.  
  4726. If the readfile block executes successfully, a will be equal to the
  4727. former value count, b will be "telephone", and c will be 10.
  4728.  
  4729. The constant FILE_CHECK, defined in HUGOLIB.H, is useful because
  4730. writefile and readfile provide no explicit error return to indicate
  4731. failure.  FILE_CHECK is a unique two-byte sequence that can be used
  4732. to test for success.
  4733.  
  4734. In the writefile block, if the block is exited prematurely due to an
  4735. error, test will never be set to FILE_CHECK.  The IF statement
  4736. following the block tests for this.
  4737.  
  4738. In the readfile block, test will only be set to FILE_CHECK if the
  4739. sequence of readval functions finds the expected number of values in
  4740. "testfile".  If there are too many or too few values in "testfile",
  4741. or if an error forces an early exit from the readfile block, test
  4742. will equal a value other than FILE_CHECK.
  4743.  
  4744.  
  4745.  
  4746. -----------------------------------------------------------------
  4747. APPENDIX A:  SUMMARY OF KEYWORDS AND COMMANDS
  4748. -----------------------------------------------------------------
  4749.  
  4750. AND
  4751.  
  4752.           DESCRIPTION:   Logical and.
  4753.  
  4754.           SYNTAX:   x = <value1> and <value2>
  4755.  
  4756.           RESULT:   x will be true if <value1> and <value2> are
  4757.                     both non-zero, false if one or both is zero.
  4758.  
  4759.  
  4760. ANYTHING
  4761.  
  4762.           DESCRIPTION:   Object specifier in grammar syntax line,
  4763.                          indicating that any nameable object in the
  4764.                          object tree is valid.
  4765.  
  4766.  
  4767. ARRAY
  4768.  
  4769.           DESCRIPTION:   When used as a data type modifier,
  4770.                          specifies that the following value is to
  4771.                          be treated as an array address.
  4772.  
  4773.           EXAMPLE:  <var1> = array <var2>[5]
  4774.  
  4775.                     The variable <var2> will be treated as an array
  4776.                     address.
  4777.  
  4778.  
  4779. BREAK
  4780.  
  4781.           DESCRIPTION:   Terminates the immediate enclosing loop.
  4782.  
  4783.           EXAMPLE:  while <expression1>
  4784.                     {
  4785.                          while <expression2>
  4786.                          {
  4787.                               if <expression3>
  4788.                                    break
  4789.                               ...
  4790.                          }
  4791.                          ...
  4792.                     }
  4793.  
  4794.                     The break statement, if encountered, will
  4795.                     terminate the innermost loop.
  4796.  
  4797.  
  4798. CALL
  4799.  
  4800.           DESCRIPTION:   Calls a routine indirectly, i.e. when the
  4801.                          routine address has been stored in a
  4802.                          variable, object property, etc.
  4803.  
  4804.           SYNTAX:   call <value>[(<argument1>, <argument2>,...)]
  4805.  
  4806.                     where <value> is a valid data type holding the
  4807.                     routine address.
  4808.  
  4809.           RETURN VALUE:  When used as a function, returns the value
  4810.                          returned by the specified routine.
  4811.  
  4812.  
  4813. CAPITAL
  4814.  
  4815.           DESCRIPTION:   Print statement modifier, indicating that
  4816.                          the next word should be printed with the
  4817.                          first letter capitalized.
  4818.  
  4819.           SYNTAX:   print capital <address>
  4820.  
  4821.                     where <address> is any dictionary word, such 
  4822.                     as, for example, an object.name property.
  4823.  
  4824. CASE
  4825.  
  4826.           DESCRIPTION:   Specifies a conditional case in a SELECT
  4827.                          structure.
  4828.  
  4829.           SYNTAX:   select <val>
  4830.                          case <case1>[, <case2>,...]
  4831.                               ...
  4832.                          case <case3>[, <case4>,...]
  4833.                               ...
  4834.  
  4835.                     where <val> is value such as a variable,
  4836.                     routine return value, object property, array 
  4837.                     element, etc., and each <case> is a single
  4838.                     value for comparison (not an expression).
  4839.  
  4840.  
  4841. CHILD
  4842.  
  4843.           SYNTAX:   x = child(<parent>)
  4844.  
  4845.           RETURN VALUE:  The object number of the immediate child
  4846.                          object of <parent>, or 0 if <parent> has
  4847.                          no children.
  4848.  
  4849.  
  4850. CHILDREN
  4851.  
  4852.           SYNTAX:   x = children(<parent>)
  4853.  
  4854.           RETURN VALUE:  The number of objects possessed by
  4855.                          <parent>.
  4856.  
  4857.  
  4858. CLS
  4859.  
  4860.           DESCRIPTION:   Clears the screen (i.e. the text window)
  4861.                          and repositions the output coordinates at
  4862.                          the bottom left of the text window.
  4863.  
  4864.           SYNTAX:   cls
  4865.  
  4866.  
  4867. COLOR (or COLOUR)
  4868.  
  4869.           DESCRIPTION:   Sets the display colors for text output.
  4870.  
  4871.           SYNTAX:   color <foreground>[, <background>]
  4872.  
  4873.                     where <background> is optional
  4874.  
  4875.           PARAMETERS:    Standard color values for <foreground> and
  4876.                          <background> are:
  4877.  
  4878.                          0    Black
  4879.                          1    Blue
  4880.                          2    Green
  4881.                          3    Cyan
  4882.                          4    Red
  4883.                          5    Magenta
  4884.                          6    Brown
  4885.                          7    White
  4886.                          8    Dark gray
  4887.                          9    Light blue
  4888.                          10   Light green
  4889.                          11   Light cyan
  4890.                          12   Light red
  4891.                          13   Light magenta
  4892.                          14   Light yellow
  4893.                          15   Bright white
  4894.  
  4895.  
  4896. DICT
  4897.  
  4898.           DESCRIPTION:   Dynamically creates a new dictionary entry
  4899.                          at runtime.
  4900.  
  4901.           SYNTAX:   x = dict(<array>, <maxlen>)
  4902.  
  4903.                     x = dict(parse$, <maxlen>)
  4904.  
  4905.                     where <array> or parse$ holds the string to be
  4906.                     written into the dictionary, and <maxlen>
  4907.                     represents the maximum number of characters to
  4908.                     be written.  Returns the new dictionary
  4909.                     address.  (NOTE:  Space should be reserved for
  4910.                     any dictionary entries to be created at runtime
  4911.                     using the $MAXDICTEXTEND setting during
  4912.                     compilation.)
  4913.  
  4914. DO
  4915.  
  4916.           DESCRIPTION:   Marks the starting point of a DO-WHILE
  4917.                          loop.
  4918.  
  4919.           SYNTAX:   do
  4920.                     {
  4921.                          ...
  4922.                     }
  4923.                     while <expr>
  4924.  
  4925.                     The loop will continue to run as long as <expr>
  4926.                     holds true.    
  4927.  
  4928.  
  4929. ELDER
  4930.  
  4931.           SYNTAX:   x = elder(<object>)
  4932.  
  4933.           RETURN VALUE:  The object number of the object preceding
  4934.                          <object> on the same branch in the object
  4935.                          tree.  The reverse of SIBLING.
  4936.  
  4937.  
  4938. ELDEST
  4939.  
  4940.           Same as CHILD.
  4941.  
  4942.  
  4943. ELSE
  4944.  
  4945.           DESCRIPTION:   In an IF-ELSEIF-ELSE conditional block, 
  4946.                          indicates the default operation if no
  4947.                          previous condition has been met.
  4948.  
  4949.           SYNTAX:   if <condition>
  4950.                          ...
  4951.                     else
  4952.                          ...
  4953.  
  4954.  
  4955. ELSEIF
  4956.  
  4957.           DESCRIPTION:   In an IF-ELSEIF-ELSE conditional block, 
  4958.                          indicates a condition that will be checked
  4959.                          only if no preceding condition has been
  4960.                          met.
  4961.  
  4962.           SYNTAX:   if <condition1>
  4963.                          ...
  4964.                     elseif <condition2>
  4965.                          ...
  4966.                     elseif <condition3>
  4967.                          ...
  4968.  
  4969.  
  4970. FALSE
  4971.  
  4972.           DESCRIPTION:   A predefined constant value:  0.
  4973.  
  4974.  
  4975. FOR
  4976.  
  4977.           DESCRIPTION:   Loop construction.
  4978.  
  4979.           SYNTAX:   for (<initial>; <test>; <mod>)
  4980.                     {
  4981.                          ...
  4982.                     }
  4983.  
  4984.                     for <var> in <object>
  4985.                     {
  4986.                          ...
  4987.                     }
  4988.  
  4989.                     For the first form, where <initial> is the
  4990.                     initial assignment expression (e.g. a = 1),
  4991.                     <test> is the test expression (e.g. a < 10), 
  4992.                     and <mod> is the modifying expression (e.g. a
  4993.                     = a + 1).  The loop will execute as long as
  4994.                     <test> holds true.
  4995.  
  4996.                     The second form loops through all the children
  4997.                     of <object> (if any), setting <var> to each
  4998.                     child object in sequence.
  4999.  
  5000.  
  5001. GRAPHICS
  5002.  
  5003.           Turns on graphics mode; not supported in Hugo v2.x.
  5004.  
  5005.  
  5006. HELD
  5007.  
  5008.           DESCRIPTION:   Object specifier in grammar syntax line,
  5009.                          indicating that any single object
  5010.                          possessed by the player object is valid.
  5011.  
  5012.  
  5013. HEX
  5014.  
  5015.           DESCRIPTION:   Print statement modifier signifying that
  5016.                          the following value is not a dictionary 
  5017.                          address, but should be printed as a
  5018.                          hexadecimal number.
  5019.  
  5020.  
  5021.           SYNTAX:   print hex <var>
  5022.  
  5023.                     where, for example, <var> is equal to 26, will
  5024.                     print "1A".
  5025.  
  5026.  
  5027. IF
  5028.  
  5029.           DESCRIPTION:   A conditional expression.
  5030.  
  5031.           SYNTAX:   if <condition>
  5032.                          ...
  5033.  
  5034.                     where <condition> is an expression or value, 
  5035.                     will run the following statement block only if
  5036.                     <condition> is true.
  5037.  
  5038.  
  5039. IN
  5040.  
  5041.           DESCRIPTION:   When used in an object definition, places
  5042.                          the object in the object tree as a
  5043.                          possession of the specified parent.  When
  5044.                          used in an expression, returns true if the
  5045.                          object is in the specified parent.
  5046.  
  5047.           SYNTAX:   in <parent>
  5048.  
  5049.                     or
  5050.  
  5051.                     <object> [not] in <parent>
  5052.  
  5053.  
  5054. INPUT
  5055.  
  5056.           DESCRIPTION:   Receive input from keyboard, storing the
  5057.                          dictionary addresses of the individual
  5058.                          words in the word array.  Unrecognized
  5059.                          words are given a value of 0.
  5060.  
  5061.           SYNTAX:   input
  5062.  
  5063.  
  5064. IS
  5065.  
  5066.           DESCRIPTION:   Attribute assignment/testing.
  5067.  
  5068.           SYNTAX:   <object> is [not] <attribute>
  5069.  
  5070.           USAGE:    When used as an assignment on its own, will set
  5071.                     (or clear, if NOT is used) the specified
  5072.                     attribute for the given object.  May also be 
  5073.                     used in an expression.
  5074.  
  5075.           RETURN VALUE:  When used in an expression, returns true
  5076.                          if <object> has the specified attribute 
  5077.                          set (or cleared, if NOT is used). 
  5078.                          Otherwise, it returns false.
  5079.  
  5080.  
  5081. JUMP
  5082.  
  5083.           DESCRIPTION:   Jumps to a specified label.
  5084.  
  5085.           SYNTAX:   jump <label>
  5086.  
  5087.                     where a unique <label> exists on a separate
  5088.                     line somewhere in the program, in the form:
  5089.  
  5090.                     :<label>
  5091.  
  5092.  
  5093. LOCAL
  5094.  
  5095.           DESCRIPTION:   Defines one or more variables local to the
  5096.                          current routine.
  5097.  
  5098.           SYNTAX:   local <var1>[, <var2>, <var3>,...]
  5099.  
  5100.  
  5101. LOCATE
  5102.  
  5103.           DESCRIPTION:   Sets the cursor position.
  5104.  
  5105.           SYNTAX:   locate(<row>, <column>)
  5106.  
  5107.           NOTE:     Screen size limits are undefined by the engine.
  5108.  
  5109.  
  5110. MOVE
  5111.  
  5112.           DESCRIPTION:   Moves an object with all its possessions
  5113.                          to a new parent.
  5114.  
  5115.           SYNTAX:   move <object> to <new parent>
  5116.  
  5117.  
  5118. MULTI
  5119.  
  5120.           DESCRIPTION:   Object specifier in grammar syntax line,
  5121.                          indicating that multiple available objects
  5122.                          are valid.
  5123.  
  5124.  
  5125. MULTIHELD
  5126.  
  5127.           DESCRIPTION:   Object specifier in grammar syntax line,
  5128.                          indicating that multiple objects possessed
  5129.                          by the player object are valid.
  5130.  
  5131.  
  5132. MULTINOTHELD
  5133.  
  5134.           DESCRIPTION:   Object specifier in grammar syntax line,
  5135.                          indicating that multiple objects
  5136.                          explicitly not held by the player object
  5137.                          are valid.
  5138.  
  5139.  
  5140. NEARBY
  5141.  
  5142.           DESCRIPTION:   Used in an object definition to place the
  5143.                          object in the specified position in the
  5144.                          object tree.
  5145.  
  5146.           SYNTAX:   nearby <object>
  5147.  
  5148.                     Gives the current object the same parent as
  5149.                     <object>.
  5150.  
  5151.                     nearby
  5152.  
  5153.                     Gives the current object the same parent as the
  5154.                     last-defined object.
  5155.  
  5156.  
  5157. NEWLINE
  5158.  
  5159.           DESCRIPTION:   Print statement modifier, indicating that
  5160.                          a line feed and carriage return should be
  5161.                          issued if the current output position is
  5162.                          not already at the start of a blank line.
  5163.  
  5164.           SYNTAX:   print newline
  5165.  
  5166.  
  5167. NOT
  5168.  
  5169.           DESCRIPTION:   Logical not.
  5170.  
  5171.           SYNTAX:   x = not <value>
  5172.  
  5173.                     <object> is not <attribute>
  5174.  
  5175.           RESULT:   In the first example, x will be true if <value>
  5176.                     is false, or false if <value> is true.
  5177.  
  5178.                     In the second, the specified attribute will be
  5179.                     cleared for <object> when used alone as an
  5180.                     assignment.  As part of an expression, it will
  5181.                     return true only if <object> does not have
  5182.                     <attribute> set.
  5183.  
  5184.  
  5185. NOTHELD
  5186.  
  5187.           DESCRIPTION:   Object specifier in grammar syntax line,
  5188.                          indicating that a single object explicitly
  5189.                          not held by the player object is valid.
  5190.  
  5191.  
  5192. NUMBER
  5193.  
  5194.           DESCRIPTION:   When used in a grammar syntax line,
  5195.                          indicates that a single positive integer
  5196.                          number is valid.
  5197.  
  5198.                          When used as a print statement modifier,
  5199.                          indicates that the following value is not
  5200.                          a dictionary address, but should be
  5201.                          printed as a positive integer number.
  5202.  
  5203.           SYNTAX:   (for usage as a print statement modifier)
  5204.  
  5205.                     print number <val>
  5206.  
  5207.                     where, for example, <val> is equal to 100, will
  5208.                     print "100" instead of the word beginning at
  5209.                     the address 100 in the dictionary table.
  5210.  
  5211.  
  5212. OBJECT
  5213.  
  5214.           DESCRIPTION:   Global variable holding the object number
  5215.                          of the direct object, if any, specified in
  5216.                          the input line.
  5217.  
  5218.                          When used in a grammar syntax line,
  5219.                          indicates that a single available object
  5220.                          is valid.
  5221.  
  5222.  
  5223. OR
  5224.  
  5225.           DESCRIPTION:   Logical or.
  5226.  
  5227.           SYNTAX:   x = <value1> or <value2>
  5228.  
  5229.           RESULT:   x will be true if either <value1> or <value2>
  5230.                     is non-false, false if both are false.
  5231.  
  5232.  
  5233. PARENT
  5234.  
  5235.           (Usage 1)
  5236.  
  5237.           SYNTAX:   x = parent(<object>)
  5238.  
  5239.           RETURN VALUE:  The object number of <object>'s parent
  5240.                          object.
  5241.  
  5242.  
  5243.           (Usage 2)
  5244.  
  5245.           DESCRIPTION:   When used in a grammar syntax line,
  5246.                          indicates that the domain for validating
  5247.                          the availability of the specified direct
  5248.                          object should be set to the parent object
  5249.                          specified in the input line.
  5250.  
  5251.  
  5252. PARSE$
  5253.  
  5254.           DESCRIPTION:   Engine variable, usable only in a PRINT 
  5255.                          statement or in conjunction with STRING 
  5256.                          or DICT, which contains either the
  5257.                          offending portion of an invalid input line
  5258.                          or any section of the input line enclosed
  5259.                          in quotes.
  5260.  
  5261.           SYNTAX:   print parse$
  5262.  
  5263.  
  5264. PAUSE
  5265.  
  5266.           DESCRIPTION:   Pauses until a key is pressed.  The ASCII
  5267.                          value of the key is stored in word[0].
  5268.  
  5269.  
  5270. PLAYBACK
  5271.  
  5272.           DESCRIPTION:   Plays back recorded commands from a file
  5273.                          in place of keyboard input.
  5274.  
  5275.           SYNTAX:   x = playback
  5276.  
  5277.           RETURN VALUE:  True if successful, false if not.
  5278.  
  5279.  
  5280. PRINT
  5281.  
  5282.           DESCRIPTION:   Print text output.
  5283.  
  5284.           SYNTAX:   print <output>
  5285.  
  5286.                     where <output> can consist of both test strings
  5287.                     enclosed in quotation marks ("..."), and values
  5288.                     representing dictionary addresses, such as
  5289.                     object names.  Separate components of <output>
  5290.                     are separated by a semicolon (";").  Each
  5291.                     component may also be preceded by a modifier
  5292.                     such as CAPITAL, HEX, or NUMBER.
  5293.  
  5294.  
  5295. PRINTCHAR
  5296.  
  5297.           DESCRIPTION:   Prints an ASCII character or series of
  5298.                          characters at the current cursor position. 
  5299.                          No newline is printed.
  5300.  
  5301.           SYNTAX:   printchar <val1>[, <val2>,...]
  5302.  
  5303.  
  5304. QUIT
  5305.  
  5306.           DESCRIPTION:   Terminates the game loop.
  5307.  
  5308.           SYNTAX:   quit
  5309.  
  5310.  
  5311. RANDOM
  5312.  
  5313.           DESCRIPTION:   Engine function which generates a random
  5314.                          number.
  5315.  
  5316.           SYNTAX:   x = random(<val>)
  5317.  
  5318.           RETURN VALUE:  Where <val> is a positive integer number,
  5319.                          will return a random number between 1 and
  5320.                          <val>, inclusively.
  5321.  
  5322.  
  5323. READFILE
  5324.  
  5325.           DESCRIPTION:   A structure that allows values to be read
  5326.                          from a file written using writefile.
  5327.  
  5328.           SYNTAX:   readfile <filename>
  5329.                     {
  5330.                          ...
  5331.                     }
  5332.  
  5333.                     The file is opened and positioned to the start
  5334.                     at the beginning of the readfile block, and
  5335.                     closed at the end.
  5336.  
  5337.  
  5338. READVAL
  5339.  
  5340.           DESCRIPTION:   Reads a value in a readfile block.
  5341.  
  5342.           SYNTAX:   x = readval
  5343.  
  5344.           RETURN VALUE:  The value read, or 0 in the case of an
  5345.                          error.  Use the FILE_CHECK constant
  5346.                          defined in HUGOLIB.H to determine if a
  5347.                          readfile block has been executed
  5348.                          successfully.  See the section above on 
  5349.                          "Reading and Writing Files".
  5350.  
  5351.  
  5352. RECORDOFF
  5353.  
  5354.           DESCRIPTION:   Ends recording commands to a file.
  5355.  
  5356.           SYNTAX:   x = recordoff
  5357.  
  5358.           RETURN VALUE:  True if successful, false if not.
  5359.  
  5360.  
  5361. RECORDON
  5362.  
  5363.           DESCRIPTION:   Begins recording commands to a file.
  5364.  
  5365.           SYNTAX:   x = recordon
  5366.  
  5367.           RETURN VALUE:  True if successful, false if not.
  5368.  
  5369.  
  5370. REMOVE
  5371.  
  5372.           DESCRIPTION:   Removes an object from the object tree.
  5373.  
  5374.           SYNTAX:   remove <object>
  5375.  
  5376.                     (The same as:  move <object> to 0)
  5377.  
  5378.  
  5379. RESTART
  5380.  
  5381.           DESCRIPTION:   Reloads the initial game data and calls 
  5382.                          the Init routine.
  5383.  
  5384.           SYNTAX:   x = restart
  5385.  
  5386.           NOTE:     RESTART does not technically restart the
  5387.                     engine; the game loop continues uninterrupted
  5388.                     after Init is called, only with the game data
  5389.                     restored to its initial state.
  5390.  
  5391.           RETURN VALUE:  True if successful, false if not.
  5392.  
  5393.  
  5394. RESTORE
  5395.  
  5396.           DESCRIPTION:   Restores a saved game by calling the
  5397.                          engine's restore routine.
  5398.  
  5399.           SYNTAX:   x = restore
  5400.  
  5401.           RETURN VALUE:  True if successful, false if not.
  5402.  
  5403.  
  5404. RETURN
  5405.  
  5406.           DESCRIPTION:   Returns from a called routine.
  5407.  
  5408.           SYNTAX:   return [<expression>]
  5409.  
  5410.           RETURN VALUE:  Returns <expression> if provided,
  5411.                          otherwise returning false.
  5412.  
  5413.  
  5414. RUN
  5415.  
  5416.           DESCRIPTION:   Runs an object property routine if one
  5417.                          exists.
  5418.  
  5419.           SYNTAX:   run <object>.<property>
  5420.  
  5421.           RETURN VALUE:  None; any value returned by the property
  5422.                          routine is discarded.
  5423.  
  5424.  
  5425. RUNEVENTS
  5426.  
  5427.           DESCRIPTION:   Calls all events which are either global
  5428.                          or currently within the event scope of the
  5429.                          player object.
  5430.  
  5431.           SYNTAX:   runevents
  5432.  
  5433.  
  5434. SAVE
  5435.  
  5436.           DESCRIPTION:   Saves the current game position by calling
  5437.                          the engine's save routine.
  5438.  
  5439.           SYNTAX:   x = save
  5440.  
  5441.           RETURN VALUE:  True if successful, false if not.
  5442.  
  5443.  
  5444. SCRIPTOFF
  5445.  
  5446.           DESCRIPTION:   Turns transcription off.
  5447.  
  5448.           SYNTAX:   x = scriptoff
  5449.  
  5450.           RETURN VALUE:  True if successful, false if not.
  5451.  
  5452.  
  5453. SCRIPTON
  5454.  
  5455.           DESCRIPTION:   Turns transcription on by calling the
  5456.                          engine's transcription routine.
  5457.  
  5458.           SYNTAX:   x = scripton
  5459.  
  5460.           RETURN VALUE:  True if successful, false if not.
  5461.  
  5462.  
  5463. SELECT
  5464.  
  5465.           DESCRIPTION:   Specifies the value for comparison in a 
  5466.                          SELECT-CASE conditional structure.
  5467.  
  5468.           SYNTAX:   select <val>
  5469.                          case <case1>[, <case2>,...]
  5470.                               ...
  5471.                          case <case3>[, <case4>,...]
  5472.                               ...
  5473.  
  5474.                     where <val> is value such as a variable,
  5475.                     routine return value, object property, array 
  5476.                     element, etc., and each <case> is a single
  5477.                     value for comparison (not an expression).
  5478.  
  5479.  
  5480. SERIAL$
  5481.  
  5482.           DESCRIPTION:   Engine variable, usable only in a print 
  5483.                          statement, which contains the serial
  5484.                          number as written by the compiler.
  5485.  
  5486.           SYNTAX:   print serial$
  5487.  
  5488.  
  5489. SIBLING
  5490.  
  5491.           SYNTAX:   x = sibling(<object>)
  5492.  
  5493.           RETURN VALUE:  The number of the object next to <object>
  5494.                          on the same branch of the object tree.
  5495.  
  5496.  
  5497. STRING
  5498.  
  5499.           DESCRIPTION:   When used in a grammar syntax line,
  5500.                          indicates that a string array enclosed in
  5501.                          quotation marks is valid.
  5502.  
  5503.                          When used as a function, stores a
  5504.                          dictionary entry in a string array.
  5505.  
  5506.           SYNTAX:   x = string(<array>, <dict>, <maxlen>)
  5507.  
  5508.                     x = string(<array>, parse$, <maxlen>)
  5509.  
  5510.                     where <array> is an array address, stores the
  5511.                     either the dictionary entry given by <dict> or
  5512.                     the contents of parse$ as a series of ASCII
  5513.                     characters, to a maximum of <maxlen>
  5514.                     characters.  Returns the length of the string
  5515.                     stored in <array>.
  5516.  
  5517.  
  5518. TEXT
  5519.  
  5520.           Turns on text mode; not supported in Hugo v2.x.
  5521.  
  5522.           text to <val>  Sends text to the array table, beginning
  5523.                          at address <val>.
  5524.  
  5525.           text to 0      Restores normal printing.
  5526.  
  5527.  
  5528. TO
  5529.  
  5530.           DESCRIPTION:   In a PRINT statement, prints blank spaces
  5531.                          in the current background color to the
  5532.                          specified position.
  5533.  
  5534.           SYNTAX:   print to <val>
  5535.  
  5536.                     where <val> is a positive integer less than or
  5537.                     equal to the maximum column position
  5538.  
  5539.  
  5540. TRUE
  5541.  
  5542.           DESCRIPTION:   Predefined constant:  1.
  5543.  
  5544.  
  5545. UNDO
  5546.  
  5547.           DESCRIPTION:   Attempts to recover the state of the game
  5548.                          data before the last player command.
  5549.  
  5550.           SYNTAX:   x = undo
  5551.  
  5552.           RETURN VALUE:  True if successful, false if not.
  5553.  
  5554.  
  5555. VERB
  5556.  
  5557.           DESCRIPTION:   Begins definition of a regular verb.  Upon
  5558.                          returning true from the verb routine, Main
  5559.                          is called.
  5560.  
  5561.           SYNTAX:   verb "<word1>"[, "<word2>",...]
  5562.  
  5563.  
  5564. WHILE
  5565.  
  5566.           DESCRIPTION:   Component of WHILE or DO-WHILE loop
  5567.                          construct.
  5568.  
  5569.           SYNTAX:   while <expr>
  5570.                          ...
  5571.  
  5572.                     (or)
  5573.  
  5574.                     do
  5575.                          ...
  5576.                     while <expr>
  5577.  
  5578.                     where the loop will run as long as <expr> holds
  5579.                     true.
  5580.  
  5581.  
  5582. WINDOW
  5583.  
  5584.           DESCRIPTION:   Switches output to the status window.
  5585.  
  5586.           SYNTAX:   window
  5587.                     {
  5588.                          ...
  5589.                     }
  5590.  
  5591.                     where the routine in braces following WINDOW 
  5592.                     will send its output to the status window,
  5593.                     beginning at the top-left corner of the screen. 
  5594.                     The current output position upon exiting the
  5595.                     window routine will become the new bottom of
  5596.                     the window.
  5597.  
  5598.  
  5599. WRITEFILE
  5600.  
  5601.           DESCRIPTION:   A structure that writes values to a file
  5602.                          that may be read using readfile.
  5603.  
  5604.           SYNTAX:   writefile <filename>
  5605.                     {
  5606.                          ...
  5607.                     }
  5608.  
  5609.                     The file is opened and positioned to the start
  5610.                     at the beginning of the writefile block, and
  5611.                     closed at the end.
  5612.  
  5613.  
  5614. WRITEVAL
  5615.  
  5616.           DESCRIPTION:   Writes one or more values in a writefile
  5617.                          block.
  5618.  
  5619.           SYNTAX:   writefile value1[, value2, ...]
  5620.  
  5621.  
  5622. XOBJECT
  5623.  
  5624.           DESCRIPTION:   Global variable holding the object number
  5625.                          of the indirect object, if any, specified
  5626.                          in the input line.
  5627.  
  5628.                          When used in a grammar syntax line,
  5629.                          indicates that a single available object
  5630.                          is valid.
  5631.  
  5632.  
  5633. XVERB
  5634.  
  5635.           DESCRIPTION:   Begins definition of non-action verb. 
  5636.                          Upon returning from the verb routine, Main
  5637.                          is not called.
  5638.  
  5639.           SYNTAX:   xverb "<word1>"[,"<word2>",...]
  5640.  
  5641.  
  5642. YOUNGER
  5643.  
  5644.           Same as SIBLING.
  5645.  
  5646.  
  5647. YOUNGEST
  5648.  
  5649.           SYNTAX:   x = youngest(<parent>)
  5650.  
  5651.           RETURN VALUE:  The number of the object most recently
  5652.                          added to parent <parent>.
  5653.  
  5654.  
  5655.  
  5656. -----------------------------------------------------------------
  5657. APPENDIX B:  THE LIBRARY (HUGOLIB.H)
  5658. -----------------------------------------------------------------
  5659.  
  5660. -----------------------------------------------------------------
  5661. ATTRIBUTES
  5662. -----------------------------------------------------------------
  5663.  
  5664.      known          if an object is known to the player
  5665.      moved          if an object has been moved
  5666.      visited        if a room has been visited
  5667.      static         if an object cannot be taken
  5668.      plural         for plural objects (i.e. some hats)
  5669.      living         if an object is a character
  5670.      female         if a character is female
  5671.      unfriendly     if a character is unfriendly
  5672.      openable       if an object can be opened
  5673.      open           if it is open
  5674.      lockable       if an object can be locked
  5675.      locked         if it is locked
  5676.      light          if an object is or provides light
  5677.      readable       if an object can be read
  5678.      switchable     if an object can be turned on or off
  5679.      switchedon     if it is on
  5680.      clothing       for objects that can be worn
  5681.      worn           if the object is being worn
  5682.      mobile         if the object can be rolled, etc.
  5683.      enterable      if an object is enterable
  5684.      container      if an object can hold other objects
  5685.      platform       if other objects can be placed on it
  5686.                     (NOTE:  container and platform are
  5687.                      mutually exclusive)
  5688.      hidden         if an object is not to be listed
  5689.      quiet          if container or platform is quiet (i.e. the
  5690.                      initial listing of contents is suppressed)
  5691.      transparent    if object is not opaque
  5692.      already_listed if object has been pre-listed (i.e. before,
  5693.                      for example, a WhatsIn listing)
  5694.      workflag       for system use
  5695.      special        for miscellaneous use
  5696.  
  5697.  
  5698. -----------------------------------------------------------------
  5699. GLOBALS, CONSTANTS, AND ARRAYS
  5700. -----------------------------------------------------------------
  5701.  
  5702. GLOBALS:
  5703.  
  5704. The first 10 globals are pre-defined by the compiler:
  5705.  
  5706.      object            direct object of a verb action
  5707.      xobject           indirect object
  5708.      self              self-referential object
  5709.      words             total number of words
  5710.      player            the player object
  5711.      actor             player, or another char. (for scripts)
  5712.      location          location of the player object
  5713.      verbroutine       the verb routine
  5714.      endflag           if not false (0), run EndGame
  5715.      prompt            for input line
  5716.      objects           the total number of objects
  5717.      linelength        the maximum length of a line of text
  5718.      pagelength        the maximum number of lines in the window
  5719.  
  5720.      player_person     first (1), second (2), or third (3)
  5721.      MAX_SCORE         total possible score
  5722.      MAX_RANK          up to x levels of player ranking
  5723.      FORMAT            specifies text-printing format
  5724.      DEFAULT_FONT      usually 0; could be, for example, PROP_ON
  5725.      STATUSTYPE        0=none, 1=score/turns, 2=time
  5726.      DISPLAYTYPE       0=text, 1=graphics
  5727.      TEXTCOLOR         normal text color
  5728.      BGCOLOR           normal background color
  5729.      BOLDCOLOR         color for boldface printing
  5730.      SL_TEXTCOLOR      statusline text color
  5731.      SL_BGCOLOR        statusline background color
  5732.      INDENT_SIZE       for paragraph indenting
  5733.      AFTER_PERIOD      number of spaces following a full-stop
  5734.      counter           elapsed turns (or time, as desired)
  5735.      score             accumulated score
  5736.      verbosity         for room descriptions
  5737.      list_nest         used by ListObjects
  5738.      light_source      in location
  5739.      event_flag        set when something happens
  5740.      speaking          if the player is talking to a char.
  5741.      old_location      whenever location changes
  5742.      obstacle          if something is stopping the player
  5743.      best_parse_rank   for differentiating like-named objects
  5744.      customerror_flag  true once CustomError is called
  5745.      need_newline      true when newline should be printed
  5746.      override_indent   true if no indent should be printed
  5747.      number_scripts    number of active character scripts
  5748.      it_obj            to reference objects via pronouns
  5749.      them_obj
  5750.      him_obj
  5751.      her_obj
  5752.      general           for general use
  5753.  
  5754.  
  5755. ARRAYS:
  5756.  
  5757.      replace_pronoun[4]       for it_obj, him_obj, etc.
  5758.      oldword[MAX_WORDS]       for "again" command
  5759.      scriptdata[48]           for object scripts
  5760.      array setscript[1024]    the actual scripts
  5761.      array ranking[10]        in tandem with scoring
  5762.  
  5763.  
  5764. CONSTANTS:
  5765.  
  5766.      BANNER              should be printed in every game header   
  5767.      MAX_SCRIPTS         that may be active at one time
  5768.      MAX_WORDS           in a parsed input line
  5769.  
  5770.      Color constants:
  5771.  
  5772.      BLACK          DARK GRAY
  5773.      BLUE           LIGHT_BLUE
  5774.      GREEN          LIGHT_GREEN
  5775.      CYAN           LIGHT_CYAN
  5776.      RED            LIGHT_RED
  5777.      MAGENTA        LIGHT_MAGENTA
  5778.      BROWN          YELLOW
  5779.      WHITE          BRIGHT_WHITE
  5780.  
  5781.      Printing format masks (for setting FORMAT global):
  5782.  
  5783.      LIST_F              print itemized lists, not sentences
  5784.      NORECURSE_F         do not recurse object contents
  5785.      NOINDENT_F          do not indent listings
  5786.      DESCFORM_F          alternate room description formatting
  5787.      GROUPPLURALS_F      list plurals together where possible
  5788.  
  5789.      Font style masks (for use with the Font routine):
  5790.  
  5791.      BOLD_ON        BOLD_OFF            boldface
  5792.      ITALIC_ON      ITALIC_OFF          italics
  5793.      UNDERLINE_ON   UNDERLINE_OFF       underline
  5794.      PROP_ON        PROP_OFF            proportional printing
  5795.  
  5796.      Additional constants:
  5797.  
  5798.      UP_ARROW            LEFT_ARROW     for reading keystrokes
  5799.      DOWN_ARROW          ENTER_KEY
  5800.      RIGHT_ARROW         ESCAPE_KEY
  5801.  
  5802.      AND_WORD  ("and")   IN_WORD   ("in")
  5803.      ARE_WORD  ("are")   IS_WORD   ("is")
  5804.      HERE_WORD ("here")  ON_WORD   ("on")
  5805.  
  5806.      FILE_CHECK          for verifying writefile/readfile
  5807.                          operations
  5808.  
  5809.  
  5810. (The following are used only by specific routines:
  5811.  
  5812. ARRAYS:
  5813.  
  5814.      _temp_array[256]    used by string manipulation functions
  5815.      menuitem[11]        required by the Menu function
  5816.  
  5817. GLOBALS:
  5818.  
  5819.      MENU_TEXTCOLOR      normal menu text color
  5820.      MENU_BGCOLOR        normal menu background color
  5821.      MENU_SELECTCOLOR    menu highlight color
  5822.      MENU_SELECTBGCOLOR  menu highlight background color)
  5823.  
  5824.  
  5825. -----------------------------------------------------------------
  5826. PROPERTIES
  5827. -----------------------------------------------------------------
  5828.  
  5829. The first 6 properties are pre-defined by the compiler:
  5830.  
  5831.      name                     basic object name
  5832.      before                   pre-verb routines
  5833.      after                    post-verb routines
  5834.      noun (nouns)             noun(s) for referring to object
  5835.      adjective (adjectives)   adjective(s) describing object
  5836.      article                  "a", "an", "the", "some", etc.
  5837.  
  5838.      preposition (prep)       "in", "inside", "outside of", etc.,
  5839.                               used generally for room objects in 
  5840.                               order to give a grammatically
  5841.                               correct description if necessary;
  5842.                               also for containers and platforms
  5843.  
  5844.      pronoun                  "he", "him", "his" or equivalent, so
  5845.                               that an object is properly referred
  5846.                               to
  5847.  
  5848.      short_desc               routine; basic "X is here"
  5849.                               description
  5850.  
  5851.      initial_desc             routine; same as above, but if
  5852.                               object has not been moved and an
  5853.                               initial_desc exists, it is called in
  5854.                               place of short_desc
  5855.  
  5856.      long_desc                routine; detailed description
  5857.  
  5858.      found_in                 in case of multiple parents,
  5859.                               found_in may hold one or more object
  5860.                               numbers; in this case, an  IN
  5861.                               <object> specifier should not be
  5862.                               included in the object definition
  5863.  
  5864.      type                     to identify the type of object, used
  5865.                               primarily by class definitions in
  5866.                               OBJLIB.H
  5867.  
  5868.      size                     for holding/inventory purposes,
  5869.                               contains a value representing the
  5870.                               size of an individual object
  5871.  
  5872.      capacity                 contains a value representing the
  5873.                               capacity of a container or platform
  5874.  
  5875.      holding                  contains a value representing the
  5876.                               current encumbrance of a container 
  5877.                               or platform
  5878.  
  5879.      reach                    for enterable objects such as
  5880.                               chairs, vehicles, etc., if the
  5881.                               accessibility of objects outside the
  5882.                               object in question is limited, reach
  5883.                               contains a list of the objects which
  5884.                               may be accessed; if access is
  5885.                               limited to the object in question
  5886.                               only, reach must still contain at
  5887.                               least one non-false value (i.e. the
  5888.                               parent object itself)
  5889.  
  5890.      list_contents            a routine that overrides the normal
  5891.                               contents listing for a room or
  5892.                               object; normal listing is only
  5893.                               carried out if it returns false
  5894.  
  5895.      in_scope                 contains a list of actors or objects
  5896.                               to which the object is accessible
  5897.                               beyond the use of the object tree or
  5898.                               the found_in property; generally
  5899.                               contains either the player object
  5900.                               (or, less commonly, another
  5901.                               character) and is set or cleared
  5902.                               using PutInScope or RemoveFromScope
  5903.  
  5904.      parse_rank               when there is ambiguity between
  5905.                               similarly named objects, the parser
  5906.                               will choose the one with a higher
  5907.                               parse_rank over one with a lower (or
  5908.                               non-existant) value
  5909.  
  5910.      exclude_from_all         returns true if the object should be
  5911.                               excluded from actions such as "get
  5912.                               all"
  5913.  
  5914.      misc                     miscellaneous use
  5915.  
  5916.  
  5917. For room objects only:
  5918.  
  5919.      n_to                     If a player can move to another
  5920.      ne_to                    room object in direction X, then
  5921.      e_to                     X_to holds the new room object
  5922.      se_to
  5923.      s_to
  5924.      sw_to
  5925.      w_to 
  5926.      nw_to
  5927.      u_to 
  5928.      d_to 
  5929.      in_to
  5930.      out_to
  5931.  
  5932.      cant_go                  routine; message instead of default
  5933.                               "You can't go that way."
  5934.  
  5935.  
  5936. For non-room objects only:
  5937.  
  5938.      door_to                  for handling "Enter <object>", holds
  5939.                               the object number of the object to
  5940.                               which an object enters (where the
  5941.                               latter behaves as a door or portal)
  5942.  
  5943.      key_object               if lockable, contains the object
  5944.                               number of the key
  5945.  
  5946.      when_open                routines; short descriptions for
  5947.      when_closed              openable objects
  5948.                               
  5949.                               If they exist, the appropriate
  5950.                               when_open/when_closed routine is
  5951.                               called instead of short_desc (if an
  5952.                               initial_desc does not exist, or if 
  5953.                               the object has been moved)
  5954.  
  5955.      ignore_response          for characters, a routine that runs
  5956.                               if the character ignores a player's
  5957.                               question, request, etc., instead of
  5958.                               the default "X ignores you."
  5959.  
  5960.      order_response           also for characters, a routine that
  5961.                               processes an imperative command
  5962.                               addressed to the character by the
  5963.                               player; it should return false if no
  5964.                               response is provided
  5965.  
  5966.      contains_desc            a routine that prints the
  5967.                               introduction to a list of child
  5968.                               objects, instead of the default
  5969.                               "Inside <object> are..." or
  5970.                               "<character> has..."; contains_desc
  5971.                               should always conclude with a
  5972.                               semicolon (";") instead of a new
  5973.                               line
  5974.  
  5975.      inv_desc                 a routine that prints a special
  5976.                               description when the object is
  5977.                               listed as part of the player's
  5978.                               inventory; inv_desc should conclude
  5979.                               with a semicolon (";")
  5980.  
  5981.      desc_detail              a routine that prints a
  5982.                               parenthetical detail following an
  5983.                               object listing, such as:  " (which 
  5984.                               is open)"; the leading space is
  5985.                               expected, as are the parentheses,
  5986.                               and the print statement should
  5987.                               conclude with a semicolon (";")
  5988.  
  5989. NOTE:  It is recommended for property routines that print a
  5990. description--such as short_desc, initial_desc, etc.--that the
  5991. routine not simply return true without printing anything as a means
  5992. of "hiding" the object; such a method may throw text formatting into
  5993. disarray.  The proper means of omitting an object from a list is to
  5994. set the hidden attribute.
  5995.  
  5996.  
  5997. -----------------------------------------------------------------
  5998. ROUTINES
  5999. -----------------------------------------------------------------
  6000.  
  6001. VERB ROUTINES
  6002.  
  6003. HUGOLIB.H contains a fairly extensive set of basic actions, each of
  6004. which takes the form Do<verb>, so that the action for taking an
  6005. object is DoGet, the action for basic player movement is DoGo, etc.
  6006.  
  6007. Each is called by the engine when a grammar syntax line specifying
  6008. the particular verb routine is matched.  Globals object and xobject
  6009. are set up by the engine, and the routine is called with no
  6010. parameters.
  6011.  
  6012. Here is a list of the provided verb routines for action verbs:
  6013.  
  6014.      DoAsk, DoAskQuestion, DoClose, DoDrop, DoEat, DoEnter, DoExit,
  6015.      DoGet, DoGive, DoGo, DoHit, DoInventory, DoListen, DoLock,
  6016.      DoLook, DoLookAround, DoLookIn, DoLookThrough, DoLookUnder,
  6017.      DoMove, DoOpen, DoPutIn, DoShow, DoSwitchOff, DoSwitchOn,
  6018.      DoTakeOff, DoTalk, DoTell, DoUnlock, DoVague, DoWait,
  6019.      DoWaitforChar, DoWaitUntil, DoWear
  6020.  
  6021. Here are the non-action verb routines:
  6022.  
  6023.      DoBrief, DoQuit, DoRestart, DoRestore, DoSave, DoScore,
  6024.      DoScriptOnOff, DoSuperbrief, DoVerbose, 
  6025.  
  6026. (NOTE:  A set of verb stub routines is also available, including the
  6027. actions:
  6028.  
  6029.      DoBurn, DoClimb, DoCut, DoDig, DoHelp, DoJump, DoKiss, DoNo,
  6030.      DoPull, DoPush, DoSearch, DoSleep, DoSmell, DoSorry, DoSwim,
  6031.      DoThrowAt, DoTie, DoTouch, DoUntie, DoUse, DoWake,
  6032.      DoWakeCharacter, DoWave, DoWaveHands, DoYell, DoYes
  6033.  
  6034. The default response for each of these stub routines is a more
  6035. colorful variation of "Try something else."  Any more meaningful
  6036. response must be incorporated into before property routines.
  6037.  
  6038. To use these verbs, include the file VERBSTUB.G with the other
  6039. grammar files, and VERBSTUB.H after HUGOLIB.H.  HUGOLIB.H and
  6040. GRAMMAR.G do this automatically if the VERBSTUBS flag is set.)
  6041.  
  6042.  
  6043. UTILITY ROUTINES, ETC.
  6044.  
  6045. Routines may be treated as procedures or functions, given the idea
  6046. that procedures are more like commands, while functions are expected
  6047. to return a value, as in:
  6048.  
  6049.      Procedure(a, b)
  6050.      x = Function(y)
  6051.      if Function()...
  6052.  
  6053. Library routines that do not return a value are generally meant to
  6054. be treated as procedures; those that do return a value may be
  6055. treated as either functions or procedures.
  6056.  
  6057. First, the junction routines:
  6058.  
  6059.      EndGame        called by the engine via:
  6060.                     EndGame(end_type)
  6061.                     
  6062.                     If end_type = 1, the game is won; if 2, the
  6063.                     game is lost.  (Since endflag may be any value,
  6064.                     a value of, for example, 3 will still call
  6065.                     EndGame, but with no additional effects via the
  6066.                     default PrintEndGame routine.)  The global
  6067.                     endflag is cleared upon calling.  Returning
  6068.                     false from EndGame terminates the Hugo Engine.
  6069.  
  6070.                     Also calls:  PrintEndGame and PrintScore
  6071.  
  6072.      FindObject     called by the engine via:
  6073.                     FindObject(object, location)
  6074.  
  6075.                     Returns true (1) if the specified object is
  6076.                     available in the specified location, or false
  6077.                     (0) if it is not.  Returns 2 if the object is
  6078.                     visible but not physically accessible.
  6079.  
  6080.                     Also calls:  ObjectisKnown, ExcludeFromAll
  6081.  
  6082.      Parse          called by the engine via:
  6083.                     Parse()
  6084.  
  6085.                     Returning true forces the engine to re-parse 
  6086.                     the modified input line.
  6087.  
  6088.                     Also calls:  PreParse, AssignPronoun and
  6089.                     SetObjWord
  6090.  
  6091.      ParseError     called by the engine via:
  6092.                     ParseError(errornumber, object)
  6093.  
  6094.                     Returning false signals the engine to print the
  6095.                     default error message
  6096.  
  6097.                     May also call:  CustomError
  6098.  
  6099.      SpeakTo        called by the engine via:
  6100.                     SpeakTo(character)
  6101.  
  6102.                     Globals object, xobject, and verbroutine are 
  6103.                     set up as in a normal verb routine call.
  6104.  
  6105.                     Also calls:  AssignPronoun
  6106.  
  6107.  
  6108. And the routines for grammatically-correct printing:
  6109.  
  6110.      The            calling form:  The(object)
  6111.  
  6112.                     Prints the definite article form of the object
  6113.                     name, e.g. "the apple"
  6114.  
  6115.      Art            calling form:  Art(object)
  6116.  
  6117.                     Prints the indefinite article form of the
  6118.                     object name, e.g. "an apple"
  6119.  
  6120.      CThe           calling form:  CThe(object)
  6121.  
  6122.                     Prints the capitalized definite article form 
  6123.                     of the object name, e.g. "The apple"
  6124.  
  6125.      CArt           calling form:  CArt(object)
  6126.  
  6127.                     Prints the capitalized indefinite article form
  6128.                     of the object name, e.g. "An apple"
  6129.  
  6130.      IsorAre        calling form:  IsorAre(object[, formal])
  6131.                     where the parameter formal is optional
  6132.  
  6133.                     Depending on whether or not the specified
  6134.                     object is plural or singular, prints "'re" or
  6135.                     "'s", respectively (or " are" or " is" if the
  6136.                     formal parameter is specified as true).
  6137.  
  6138.      MatchPlural    calling form:  MatchPlural(object, w1, w2)
  6139.  
  6140.                     Prints the dictionary entry given by w1 if the
  6141.                     supplied object is not plural, or w2 if it is.
  6142.  
  6143.      MatchSubject   calling form:  MatchSubject(object)
  6144.  
  6145.                     Matches a verb to the given subject <object>. 
  6146.                     If the object is plural, nothing is printed; 
  6147.                     if the object is singular, an "s" is printed.
  6148.  
  6149.      NOTE:  None of the above printing routines prints a carriage
  6150.      return, and all return 0 (the null string).  Therefore, either
  6151.      of the following usages are valid:
  6152.  
  6153.           CThe(apple)
  6154.           print " is here."
  6155.  
  6156.      or
  6157.  
  6158.           print CThe(apple); " is here."
  6159.  
  6160.  
  6161. Other routines:
  6162.  
  6163.      Acquire             calling form:
  6164.                          Acquire(parent, object)
  6165.  
  6166.                          Checks to see if parent.capacity is
  6167.                          greater than or equal to parent.holding 
  6168.                          plus object.size.  If so, it moves object
  6169.                          to the specified parent, and returns true. 
  6170.                          If the object cannot be moved, Acquire
  6171.                          returns false.
  6172.  
  6173.                          Also calls:  CalculateHolding
  6174.  
  6175.      AnyVerb             calling form:
  6176.                          AnyVerb(object)
  6177.  
  6178.                          Returns object if the current verbroutine
  6179.                          is not an xverb; otherwise it returns
  6180.                          false. 
  6181.  
  6182.      AssignPronoun       calling form:
  6183.                          AssignPronoun(object)
  6184.  
  6185.                          Sets the appropriate global it_obj,
  6186.                          them_obj, him_obj, or her_obj to the
  6187.                          specified object.
  6188.  
  6189.      CalculateHolding    calling form:
  6190.                          CalculateHolding(object)
  6191.  
  6192.                          Properly recalculates object.holding based
  6193.                          on the sizes of all held objects.
  6194.  
  6195.      CenterTitle         calling form:
  6196.                          CenterTitle(text)
  6197.  
  6198.                          Clears the screen and centers the text
  6199.                          given by the specified dictionary entry 
  6200.                          in the top window.
  6201.  
  6202.      CheckReach          calling form:
  6203.                          CheckReach(object)
  6204.  
  6205.                          Checks to see if the specified object is
  6206.                          within reach of the player object. 
  6207.                          Returns true if accessible; returns
  6208.                          false--and prints an appropriate
  6209.                          message--if not.    
  6210.  
  6211.      Contains            calling form:
  6212.                          Contains(parent, object)
  6213.  
  6214.                          Returns <object> if the specified object
  6215.                          is present as a possession of the
  6216.                          specified parent, even as a grandchild.
  6217.  
  6218.      CustomError         calling form:
  6219.                          CustomError(errornumber, object)
  6220.  
  6221.                          REPLACE if custom error messages are
  6222.                          desired.  Is called by ParseError whenever
  6223.                          errornumber is greater than or equal to
  6224.                          100, specifying a user parser error. 
  6225.                          Should return false if no user message is
  6226.                          found.
  6227.  
  6228.      DarkWarning         calling form:
  6229.                          DarkWarning
  6230.  
  6231.                          Is called by MovePlayer whenever the
  6232.                          player object is moved into a location
  6233.                          without a light source.  The default
  6234.                          library routine simply prints a message;
  6235.                          for a more sinister response, such as the
  6236.                          death of the player, REPLACE the default
  6237.                          with a new DarkWarning routine.
  6238.  
  6239.      DeleteWord          calling form:
  6240.                          DeleteWord(wordnumber[, number])
  6241.  
  6242.                          Deletes the number of words given by the
  6243.                          second argument--or only one word if no 
  6244.                          second argument is given--starting with 
  6245.                          word[wordnumber].  Returns the number of
  6246.                          words deleted.
  6247.  
  6248.      DescribePlace       calling form:
  6249.                          DescribePlace(location[, long])
  6250.  
  6251.                          Prints the location name and, when
  6252.                          appropriate, a location description. 
  6253.                          Including a non-false long parameter will
  6254.                          force a location description.
  6255.  
  6256.      ExcludeFromAll      calling form:
  6257.                          ExcludeFromAll(object)
  6258.  
  6259.                          Returns true if, based on the current
  6260.                          circumstances (verbroutine, etc.), the
  6261.                          supplied object should be excluded from
  6262.                          actions using "all"--such as multi,
  6263.                          multiheld, and multinotheld grammar
  6264.                          tokens.
  6265.  
  6266.      FindLight           calling form:
  6267.                          FindLight(location)
  6268.  
  6269.                          Checks to see if a light source is
  6270.                          available in the player's location; if so,
  6271.                          it sets the global light_source to the
  6272.                          object number of the source and returns
  6273.                          that value.
  6274.  
  6275.                          Also calls:  ObjectIsLight
  6276.  
  6277.      Font                calling form:
  6278.                          Font(bitmask)
  6279.  
  6280.                          Sets the current font attributes as
  6281.                          specified by bitmask, where bitmask is one
  6282.                          or more font-style constants (see library
  6283.                          constants, above) combined with "|" or
  6284.                          "+".
  6285.  
  6286.      GetInput            calling form:
  6287.                          GetInput([prompt string])
  6288.  
  6289.                          Receives input from the keyboard, storing
  6290.                          individual words in the word array;
  6291.                          unknown words--i.e. those that are not in
  6292.                          the dictionary--are assigned the null
  6293.                          string, 0 or "".  If an argument is
  6294.                          passed, it is assumed to be a dictionary
  6295.                          address for the prompt string.  If no
  6296.                          argument is passed, no prompt is printed.
  6297.  
  6298.      HoursMinutes        calling form:
  6299.                          HoursMinutes(counter)
  6300.  
  6301.                          Prints the time in hh:mm format given that
  6302.                          the global counter represents the time in
  6303.                          minutes from 12:00 a.m.
  6304.  
  6305.      Indent              calling form:
  6306.                          Indent
  6307.  
  6308.                          If the NOINDENT_F bit is not set in the 
  6309.                          FORMAT mask, Indent prints two spaces
  6310.                          without printing a newline
  6311.  
  6312.      InList              calling form:
  6313.                          InList(object, property, value)
  6314.  
  6315.                          If <value> is in the list of values held
  6316.                          in <object>.<property>, returns the number
  6317.                          of the (first) property element equal to
  6318.                          <value>; otherwise returns 0.
  6319.  
  6320.      InsertWord          calling form:
  6321.                          InsertWord(wordnumber[, number])
  6322.  
  6323.                          Makes space for either the number of words
  6324.                          given by the number argument--or one word
  6325.                          if no second argument is given--if
  6326.                          possible, at word[wordnumber], shifting
  6327.                          upward all words from that point to the
  6328.                          end of the input line.  Returns the number
  6329.                          of words inserted.
  6330.  
  6331.      ListObjects         calling form:
  6332.                          ListObjects(object)
  6333.  
  6334.                          Lists all the possessions of the specified
  6335.                          object in the appropriate form (according
  6336.                          to the global FORMAT).  Possessions of
  6337.                          possessions are listed recursively if
  6338.                          FORMAT does not contain the NORECURSE_F
  6339.                          bit.  Format masks are combined, as in:
  6340.  
  6341.                          FORMAT = LIST_F | NORECURSE_F | ...
  6342.  
  6343.                          Also calls:  WhatsIn
  6344.  
  6345.      Menu                calling form:
  6346.                          Menu(number, [width])
  6347.  
  6348.                          Prints a menu, given that the possible
  6349.                          choices (up to 10) are contained in the 
  6350.                          menuitem array, with menuitem[0] is the 
  6351.                          title of the menu.  Returns the number of
  6352.                          the item selected, or 0 if none is chosen.
  6353.  
  6354.                          Also calls:  CenterTitle
  6355.  
  6356.      Message             calling form:
  6357.                          Message(&routine, num, a, b)
  6358.  
  6359.                          Used by most routines in HUGOLIB.H for
  6360.                          text output, so that the bulk of the
  6361.                          library text is centralized in one
  6362.                          location.  Message number num for the
  6363.                          specified routine is printed; a and b are
  6364.                          optional parameters that may represent
  6365.                          objects, dictionary entries, or any other
  6366.                          value.
  6367.  
  6368.      MovePlayer          calling form:
  6369.                          MovePlayer(location[, silent[, none]])
  6370.                          MovePlayer(direction[, silent[, none]])
  6371.  
  6372.                          Moves the player to the new location,
  6373.                          properly setting all relevant variables 
  6374.                          and attributes.  If <silent> is specified
  6375.                          (as a true value), no room description is
  6376.                          printed following the move.
  6377.  
  6378.                          A direction object (i.e. n_obj, d_obj) may
  6379.                          be specified instead of a location; in
  6380.                          this instance, MovePlayer moves in that
  6381.                          direction from the player object's present
  6382.                          location.
  6383.  
  6384.                          If <none> is true, before/after routines
  6385.                          are not run.
  6386.  
  6387.                          Can be checked in a location's before or
  6388.                          after property as "location MovePlayer" to
  6389.                          catch a player's exit from or entrance to
  6390.                          a location.
  6391.  
  6392.                          Returns the object number of the player 
  6393.                          object's new parent.
  6394.  
  6395.                          NOTE:  MovePlayer does not check to see 
  6396.                          if a move is valid; that must be done
  6397.                          before calling the routine.
  6398.  
  6399.                          May also call:  DarkWarning
  6400.  
  6401.      NumberWord          calling form:
  6402.                          NumberWord(number[, true])
  6403.  
  6404.                          Prints a number in non-numerical word
  6405.                          format, where <number> is between -32767
  6406.                          to 32767.  Always returns 0 (the null
  6407.                          string).  If a second (true) argument is
  6408.                          supplied, the word is capitalized.
  6409.  
  6410.      ObjectIs            calling form:
  6411.                          ObjectIs(object)
  6412.  
  6413.                          Lists certain attributes, such as
  6414.                          providing light or being worn, of the
  6415.                          given object in parenthetical form.
  6416.  
  6417.      ObjectisKnown       calling form:
  6418.                          ObjectisKnown(object)
  6419.  
  6420.                          Returns true if the object is known to the
  6421.                          player.
  6422.  
  6423.      ObjectisLight       calling form:
  6424.                          ObjectisLight(object)
  6425.  
  6426.                          Returns true if the object or one of its
  6427.                          visible possessions is providing light. 
  6428.                          If so, it also sets the global
  6429.                          light_source the object number of the
  6430.                          source.
  6431.  
  6432.      ObjWord             calling form:
  6433.                          ObjWord(word, object)
  6434.  
  6435.                          Returns either adjective or noun (i.e. the
  6436.                          property number) if the given is either an
  6437.                          adjective or noun of the specified object.
  6438.  
  6439.      Perform             calling form:
  6440.                          Perform(&routine, [object], [xobject])
  6441.  
  6442.                          Sets the verbroutine global (as well as 
  6443.                          object and xobject, if specified), and
  6444.                          then calls the routine.  Calls before and
  6445.                          after routines in accordance with the game
  6446.                          loop.  Returns the value returned by the
  6447.                          routine, after resetting verbroutine,
  6448.                          object, and xobject to their previous
  6449.                          values.
  6450.  
  6451.      PreParse            calling form:
  6452.                          PreParse
  6453.  
  6454.                          Provided so that, if needed, this routine
  6455.                          may be REPLACED instead of the more
  6456.                          extensive library Parse routine.  The
  6457.                          default routine defined in the library is
  6458.                          empty.
  6459.  
  6460.      PrintEndGame        calling form:
  6461.                          PrintEndGame(end_type)
  6462.  
  6463.                          Depending on whether end_type is 1 or 2,
  6464.                          prints "*** YOU'VE WON THE GAME! ***" or
  6465.                          "*** YOU ARE DEAD ***".
  6466.  
  6467.      PrintScore          calling form:
  6468.                          PrintScore(end_of_game)
  6469.  
  6470.                          Prints the score in the appropriate form,
  6471.                          depending on whether or not end_of_game is
  6472.                          true.
  6473.                          
  6474.      PrintStatusLine     calling form:
  6475.                          PrintStatusLine
  6476.  
  6477.                          Prints the status line in the appropriate
  6478.                          format, according to the global
  6479.                          STATUSTYPE.
  6480.  
  6481.      PropertyList        calling form:
  6482.                          PropertyList(obj, property)
  6483.  
  6484.                          Lists the objects held in obj.property (if
  6485.                          any), returning the number of objects
  6486.                          listed.
  6487.  
  6488.      PutInScope          calling form:
  6489.                          PutInScope(object, actor)
  6490.  
  6491.                          Makes <object> accessible to <actor>,
  6492.                          regardless of their respective locations,
  6493.                          and providing that the in_scope property
  6494.                          of <object> has at least one empty
  6495.                          slot--i.e. one that equals 0.  Returns
  6496.                          true if successful.
  6497.  
  6498.      RemoveFromScope     calling form:
  6499.                          RemoveFromScope(object, actor)
  6500.  
  6501.                          Removes <object> from the scope of
  6502.                          <actor>.  Returns true if successful, or
  6503.                          false if <object> was never in scope of 
  6504.                          <actor> to begin with.
  6505.  
  6506.      SetObjWord          calling form:
  6507.                          SetObjWord(position, object)
  6508.  
  6509.                          Inserts the specified object in the word
  6510.                          array in the format:
  6511.                          "adjective1 adjective2...noun"
  6512.  
  6513.      ShortDescribe       calling form:
  6514.                          ShortDescribe(object)
  6515.  
  6516.                          Prints the short description of the given
  6517.                          object, first checking to see if it should
  6518.                          run initial_desc, when_open, or
  6519.                          when_closed, as appropriate.  Then, if no
  6520.                          short_desc property exists, it prints a
  6521.                          default "X is here."
  6522.  
  6523.                          Also calls:  WhatsIn
  6524.  
  6525.      SpecialDesc         calling form:
  6526.                          SpecialDesc(object)
  6527.  
  6528.                          Checks each child object of <object>,
  6529.                          running any appropriate initial_desc or 
  6530.                          inv_desc property routines.  Sets the
  6531.                          global variable list_count to the number
  6532.                          of remaining (i.e. non-listed) objects.
  6533.  
  6534.      WhatsIn             calling form:
  6535.                          WhatsIn(parent)
  6536.  
  6537.                          Lists the possessions of the specified
  6538.                          parent, according the form given by the 
  6539.                          global FORMAT.  Returns the number of
  6540.                          objects listed.
  6541.  
  6542.                          Also calls:  SpecialDesc, ListObjects
  6543.  
  6544.  
  6545.      YesorNo             calling form:
  6546.                          YesorNo
  6547.  
  6548.                          Checks to see if the just-received input
  6549.                          is "yes", "y", "no", or "n".  If none of
  6550.                          the above, it prompts for a yes or no
  6551.                          answer.  Once a valid answer is received,
  6552.                          it returns true (if yes) or false (if no).
  6553.  
  6554.  
  6555. AUXILIARY MATH ROUTINES
  6556.  
  6557.      higher              calling form:
  6558.                          higher(a, b)
  6559.  
  6560.                          Returns the higher number of <a> or <b>.
  6561.  
  6562.      lower               calling form:
  6563.                          lower(a, b)
  6564.  
  6565.                          Returns the lower number of <a> or <b>.
  6566.  
  6567.      mod                 calling form:
  6568.                          mod(a, b)
  6569.  
  6570.                          Returns the remainder of <a> divided by 
  6571.                          <b>.
  6572.  
  6573.      pow                 calling form:
  6574.                          pow(a, b)
  6575.  
  6576.                          Returns <a> to the power of <b>.  (The
  6577.                          return value is unpredictable if the
  6578.                          result is outside the boundary of -32767
  6579.                          to 32767.)
  6580.  
  6581.  
  6582. STRING ARRAY ROUTINES
  6583.  
  6584.      StringCompare       calling form:
  6585.                          StringCompare(array1, array2)
  6586.  
  6587.                          Returns 1 if <array1> is lexically greater
  6588.                          than <array2>, -1 if <array1> is lexically
  6589.                          less than <array2>, and 0 if the strings
  6590.                          are identical.
  6591.  
  6592.      StringCopy          calling form:
  6593.                          StringCopy(new, old[, len])
  6594.  
  6595.                          Copies the contents of the array at the 
  6596.                          address given by <old> to the array at
  6597.                          <new>, to a maximum of <len> characters 
  6598.                          if <len> is given, or the length of <old>
  6599.                          if it isn't.
  6600.  
  6601.      StringDictCompare   calling form:
  6602.                          StringDictCompare(array, dictentry)
  6603.  
  6604.                          Performs a StringCompare-like comparison
  6605.                          of a string array given by <array> and the
  6606.                          dictionary entry <dictentry>, returning 1,
  6607.                          -1, or 0 if <array> is lexically greater
  6608.                          than, less than, or equal to <dictentry>,
  6609.                          respectively.
  6610.  
  6611.      StringEqual         calling form:
  6612.                          StringEqual(array1, array2)
  6613.  
  6614.                          Returns true only if <array1> and <array2>
  6615.                          are identical.
  6616.  
  6617.      StringLength        calling form:
  6618.                          StringLength(array)
  6619.  
  6620.                          Returns the length of the string stored 
  6621.                          as <array>.
  6622.  
  6623.      StringPrint         calling form:
  6624.                          StringPrint(array[, start, end])
  6625.  
  6626.                          Prints the string stored as <array>,
  6627.                          beginning with <start> and ending with
  6628.                          <end> if given.
  6629.  
  6630.  
  6631. FUSE/DAEMON ROUTINES
  6632.  
  6633.      (See the earlier section on fuses and daemons for more
  6634.      information.)
  6635.  
  6636.      Activate            calling form:
  6637.                          Activate(object[, setting])
  6638.  
  6639.                          Activates the specified fuse or daemon
  6640.                          object.  The setting value is only
  6641.                          specified for fuses, where it represents
  6642.                          the initial value of the timer property.
  6643.  
  6644.      Deactivate          calling form:
  6645.                          Deactivate(object)
  6646.  
  6647.                          Deactivates the specified fuse or daemon
  6648.                          object.
  6649.  
  6650.  
  6651. CHARACTER SCRIPT ROUTINES
  6652.  
  6653.      (See the earlier section on character scripts for more
  6654.      information.)
  6655.  
  6656.      CancelScript        calling form:
  6657.                          CancelScript(character)
  6658.  
  6659.                          Immediately cancels the character script
  6660.                          associated with the object <character>. 
  6661.                          Returns true if successful, i.e. if a
  6662.                          script for <character> is found.
  6663.  
  6664.      PauseScript         calling form:
  6665.                          PauseScript(character)
  6666.  
  6667.                          Temporarily pauses the character script 
  6668.                          associated with the object <character>. 
  6669.                          Returns true if successful.
  6670.  
  6671.      ResumeScript        calling form:
  6672.                          ResumeScript(character)
  6673.  
  6674.                          Resumes execution of a paused script. 
  6675.                          Returns true if successful.
  6676.  
  6677.      SkipScript          calling form:
  6678.                          SkipScript(character)
  6679.  
  6680.                          Skips execution of the script for
  6681.                          <character> during the next call to
  6682.                          RunScripts only.
  6683.  
  6684.      Script              calling form:
  6685.                          Script(character, steps)
  6686.  
  6687.                          Initializes space for the requested number
  6688.                          of steps in the setscript array, sets up
  6689.                          the data for the script in the scriptdata
  6690.                          array, and returns the location of the
  6691.                          script in setscript.  Returns -1 if
  6692.                          MAX_SCRIPTS is exceeded.
  6693.  
  6694.      RunScripts          calling form:
  6695.                          RunScripts
  6696.  
  6697.                          Runs all active scripts, calling them in
  6698.                          the form:
  6699.  
  6700.                               CharRoutine(character, object)
  6701.  
  6702.  
  6703. CHARACTER ACTION ROUTINES
  6704.  
  6705. As a starting point, the library also provides a limited number of
  6706. routines for character objects to use in scripts.  They are:
  6707.  
  6708.      &CharWait, 0
  6709.  
  6710.      &CharMove, direction_object (requires OBJLIB.H)
  6711.  
  6712.      &CharGet, object
  6713.  
  6714.      &CharDrop, object
  6715.  
  6716. and
  6717.  
  6718.      &LoopScript, 0
  6719.  
  6720.  
  6721. -----------------------------------------------------------------
  6722. CONDITIONAL COMPILATION
  6723. -----------------------------------------------------------------
  6724.  
  6725. A number of compiler flags may be set which exclude certain portions
  6726. of HUGOLIB.H from compilation if these functions or objects are not
  6727. required.
  6728.  
  6729.      FLAG:               EXCLUDES:
  6730.  
  6731.      NO_AUX_MATH         Auxiliary math routines
  6732.      NO_FUSES            Fuses AND daemons
  6733.      NO_MENUS            Use of the Menu function
  6734.      NO_OBJLIB           OBJLIB.H
  6735.      NO_RECORDING        Command recording functions
  6736.      NO_SCRIPTS          Character scripting routines
  6737.      NO_STRING_ARRAYS    String array functions
  6738.      NO_VERBS            All action verbs
  6739.      NO_XVERBS           All non-action verbs
  6740.  
  6741.  
  6742.  
  6743. -----------------------------------------------------------------
  6744. APPENDIX C:  LIMIT SETTINGS
  6745. -----------------------------------------------------------------
  6746.  
  6747. NOTE:  The default settings for the complete set of limits may be
  6748. obtained by invoking the compiler via:
  6749.  
  6750.      hc $list
  6751.  
  6752. (The following limits are static and non-modifiable, since they
  6753. reflect the internal configuration of the Hugo Engine:
  6754.  
  6755.      MAXATTRIBUTES       The maximum number of definable
  6756.                          attributes, not counting aliases
  6757.  
  6758.      MAXGLOBALS          The maximum number of definable global
  6759.                          variables
  6760.  
  6761.      MAXLOCALS           The maximum number of local variables
  6762.                          allowed in a routine, including arguments
  6763.                          passed to the routine)
  6764.  
  6765. The following are the modifiable settings, which may be setting
  6766. using:
  6767.  
  6768.      $<setting>=<new limit>
  6769.  
  6770. either in the invocation line or in the source code.
  6771.  
  6772.      MAXALIASES          The maximum number of aliases that may be
  6773.                          defined for attributes and/or properties
  6774.  
  6775.      MAXARRAYS           The maximum number of arrays that may be
  6776.                          defined (not the total array space, which
  6777.                          is automatically reserved)
  6778.  
  6779.      MAXCONSTANTS        The maximum number of constants
  6780.  
  6781.      MAXDICT             The maximum number of entries that the
  6782.                          compiler can enter into the dictionary
  6783.                          table
  6784.  
  6785.      MAXDICTEXTEND       The total number of bytes (not the total
  6786.                          number of entries) available for dynamic
  6787.                          dictionary extension during runtime
  6788.  
  6789.      MAXEVENTS           The maximum number of global or object-
  6790.                          linked events
  6791.  
  6792.      MAXFLAGS            The maximum number of compiler flags that
  6793.                          may be set at one time to control
  6794.                          conditional compilation
  6795.  
  6796.      MAXLABELS           The maximum number of labels that may be
  6797.                          defined in an entire program
  6798.  
  6799.      MAXOBJECTS          The maximum number of objects and/or
  6800.                          classes that may be created
  6801.  
  6802.      MAXPROPERTIES       The maximum number of properties that may
  6803.                          be defined
  6804.  
  6805.      MAXROUTINES         The maximum number of stand-alone routines
  6806.                          (not property routines) that may be
  6807.                          defined
  6808.  
  6809.  
  6810.  
  6811. -----------------------------------------------------------------
  6812. APPENDIX D:  PRECOMPILED HEADERS
  6813. -----------------------------------------------------------------
  6814.  
  6815. It is possible to compile files that would normally be included
  6816. using the #include directive into a precompiled header file that may
  6817. be linked using #link, as in:
  6818.  
  6819.      #link "<filename.HLB>"
  6820.  
  6821. The advantage of doing this is primarily one of faster compilation
  6822. speed; files that are used over and over again without alteration
  6823. (such as HUGOLIB.H) may be precompiled so that they are not
  6824. recompiled every time.
  6825.  
  6826. The #link directive must come after any grammar, but before any
  6827. definitions of attributes, properties, globals, objects, synonyms,
  6828. etc.  Grammar is illegal in a precompiled header.
  6829.  
  6830. To create a precompiled header, use the -h directive when invoking
  6831. the Hugo Compiler.  The file HUGOLIB.HUG serves as a good example. 
  6832. Compile it via
  6833.  
  6834.      hc -h hugolib.hug
  6835.  
  6836. in order to generate HUGOLIB.HLB.
  6837.  
  6838. Next, change occurrences of
  6839.  
  6840.      #include "hugolib.h"
  6841.  
  6842. in Hugo programs to 
  6843.  
  6844.      #link "hugolib.hlb"
  6845.  
  6846. Change the definition for the main routine from
  6847.  
  6848.      routine main
  6849.      {...
  6850.  
  6851. to
  6852.  
  6853.      replace main
  6854.      {...
  6855.  
  6856. since HUGOLIB.HUG contains a temporary main routine.
  6857.  
  6858. NOTE:  Any conditional compilation flags set in the Hugo program
  6859. will have no effect on the compiled code in HUGOLIB.HLB, since the
  6860. routines included in or excluded from HUGOLIB.HLB are determined by
  6861. the flags set in HUGOLIB.HUG.  It is recommended that a Hugo user
  6862. using precompiled headers compile a version of HUGOLIB.HUG that
  6863. includes HUGOFIX.H and/or VERBSTUB.H as desired.
  6864.  
  6865. It is generally not possible to include multiple precompiled .HLB
  6866. headers compiled in separate passes via subsequent #links in the
  6867. same source file.  Because of the absolute references assigned to
  6868. data such as dictionary addresses, attribute numbers, etc., such an
  6869. attempt will produce an "Incompatible precompiled headers" error.
  6870.  
  6871. However, for games that are composed of separate sections that can
  6872. be combined into distinct files, it may make sense to precompile one
  6873. .HUG file containing all the common elements that will be used by
  6874. the separate sections--such as the player object, etc.--and which
  6875. #includes or #links the library in it.  Then, this new .HLB file can
  6876. be #linked in each of the separate sections during development and
  6877. testing.  Of course, each of the separate sections will have to be
  6878. #included in a single master file for building the full release
  6879. version.
  6880.  
  6881. Finally, it is advisable that precompiled headers be used only in
  6882. building .HEX files during the design/testing stage in order to
  6883. facilitate faster development.  The reason is that the linker does
  6884. not selectively include routine calls; the entire .HLB file is
  6885. loaded during the link phase.  As a result, Hugo files produced
  6886. using precompiled headers--especially if existing routines in the
  6887. .HLB file are replaced in the source--tend to be larger and
  6888. therefore less economical in their memory usage.  For this reason,
  6889. it is recommended that #include be used for building release
  6890. versions instead of #linking the corresponding precompiled header.
  6891.  
  6892.  
  6893.  
  6894. -----------------------------------------------------------------
  6895. APPENDIX E:  THE HUGO DEBUGGER
  6896. -----------------------------------------------------------------
  6897.  
  6898. The Hugo Debugger is a valuable part of the Hugo design system.  It
  6899. allows a programmer to monitor all aspects of program execution,
  6900. including watching expressions, modifying values, moving objects,
  6901. etc.--all things expected of a modern source-level debugger.
  6902.  
  6903. The Hugo Debugger is not technically a source-level debugger,
  6904. however.  During its development, its author has referred to it as
  6905. a source(ish) level debugger--what the debugger does, in effect, is
  6906. to "decompile" compiled code into the tokens and symbols that
  6907. comprise each line of code.
  6908.  
  6909. In order to be used with the debugger, a Hugo program must be
  6910. compiled using the -d switch in order to create an .HDX debuggable
  6911. file with additional data such as names for objects, variables,
  6912. properties, etc.
  6913.  
  6914. (Note that .HDX files can be run by the engine, but .HEX files
  6915. cannot be run by the debugger because of the additional data
  6916. required.)
  6917.  
  6918. The MS-DOS convention for running the debugger is
  6919.  
  6920.      hd <filename>
  6921.  
  6922. The debugger will begin on the debugging screen.  Switch back-and-
  6923. forth from the actual game screen by pressing TAB.
  6924.  
  6925. At this point, it is probably best to select "Shortcut Keys" from
  6926. the Help menu, since the actual keystrokes for running the debugger
  6927. may vary from system to system.  (It is possible to operate the
  6928. debugger entirely through menus, but this soon becomes tedious for
  6929. operations like stepping line-by-line.)
  6930.  
  6931. The file HDHELP.HLP should be in the same directory as HD.EXE--this
  6932. is the online help file for the debugger, containing information on
  6933. such things as:
  6934.  
  6935.      Printing
  6936.  
  6937.      Windows and Views, including
  6938.           Code Window
  6939.           Watch Window
  6940.           Calls
  6941.           Breakpoints
  6942.           Local Variables
  6943.           Property/Attribute Aliases
  6944.           Auxiliary Window
  6945.           Output
  6946.  
  6947.      Running a program
  6948.           Finish Routine
  6949.           Stepping Through Code
  6950.           Skipping Over Code
  6951.           Stepping Backward
  6952.  
  6953.      Searching Code
  6954.      Watch Expressions
  6955.      Setting or Modifying Values
  6956.      Breakpoints
  6957.      Object Tree
  6958.      Moving Objects
  6959.  
  6960.      Setup
  6961.  
  6962.  
  6963.  
  6964. -----------------------------------------------------------------
  6965. Hugo Compiler, Engine, Debugger, Library, and the Hugo Manual
  6966.  
  6967. Copyright (c) 1995-1997 by Kent Tessman
  6968. -----------------------------------------------------------------