home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / gags.zip / PART3.DOC < prev    next >
Text File  |  1985-08-24  |  22KB  |  429 lines

  1.                                       3-1
  2.  
  3.       The Generic Adventure Game System
  4.       Copyright 1985 by Mark J. Welch
  5.  
  6.  
  7.  
  8.       The GAGS source code (briefly explained, not included)
  9.       --------------------
  10.       
  11.       [ The GAGS source code is available to registered users of GAGS 
  12.         for $25; source code purchasers must also sign an agreement not 
  13.         to distribute or share the source code. For information, 
  14.         contact Mark J. Welch. ] 
  15.       
  16.       The Generic Adventure Game System is broken into fourteen 
  17.       "modules," each structured as a Turbo Pascal "include" file.  
  18.       Initially, the entire program was in one source code file. The 
  19.       tremendous size of the parser led to its being broken out as a 
  20.       separate module. Soon, other groups of procedures were also 
  21.       removed from the main program file so that I could edit and print 
  22.       smaller pieces at a time, and so that Turbo could handle the 
  23.       files (Turbo Pascal can only process files up to 64K).  
  24.            As my Programming Methodology professor pointed out four 
  25.       years ago, it is also much easier to track down bugs when you 
  26.       only modify one module at a time. Naturally, I should've started 
  27.       the project by defining the separate modules, and I should have 
  28.       drawn out pseudo-code, so that the program was better structured. 
  29.       These bad habits might explain the 'C' I got in that class....  
  30.  
  31.            The twelve modules are: 
  32.  
  33.       -- the parser (PARSE.MOD); 
  34.       -- the execution module (EXECUTE.MOD) which interprets the 
  35.       user's parsed command line, with three sub-modules EXECSUBS.MOD,
  36.       SPECIALS.MOD, and SAVEREST.MOD; 
  37.       -- the initialization module (INIT.MOD), which zeros out all 
  38.       the arrays and reads the data file;
  39.       -- the declaration module (DECLARE.MOD), which contains all the 
  40.       global type, constant, and variable  declarations;
  41.       -- a command-line parameter checking module (PARAM.MOD);
  42.       -- a title-printing module (TITLE.MOD) which also contains 
  43.       several useful tools; 
  44.       -- a creature-animation module (ANIMATE.MOD), which executes 
  45.       any actions creatures take (i.e. attacking the player);
  46.       -- two tools modules (GENTOOLS.MOD and SPCTOOLS.MOD) which contain 
  47.       procedures and functions used by more than one other module;
  48.       -- a module to describe and list the player's location 
  49.       information (DESCRIBE.MOD);
  50.       -- and the main program (ADVENT.PAS) which INCLUDEs the other 
  51.       modules. 
  52.       
  53.                                       3-2
  54.       
  55.       Summary:
  56.       
  57.       The parser is quite straightforward: it takes a command line 
  58.       string, and breaks it into words; it massages the words, tries to 
  59.       eliminate unimportant words, throws away adjectives if they match 
  60.       following nouns, and locate from one to four important sentence 
  61.       elements: a verb, a noun, a preposition, and an object of the 
  62.       preposition. These are passed back to the main program.  
  63.            The main program immediately 'executes' the user's 
  64.       deciphered command (unless a syntax error was discovered in the 
  65.       parser); the execute module simply decides which verb was used 
  66.       and calls the procedure appropriate to that verb or class of 
  67.       verbs.  
  68.      
  69.            Whenever a change is made to the program, several modules 
  70.       must usually be changed. For example, to add a new field to nouns 
  71.       (say, 'NUKEABLE'), the declaration of the nouns record must be 
  72.       changed to add the field; the initialization procedure must 
  73.       assign it a default value ('true'?) and must also check to see if 
  74.       the noun declaration in the data file changes its 'default' 
  75.       value; and any appropriate changes must also be made to the 
  76.       execute module. In this case, the logical intent would be to also 
  77.       add a verb 'NUKE' and of course also add a procedure in the 
  78.       execute module called 'nuke' with a parameter of what noun to 
  79.       destroy. That verb would have to be added in the initialization 
  80.       module (INIT_VERBS procedure) so the parser recognizes it; and an 
  81.       appropriate check would be made in the nuke procedure to see if 
  82.       conditions are met. Nuke might activate a special, which means 
  83.       the nuke procedure would call the 'special' procedure if the 
  84.       proper conditions are met. 
  85.  
  86.  
  87.  
  88.                                       3-3
  89.  
  90.       GAGS - A Generic Adventure Game System 
  91.       Copyright 1985 by Mark Welch
  92.  
  93.       --------------------------
  94.       In More Detail: The Parser
  95.       --------------------------
  96.          Definition: The PARSER examines each word in an input sentence 
  97.       to determine whether it is a valid part of speech in the context of 
  98.       other words in the sentence.  
  99.  
  100.  
  101.       Background:
  102.           In some software, the input is quite fixed. In spreadsheets or 
  103.       word processors, for example, a fixed list of commands are 
  104.       available, and no general flexibility is permitted (although 
  105.       multiple ways might be offered to accomplish the same task).  
  106.            In some early adventure games, two-word commands were the 
  107.       limit.  "TAKE BOOK" was the way you picked up a book. Sometimes 
  108.       synonyms were offered ("GET", for example). More complex sentences 
  109.       were sometimes permitted ("THROW AXE AT DWARF"), but it's a much 
  110.       easier programming task if the syntax is fixed. For this last 
  111.       reason, the word "the" was a latecomer to adventure games.  
  112.            Of course, what you really want is a way to say "Take the 
  113.       small red key from the second dwarf and put it in the blue box 
  114.       under the rug" and have the program figure out what you want. GAGS 
  115.       can't do that, for several reasons. It can, however, accept some 
  116.       fairly long sentences and concepts more complex than  "THROW AXE." 
  117.            One acquaintance suggested that a really good adventure game 
  118.       should understand a sentence like "Dive under the fallen branch and 
  119.       roll to the left, grabbing the laser pistol as you rise, and sever 
  120.       the dwarf's leg by ricocheting a laser shot off of the pickup's 
  121.       mirror." I'll leave that as an exercise to the reader.  
  122.       
  123.       What does a parser need to do?
  124.  
  125.            A parser breaks up a sentence into parts of speech. Let's 
  126.       think about that for a minute, using the previous sentence as an 
  127.       example.  
  128.        
  129.               "A parser breaks up a sentence into parts of speech."
  130.               /       |   |          |        |      |
  131.       article/ subject^   ^verb      ^object  ^prep  ^obj.of prep
  132.       
  133.            Instantly, most people can recognize the subject and the verb. 
  134.       "Parser" is the noun, and "breaks up" is the verb. Or is "breaks" 
  135.       the verb? "Up" is a preposition...but here it's an adverb. Gee, the 
  136.       English language is complicated.  
  137.            Already we have a problem: some words can serve as multiple 
  138.       parts of speech and can only be parsed by checking context. There 
  139.       are rules to English, but they're complex and filled with 
  140.       exceptions. Many programmers are working hard to develop "Natural 
  141.       Language Interfaces" to computers, so people can get computers to 
  142.       perform complex tasks without having to know how to program a 
  143.       computer. Very few of those "natural language interfaces" can 
  144.       accept a complex sentence, and most -- like GAGS' parser -- limit 
  145.       their knowledge to a certain task so context problems are reduced 
  146.       and the rules can be made more limited.  
  147.       
  148.                                  (continued)
  149.  
  150.                                       3-4
  151.  
  152.                      (the parser, continued)
  153.  
  154.  
  155.            In writing this game, I wasn't interested in AI or complex English 
  156.       or anything like that. I just wanted to allow people to enter 
  157.       understandable sentences, like "put the red key with the blue globe." How 
  158.       to do that?  
  159.            I cheated, to start. The first thing my parser does is strip 
  160.       out extraneous words, words that always (I hope) add no real 
  161.       meaning to a sentence. "The" and "a" are removed. So is "go", since 
  162.       that has no meaning unless it's followed by a direction. GAGS wants 
  163.       a verb to come first in the sentence, and will choke if there isn't 
  164.       one.  
  165.  
  166.  
  167.  
  168.       GAGS' Parser
  169.       ------------
  170.            The Parse procedure first breaks the sentence up into words 
  171.       (an array of strings), arbitrarily counting any non-alphabetic 
  172.       character as a word separator. (Actually, the real check is for 
  173.       ASCII characters from 'A'..'z'.) 
  174.            It then strips out any words which are "extras." A strange 
  175.       effect is that no check is made to see if the sentence really made 
  176.       sense before it was "stripped" of extra words. The sentence 
  177.       
  178.             "The Put the the red the gun the in the the the wooden the bookcase"
  179.  
  180.       becomes
  181.       
  182.             "Put red gun in wooden bookcase."
  183.       
  184.            The parser then immediately begins scanning the sentence, 
  185.       left-to-right.  The first word must be a verb now. If it is, the 
  186.       program moves on to the next word (or exits when it finds no more 
  187.       words). The program expect the second word to be a noun. If it's 
  188.       not a noun, it checks to see if it is an adjective with a noun 
  189.       following it. If neither is true, it checks the possibility that 
  190.       the second word might just be a preposition ("Look in bookcase"). 
  191.       If the second word wasn't a preposition, the third word is checked 
  192.       as a preposition.  The following word(s) is/are again checked as a 
  193.       noun or an adjective-noun pair.  
  194.       
  195.            A more "correct" parser could check for a verb, and then check 
  196.       to make sure that any articles ("the" or "a") are positioned 
  197.       properly with nouns, and that words like "please" or "now" are 
  198.       located logically.  
  199.       
  200.            Four strings are returned from the parser: a verb, a noun, a 
  201.       preposition, and another noun as the object of the preposition. 
  202.       Also, if any error was discovered (a word not recognized, or a 
  203.       missing verb), a boolean variable 'syntax_error' is set to 'true.' 
  204.       
  205.  
  206.  
  207.  
  208.                                       3-5
  209.  
  210.       GAGS - A Generic Adventure Game System 
  211.       Copyright 1985 by Mark Welch
  212.       
  213.       ---------------------------------
  214.       Possible Source Code Enhancements
  215.       ---------------------------------
  216.  
  217.  
  218.  
  219.       Modifying the Source Code: Some Suggestions
  220.       -------------------------------------------
  221.            There are probably an infinite number of ways you can modify 
  222.       the source code to GAGS to make it a more enjoyable game. In many 
  223.       ways, my original coding was too simple to permit a full-featured 
  224.       game. Changes to the game range from relatively simple and painless 
  225.       additions to some extremely complex modifications which could mean 
  226.       rewriting huge portions of the code. In fact, I'm open-minded 
  227.       enough to realize that some efforts would involve rewriting the 
  228.       entire game or starting from scratch.  
  229.       
  230.       
  231.       Enlarging the Game
  232.       ------------------
  233.       As shipped, GAGS can handle up to 200 rooms, 100 creatures, and 
  234.       100 objects. These limits permit the game to run snugly in a 192K 
  235.       IBM PC, or quite comfortably in a 256K system. If you have more 
  236.       memory than that, you might want to expand these limits. All the 
  237.       changes would be in the declaration module (DECLARE.MOD), where 
  238.       you'd need to simply re-define the first and last numbers of each 
  239.       range (creatures, rooms, and nouns).  
  240.       
  241.  
  242.       "On-Line Help"
  243.       --------------
  244.       One verb you might want to add is "help." A help procedure might 
  245.       do one of several things: it might simply read in a file and 
  246.       display it on the screen; it might prompt for the user's specific 
  247.       help question (or you might patch the parser so the user could 
  248.       type "help scream" or whatever); or it might try to offer 
  249.       context-sensitive help ("The reason you can't go north is that 
  250.       the banshee blocks your way. Banshees often let you pass if you 
  251.       give them yogurt"). 
  252.       
  253.       
  254.       Specials
  255.       --------
  256.       Although several methods of invoking "specials" have been 
  257.       provided, you might want to add more by defining new verbs to 
  258.       activate them. Or, you might modify the "Take" procedure to 
  259.       invoke a special; this would involve a fairly aggressive 
  260.       rewriting of that procedure. You might want to modify the 
  261.       procedures in which a creature is killed to search for text to 
  262.       display, rather than the stock "creature is killed" message; you 
  263.       might even want to leave a dead body in the room after a creature 
  264.       is killed. Keying user-defined verbs to specials would be ideal.
  265.       
  266.                                  (continued)
  267.       
  268.                                       3-6
  269.  
  270.                          (Enhancing GAGS, continued)
  271.                                          
  272.  
  273.       Adding Verbs
  274.       ------------
  275.       Probably the simplest thing to do is add a verb to the game. In 
  276.       the latter stages of development, I was able to add new verbs in 
  277.       about ten minutes, plus the time it took to write a procedure to 
  278.       execute the verb's desired actions. Adding a verb was designed to 
  279.       be the easiest task because I started the game with one verb 
  280.       ("Look") and added new verbs at the rate of about one per night 
  281.       of development and debugging. 
  282.          To add a verb, you must modify the Init_Verbs procedure so 
  283.       that the parser recognizes it as a valid verb, and you must add 
  284.       the new verb to the multiple if..then..else statement in the 
  285.       Execute procedure so that Execute performs the action you desire 
  286.       from the verb's invocation.
  287.          If you want to add synonyms, this involves merely calling 
  288.       whatever procedure already exists. If you want to create a new 
  289.       procedure, you have Execute call it and then write the procedure. 
  290.       I added the "Scream" procedure in this way in a total of fifteen 
  291.       minutes, and then created two synonyms ("shriek" and "shout") in 
  292.       five more minutes. Of course, the Scream procedure doesn't do 
  293.       anything to modify variables; more complex procedures will 
  294.       involve some fairly complex actions and testing. When you write a 
  295.       new procedure, you'll usually want to test to see if the desired 
  296.       action can be performed, and whether the things being acted upon 
  297.       are present.  
  298.          Two verbs called for by several beta-testers but not 
  299.       implemented are "shoot" and "fire," which would be useful in 
  300.       games with guns.
  301.       
  302.       
  303.       Multiple Nouns with the Same Name
  304.       ---------------------------------
  305.       One thing Infocom adventures provide are multiple nouns with the 
  306.       same name, like "brass key" and "bronze key." While GAGS 
  307.       currently doesn't provide this, it wouldn't be too difficult to 
  308.       modify it to do so. The parser would pass along the noun, but the 
  309.       Noun_Number procudure currently returns only the number of the 
  310.       first noun with the specified name. You could have Noun_Number 
  311.       check to see if the adjective matches (which would involve having 
  312.       the parser return the adjective along with the noun, verb, 
  313.       preposition, and object) and resolve unanswered ambiguities by 
  314.       asking, "Which <noun> do you mean, the <first_adj> one or the 
  315.       <second_adj> one?" 
  316.            Alternately, the parser could be left to resolve the 
  317.       ambiguity and could then return a noun NUMBER instead of the 
  318.       actual noun name. This last approach could also save some 
  319.       processor time since the noun's number is accessed during both 
  320.       the Is_Noun and the Noun_Number functions. Of course, returning a 
  321.       noun number instead of a name would require a major rewrite of 
  322.       the program. 
  323.            
  324.                                  (continued)
  325.  
  326.                                       3-7
  327.  
  328.                          (Enhancing GAGS, continued)
  329.  
  330.       Creature Animation
  331.       ------------------
  332.       With a fairly small effort, creatures in the game could be 
  333.       "animated" -- that is, made to move from room to room within the 
  334.       game. This involves modifying the ANIMATE module by adding new 
  335.       procudure(s) and making calls to them from the animate procedure. 
  336.       The procedure could check a new field in the creature record and 
  337.       thus decide what sort of motion is called for (none, random, or 
  338.       intelligent). It might merely have the creature follow the player 
  339.       once encountered, or might invoke random behavior. Perhaps 
  340.       creatures could pick up items the player has discarded (or thrown 
  341.       at the creatures), and even use them as weapons against the 
  342.       player or as tools to their own goals. There are some fascinating 
  343.       possibilities here. 
  344.  
  345.  
  346.       Turn/Time Sensitivity
  347.       ---------------------
  348.       In the same manner -- a module executed from the main program -- 
  349.       the game could support time or number-of-turn sensitivity. For 
  350.       example, the game might seal off an area of the game after a 
  351.       certain time, and trap the player inside (or outside). Or a 
  352.       creature might be added to the game after a certain time period. 
  353.       Perhaps the player could be chased more aggressively by creatures 
  354.       as time passes, or even chased at a rate commensurate (sp?) with 
  355.       his or her skill level, so experienced adventurers who breeze 
  356.       through many rooms quickly are instantly set upon by all the 
  357.       beasts available. The player might also collapse from hunger if 
  358.       s/he hasn't eaten food in a certain number of turns. Again, the 
  359.       limits for this addition are virtually limitless, but all require 
  360.       some modification of several procedures. 
  361.       
  362.  
  363.       Adding Verbs in Data Files (User-defined verbs)
  364.       --------------------------
  365.       When I first began designing GAGS, I had hoped to allow new verbs 
  366.       and their actions to be defined in the data file, so that anyone 
  367.       could add new verbs. I decided that although the idea was 
  368.       conceptually sound, the difficulty of the task made it not worth 
  369.       the advantage. Additionally, an additional level of game design 
  370.       complexity would be added. 
  371.          I think that permitting "special" verbs to be defined in data 
  372.       files is still a possibility, and though not at all a simple 
  373.       task, it would not be a lifelong effort. Essentially, my approach 
  374.       would be to add a new "special" procedure -- or more than one -- 
  375.       but leave the verb names undefined. Then, when the data file was 
  376.       read in, the verb names could be plugged into place and tested 
  377.       against. If the specified conditions of the special were in 
  378.       place, and the verb was typed, a standard "special" could be 
  379.       executed. 
  380.    
  381.  
  382.                                       3-8
  383.  
  384.  
  385.       Attempts to reduce the size of GAGS
  386.       ===================================
  387.  
  388.            The program already makes extensive use of overlay files, 
  389.       due to Turbo Pascal's 64K code segment limit. I noticed only 
  390.       about a 5-second slowdown in the game's initialization when I 
  391.       began using overlays. Since the total of the .COM file and the 
  392.       overlay files is about 75K, it's probably relatively simple to 
  393.       reduce the code size to under 64K and avoid the use of overlays, 
  394.       but I don't find a pressing need and prefer not to worry about 
  395.       the RAM needed by each feature I add.  
  396.            
  397.       Rough minimum size: 59K
  398.       -----------------------
  399.          Before GAGS grew to its present size, in an effort to further 
  400.       reduce the RAM needed, I tried adding more overlays in several 
  401.       areas. First, the main modules (execute, the two initialize 
  402.       procedures, title, and the parser) were overlaid.  This, of 
  403.       course, means a disk access every turn since the parser and 
  404.       execute procedures alternate. Then I overlaid as many of the 
  405.       EXECSUBS procedures as possible, breaking them into two or three 
  406.       overlays to avoid some disk swapping.
  407.           I then reduced the size of the arrays: to 10 creatures, 25 
  408.       nouns, and 70 rooms. This reduced the program's reported maximum 
  409.       heap size to 64K exactly.  
  410.          I then installed my machine as a 128K IBM PC, and attempted to 
  411.       run the object file with varying amounts of memory allocated to a 
  412.       print buffer (in 1K increments). 
  413.          The program, as quickly overlaid and compressed, will execute 
  414.       with a 43K print buffer installed, or in 85K of RAM. The 
  415.       operating system reserves 26K of the 85K; the program itself, 
  416.       with its data areas and such, thus takes up 59K.  
  417.          The main program .COM file was under 20K, as distinct from the 
  418.       51K file generated without use of overlays. However, even with 
  419.       all the overlays above, the standard 200-room/100-creature/100-
  420.       noun data would not fit in 128K, so there are no real savings 
  421.       except possible space reserved for other resident programs in a 
  422.       192K machine.  
  423.          These size figures were obtained before a number of GAGS' 
  424.       functions were added or enhanced; GAGS is probably about 10-20% 
  425.       larger now than it was then. Reducing GAGS to run in a 64K CP/M 
  426.       system is almost impossible, and would certainly involve too much 
  427.       performance degradation to be worth the effort.  
  428.  
  429.