Post by parzival on Mar 26, 2021 14:57:21 GMT
I’ve been working on a ZORK-style adventure game in BASIC. It involves a heavy amount of string data— rooms, words, descriptions, etc., and a number of arrays both for string and numeric variables. It’s currently two separate programs— a data loader that acts as the title and instruction page (on screen while the data loads), and a game program that allows the user to enter commands to “move” around and manipulate objects. (Mostly this just changes the number within a given array, calling up a new array entry to show the player.)
The loader works, and successfully transfers data to the game program. The command system works, the parser works, the branches to the manipulation routines works, and so far the routines I can test play all work. But I’ve discovered a very odd event. As with most text games, there are obstacles to certain actions which the user has to resolve. For example, the player might “enter” a room in the game and find a creature there holding an item the player wants or needs. If the player attempts to take the wanted item, the creature prevents this. Of course, this is a simple sequence of IF/THEN statements comparing the states of different array variables and printing an appropriate string in response, depending on these states.
In this particular game, the above sequence is unique, which means the variables used are unique. However, I’ve designed the system to be quickly adaptable for different adventure stories, so the sequence involves two DIMensioned arrays which are quite large, though only one variable element in each array actually contains data. In this case, the arrays are IO(X) and IO$(X). (IO being shorthand for “ItemObstacle”). The “X” is the ordinal number of the item being “protected”— for example, if item “COOKIE” is the 21st item/word in the list of items, X would be 21.
IO(X) then holds the ordinal number of the obstacle itself (obstacles and items are all part of the same word list). So if “MOM” is the 36th item/word in the list, then IO(21)=36. The COOKIE is protected by MOM.
So when the command “TAKE COOKIE” is entered by the player, the game checks the IO array to see if there is an obstacle for the word COOKIE and if that obstacle is in the same location as the COOKIE. The IO array returns 36 as an obstacle value corresponding with COOKIE. The routine checks to see if item 36 (“MOM”) is in the room, and if it is, prints IO$(21); this is the sentence that is printed if your try to TAKE the COOKIE while MOM is in the room— “Mom slaps your hand away and says, ‘Not till you’ve eaten your Brussel sprouts!”
And here’s where things break down. In my program IO(160)=185. IO$(160)=“The monkey king shrieks and knocks your hand away!”
Only the command PRINT IO$(160) produces gobbledygook. Originally, it produced a partial string, then some keyboard characters, and the list of numbers that were read next in the data loader program. Work on the data loader program later changed what it printed to include garbled text from a REM statement at the end of the data program, and then changed the colors of the text! I thought there might have been an issue in the READ and DATA sequences in the loader program, so I took the string and IO value out of the DATA statement, and made it a direct assignment:
IO(160)=185:IO$(160)=“The monkey king shrieks and knocks your hand away!”:IO$(160)=IO$(160)+””
(The last part of that line turns the string into a dynamic string so the data loader program can pass it along intact to the game program with the LOAD statement. I’ve done the equivalent with all the strings in the program without issue.)
But that still produces the error. I’ve even changed the location at which that string appears in the list of data loaded— still produces gobbledygook and the color change. Note that once this garbled result is printed, the program still functions as expected, and no other data seems to be affected.
I’m baffled. I wondered if I’ve triggered a hidden BASIC keyword? “IO$” isn’t on any list I’ve found, but I realize it’s close to the old computer term “I/O”, though I’ve never seen that as a keyword in any form of BASIC.
The two programs are close in size, and very large (22663 free bytes before loading data, vs. 22749 free bytes in the game program— with the data loaded that latter falls to just 1221 free bytes!). Am I simply hitting some sort of memory issue— the game program and the variables are somehow picking up the remaining overwritten scraps of the loader program? (I’m not a technically oriented guy, so if that’s nonsense, I don’t mind being corrected.)
If anyone can make sense of this, I’d appreciate the help!
The loader works, and successfully transfers data to the game program. The command system works, the parser works, the branches to the manipulation routines works, and so far the routines I can test play all work. But I’ve discovered a very odd event. As with most text games, there are obstacles to certain actions which the user has to resolve. For example, the player might “enter” a room in the game and find a creature there holding an item the player wants or needs. If the player attempts to take the wanted item, the creature prevents this. Of course, this is a simple sequence of IF/THEN statements comparing the states of different array variables and printing an appropriate string in response, depending on these states.
In this particular game, the above sequence is unique, which means the variables used are unique. However, I’ve designed the system to be quickly adaptable for different adventure stories, so the sequence involves two DIMensioned arrays which are quite large, though only one variable element in each array actually contains data. In this case, the arrays are IO(X) and IO$(X). (IO being shorthand for “ItemObstacle”). The “X” is the ordinal number of the item being “protected”— for example, if item “COOKIE” is the 21st item/word in the list of items, X would be 21.
IO(X) then holds the ordinal number of the obstacle itself (obstacles and items are all part of the same word list). So if “MOM” is the 36th item/word in the list, then IO(21)=36. The COOKIE is protected by MOM.
So when the command “TAKE COOKIE” is entered by the player, the game checks the IO array to see if there is an obstacle for the word COOKIE and if that obstacle is in the same location as the COOKIE. The IO array returns 36 as an obstacle value corresponding with COOKIE. The routine checks to see if item 36 (“MOM”) is in the room, and if it is, prints IO$(21); this is the sentence that is printed if your try to TAKE the COOKIE while MOM is in the room— “Mom slaps your hand away and says, ‘Not till you’ve eaten your Brussel sprouts!”
And here’s where things break down. In my program IO(160)=185. IO$(160)=“The monkey king shrieks and knocks your hand away!”
Only the command PRINT IO$(160) produces gobbledygook. Originally, it produced a partial string, then some keyboard characters, and the list of numbers that were read next in the data loader program. Work on the data loader program later changed what it printed to include garbled text from a REM statement at the end of the data program, and then changed the colors of the text! I thought there might have been an issue in the READ and DATA sequences in the loader program, so I took the string and IO value out of the DATA statement, and made it a direct assignment:
IO(160)=185:IO$(160)=“The monkey king shrieks and knocks your hand away!”:IO$(160)=IO$(160)+””
(The last part of that line turns the string into a dynamic string so the data loader program can pass it along intact to the game program with the LOAD statement. I’ve done the equivalent with all the strings in the program without issue.)
But that still produces the error. I’ve even changed the location at which that string appears in the list of data loaded— still produces gobbledygook and the color change. Note that once this garbled result is printed, the program still functions as expected, and no other data seems to be affected.
I’m baffled. I wondered if I’ve triggered a hidden BASIC keyword? “IO$” isn’t on any list I’ve found, but I realize it’s close to the old computer term “I/O”, though I’ve never seen that as a keyword in any form of BASIC.
The two programs are close in size, and very large (22663 free bytes before loading data, vs. 22749 free bytes in the game program— with the data loaded that latter falls to just 1221 free bytes!). Am I simply hitting some sort of memory issue— the game program and the variables are somehow picking up the remaining overwritten scraps of the loader program? (I’m not a technically oriented guy, so if that’s nonsense, I don’t mind being corrected.)
If anyone can make sense of this, I’d appreciate the help!