home *** CD-ROM | disk | FTP | other *** search
/ Freelog 16 / Freelog016.iso / BeOS / Hugo / manual.txt < prev   
Text File  |  2000-11-05  |  209KB  |  7,643 lines

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