GameBASIC 1.1 Written by Robert A. Stoerrle (a.k.a. MALAKAI) 1 September 1988 If you've ever written--or tried to write--a text adventure game in BASIC, you're probably well aware of its shortcomings in that area. For one thing, BASIC is just too slow to handle an elaborate text parser. In addition, the INPUT command won't accept sentences that contain commas, and the player can move the cursor around at will and even clear the screen during input. The usual solution is to write selected parts of the game in machine language, but this consumes much time, time that would better be spent creating new puzzles for the adventurer to solve. Now there's an easier alternative. "GameBASIC" is a machine language utility that adds several new commands to BASIC to make the development of text adventure games faster and easier. It adds statements and functions to help with text parsing, screen formatting, input validation, and structured programming. It even contains commands for easier disk access and eliminates the save-with-replace bug. To load and activate the GameBASIC, simply type the following: LOAD "GAMEBASIC",8,1 NEW SYS 49152 A sign-on message will appear to remind you that GameBASIC is in effect. Please note that any programs that contain the new commands must be typed while GameBASIC is activated. Since it is necessary to have the GameBASIC in memory to execute a program written with it, you might find it useful to have your programs automatically load and activate the utility. Just include the following two lines at the beginning of your adventure game program: 10 IF PEEK(49152)<>169 THEN LOAD "GAMEBASIC",8,1 20 CLR:SYS49152 Text Parsing Commands --------------------- Text parsing is the process of taking what the adventurer has typed and carrying out his commands. The first phase of this process is the most time- consuming. It involves converting each word in the sentence into a number by comparing it to a list of words and returning its position in the list. Obviously, the more words there are in the list, the longer it takes to parse the sentence. Since this process is such a repetitive task, it is well suited to machine language. Thus, GameBASIC provides the PARSE statement which converts an entire sentence to numbers. For the PARSE command to work, you must supply GameBASIC with a list of words. These words are stored under ROM (at $A000) so that they don't take any memory away from BASIC. The following commands are provided to maintain that list and help with text parsing. RESET. This command clears the word list. You should use it before adding the first word to the list. ENTER word, type. The ENTER command allows you to add a new word to the list. "Word" is a string that holds the word, and "type" is the part of speech of the word. The part of speech is simply a number from 1 to 15. You can devise a coding scheme by assigning a certain number to verbs, another number to nouns, and so on. Words should be typed unshifted and may contain letters, numbers, the hyphen, and the apostrophe. However, the last letter has special significance. If it is shifted, only that exact word will be recognized during parsing. Otherwise, any word that begins with that sequence of letters will be recognized as the same word. For example, if the last letter of the word "take" is unshifted, the words "takes" and "taken" would also be considered to be that word. This is a handy feature for verbs, since many have several different endings. However, words such as "a" and "the" should be typed with the last (or only) letter shifted. PARSE string. As discussed, the words in the given string will be converted to numbers by this command. Note that punctuation and capitalization, except for the hyphen and apostrophe, in the input sentence are ignored. TYPE(0) and NUM(0) are two functions which should be used after the string is parsed. They will return the part of speech and list index of the current word in the sentence, starting with the first word. TYPE should be read first, as NUM advances to the next word after returning the list index. The usual format is as follows: B=TYPE(0):A=NUM(0) After these statements are executed, you will be able to work with the part of speech and word index for the current word by referring to variables A and B. Although there is really only one list of words, it is helpful to think of there being fifteen different lists, one for each part of speech. The list index is the position of the word in the list. If the fifth noun in the list is "sword," the list index returned will be 5, even if there are words of other types preceding the fifth noun. Sometimes a part of speech of zero will be returned. This can indicate one of two things, and you should check the list index to determine which. If the list index returned is is -1, you have reached the end of the input sentence. If the list index is -2, a word was encountered that is not in the list. When a word in the input sentence wasn't found in the word list, you can use the TEXT$(0) function to get the text of the unrecognized word. You might then want to print it out and tell the adventurer that the word is not in the computer's vocabulary. If you're into artificial intelligence, you might even ask for a definition of the word and add the word to the list! TEXT$(type, index). This variation of the TEXT$ function can be used to return the text of any word in the word list. You must supply the part of speech code and the list index of the word that you want. Please note that these commands do not constitute a complete text parser. You will still have to write code to interpret the player's commands, but it's a lot easier and quicker to work with numbers than it is to use strings. Input Validation ---------------- Two of the most annoying aspects of the INPUT statement are its refusal to accept such characters as the comma and the colon and the ability to disrupt the rest of the screen during input. Therefore, the PROMPT command was included in GameBASIC. Its format is as follows: PROMPT text, mode, string variable When this statement is executed, the "text" string is first printed. This is usually some sort of prompt, such as a question mark or a greater than sign (>). Then, input is received from the keyboard. Unlike the INPUT command, however, only certain characters are allowed. No longer is it possible to clear the screen, move the cursor up and down, change colors, and so on. You can still use the DELete key, but you can't go past the beginning or end of a line. "Mode" allows you to specify further which keys are allowed and which aren't. The three modes available are: 0 -- Upper and lower-case letters, numbers, punctuation, and DEL. 1 -- Same as above, except that upper-case letters are prohibited. 2 -- Unshifted letters and DEL, but letters are printed in upper-case. As with the INPUT statement, the RETURN key should be pressed after the input sentence has been typed. Whatever the player typed is then assigned to the given string variable. Remember that PROMPT only works with string variables. If you desire a numeric response, you'll have to use the VAL function to convert the string to a floating point number. Screen Formatting ----------------- GameBASIC has one transparent effect that does not need to be invoked by any new command. If you have ever used a word processor, you are probably familiar with the term word-wrap. It refers to the feature that prevents words from being split up over two lines on the screen. Normally, BASIC's PRINT statement does not have this convenience. However, when the GameBASIC is activated, the feature is installed, which makes it easier to format paragraphs of text. Instead of using one PRINT for each line of output, you can pack as much text as possible into each PRINT statement, following every one except the last with a semicolon. You can even assign an entire paragraph to a string variable and PRINT it. It will be formatted correctly on the screen. There is one side effect caused by this feature: the comma and TAB options of the PRINT statement do not function correctly unless the item before the comma or TAB has a space as its last character. Also note that word-wrap is functional only within a program; it is unavailable in direct mode. There are also several commands provided to assist with screen formatting. SCREEN allows you to change the screen and border colors. Its syntax is as follows: SCREEN border, screen. Its parameters may range from 0-15 and are the standard color codes. WINDOW text, color. It is possible to reserve the top line of the screen as a status line for the purpose of displaying such information as the name of the game or the current room. The status window will never scroll off the screen. You can use the WINDOW statement to create this window or place text in it. It is followed by a string expression and a color code. The string is displayed in reverse video in the specified color at the top of the screen. This command can be used again to change the text in the window. Please note that anything that is in the window before the WINDOW command is executed will be erased. The window will remain at the top of the screen, and the rest of the screen will scroll normally, as long as a cursor-down is not printed on the bottom line of the screen. Also, the screen must not be cleared with the normal CHR$(147) code. Instead, use the command CLS. Structured Programming ---------------------- Text adventures are logical in nature and lend themselves conveniently to structured programming languages. BASIC is not ordinarily considered such a language because of its lack of such features as an ELSE statement and named procedures. However, GameBASIC bridges the gap between BASIC and structured programming. While this program is in effect, you will be able to add an ELSE clause to your IF statements. The statements on that line following the ELSE will be executed only if the condition that is being tested is false. If the condition is true, the statements following between THEN and ELSE will be executed, and the instructions after the ELSE will be totally ignored. Note that a colon (:) is required before the ELSE. For instance: IF Q=1 THEN PRINT"YES":ELSE PRINT "NO" In this example, if the value of Q is 1, the program will display the word "YES." Otherwise, the word "NO" will be printed. In addition to the ELSE statement, you may now name your subroutines. At the very beginning of a subroutine, simply include the keyword PROC followed by the name of the procedure. Any name beginning with a letter will do, even if it contains a reserved BASIC word such as STOP. To call that subroutine, simply type GOSUB followed by the name that you gave the subroutine in the PROC statement. As always, the RETURN statement is used to end the subroutine and return to the statement directly after the GOSUB. Note that it is still possible to GOSUB to a line number. Also, you may use PROC to label a line to jump to using GOTO. In fact, you need never reference line numbers again within a program. When writing adventure games, programmers frequently use an ON GOTO statement to jump to the appropriate section of code to perform a given verb. Unfortunately, if there are many verbs, it may not be possible to fit all of the line numbers onto the line after the GOTO. GameBASIC solves this problem by allowing you to extend ON GOTO and ON GOSUB statements for as many lines as you wish. On subsequent lines, simply include the 'at' symbol (@) as the first character on the line and continue your list of line numbers. Alternatively, instead of line numbers, you may use procedure names defined by PROC statements, as explained above. Please note that there should NOT be a comma at the end of any line. For example: 1050 ON V GOTO GO, EAT, DRINK, CLIMB 1060 @ DESCEND, ATTACK If V is 5, the program will branch to the subroutine named DESCEND. Another useful pair of commands is REPEAT and UNTIL. These are found in most structured programming languages and are normally missing from BASIC. They form a special form of loop that is executed as long as a certain condition has not become true. The condition follows the UNTIL statement at the bottom of the loop. The general structure of such a loop is as follows: REPEAT [statements] UNTIL condition Note that it is possible to nest REPEAT loops. Sometimes a special situation will occur in a subroutine that requires that subroutine branch to some part of the program without returning to its calling GOSUB. This is known is improperly exiting a subroutine and is usually accomplished with a GOTO. The problem with this is that the computer wastes valuable memory remembering where to RETURN from that subroutine, while a RETURN will never occur. To alleviate this problem, GameBASIC provides an EXIT statement. Followed by a line number or procedure name, it performs a GOTO to that line while removing the RETURN information from the stack (the area of memory that stores RETURN information). Another variation of this command is POP, which simply removes the RETURN information from the stack, without exiting the subroutine. After a POP, you are free to exit at any time with a GOTO, but RETURN can no longer be used. Disk Commands ------------- GameBASIC makes disk access much easier, enhancing existing BASIC commands and adding several new commands. First of all, the LOAD and SAVE commands no longer default to the tape drive; they now automatically access the disk drive (device 8). All of the new commands also default to this drive. In order to change the default drive number, you can use the DEVICE command. The keyword DEVICE is followed by the new default device number (8-11). To load a program from the default drive, for example, all you need type is: LOAD "Program name" You need not include the ',8.' The DIR command displays a directory of the disk in the default drive. It does NOT disturb any program in memory. The SCRATCH command is followed by a string containing a filename. That file will be scratched from the disk in the default drive. The REPLACE command combines the SCRATCH and SAVE commands into one. It is intended to replace the unreliable '@0:' save-with-replace feature. Simply follow the keyword REPLACE with the filename to be scratched and then resaved. The DISK command typed alone will display the current disk status on the screen. Alternately, you can follow this command with a string containing a normal DOS command (like N0:diskname,id) to be sent to the default drive. The BFILE command can be used in place of the ',8,1' suffix on the LOAD command. BFILE is followed by a filename. That file will be loaded from the default drive at the address from which it was saved. This command is intended to be used to load machine language programs or data tables into memory without disturbing the BASIC program in memory. Note that, unlike LOAD, the program will NOT be rerun after the load. Many adventure game programmers store room descriptions and information on disk in the form of sequential files. The problem comes in reading this information back into memory. The INPUT# command is fooled by commas and colons embedded in the text, and it cannot read strings longer than 88 characters. Thus, the PUT# and FETCH# commands have been added. PUT# is identical to PRINT#, with a few important differences. First, each item must be separated by commas. You may not use the semicolon, TAB, or SPC options. The data are stored in a different manner. Only numbers from -32768 to 32768 can be written using this command. Thus, only the FETCH# command (whose syntax is identical to that of INPUT#) may be used to read data written by PUT#. FETCH# has the ability to read any string that was written using PUT#, even if it contains commas or colons. Miscellaneous Features ---------------------- GameBASIC contains several commands that are of limited use but nevertheless are handy to have around. WARM is a tidy way to end your programs. It disables this utility, and displays the screen that you see when you use the STOP and RESTORE key combination. In technical terms, it performs a BASIC warm start. DISABLE turns off GameBASIC without performing the warm start. UPPER and LOWER allow you to switch between uppercase/graphics mode and lowercase/uppercase mode. This is the same as using the Commodore key in conjunction with the SHIFT key, with one important difference: these commands lock the computer in either of those modes; you cannot use the Commodore/SHIFT combination to change cases after using UPPER or LOWER. To get a list of the new commands added by GameBASIC, just type HELP. When you are listing programs or the disk directory, you can now use the SHIFT key to temporarily pause the listing. To resume the listing, simply release SHIFT. To stop the listing for a while, use SHIFT LOCK. While this package is primarily designed for programming adventure games, some of the commands (particularly the structured programming options), should appeal to all BASIC programmers. As always, any questions, comments, or complaints can be directed via E-Mail to my MALAKAI account on Q-Link. --- Robert A. Stoerrle ---