Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : CMM2: Scott Adams Adventure Game Interpreter
Page 1 of 5 | |||||
Author | Message | ||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Conversation spun off from: https://www.thebackshed.com/forum/ViewTopic.php?TID=12495&PID=159807 Hi Bill, That's really great, I'm pleased that someone is carrying this work forward, I'm happy to help in any way I can. The version of "interp.bas" that I wrote and included on the Welcome Tape is derived from a very early version of Scott Adams' Adventure Interpreter and some of his later games (or later versions of the earlier games) will require further extensions to the interpreter. With reference to the issue of command 85, see: https://github.com/pdxiv/LuaScott/blob/master/doc/The_ADVENTURE_Data_Base_Format_(1980).md Command 85 is: 85, SAYwCR, This says the noun (second word) input by the player and starts a new line. So I guess the only implementation you need to add is to write the noun (probably in quotes) to the console followed by a newline. In the "pirate.dat" data file "Say" is implemented differently, see this decoded version of the content: pirate_dmp.zip Look at action 146: 146: SAY ANY Par 0 Par 0 Par 0 Par 0 Par 0 MSG:64 0 0 0 So SAY followed by ANY noun, causes message 64 to be displayed, and message 64 is "Use one word." The actual saying of YOHO is handled by actions 31, 32 and 88: 31: YOH ANY IN 5 Par 6 HAS 3 Par 0 Par 0 CLS MSG:7 GOTOy DspRM 32: YOH ANY -IN 5 Par 5 HAS 3 -BIT 4 Par 0 CLS MSG:7 GOTOy DspRM 88: YOH ANY Par 0 Par 0 Par 0 Par 0 Par 0 MSG:3 0 0 0 Decoding action 31 it reads: If the verb is YOH{O} And the player is in location 5, the window ledge And the player has item 3, the large leather book Then clear the display Display message 7, "Everything spins around and suddenly you are elsewhere..." Goto location 6, the sandy beach on a tropical isle. (the GOTOy parameter comes from the Par 6 earlier in the sequence) And describe/display the room. You should be able to decode the other actions for yourself using the reference above Let me know if you would like any more assistance, I have PM'd you with my email address if you prefer to communicate that way, but I see no reason not to discuss publicly on TBS. OK, it's a bit complex. I corresponded informally with Scott Adams about the issue of the license (see file "pirate/permission.pdf" in the Welcome Tape). Whilst the idea of making the interpreter available for free and allowing it to be extended got his full blessing he wasn't willing to let me slap the MIT License (or something equivalent on it) and I wasn't willing to stretch the good will of one of the father's of commercial game software by asking for a formal legal agreement. Ultimately I was in a rush to release the Welcome Tape and so decided to play it safe and slap that restrictive text in the LICENSE file. You certainly have my blessing to make changes and make your enhancements available and I have no doubts that you have Scott's too, I can approach him if you like ? What I can't guarantee is that at some point in the future his heirs might take umbrage and ask us to stop distributing it ... I think the chance of this happening is infinitesimally small, but I am not a lawyer and cannot predict the future Best wishes, Tom Edited 2020-11-27 21:32 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Thanks Tom, Sorry but this is me you're talking to. I'm more like Victor Meldrew than Peter Mather. I did find the Github reference and looked at Pirate.dmp but while the Github thing I can partly understand the Pirate.dmp is gobbldeygook to me. Sorry. I'll read this again in the morning after a cup of coffee or two. Cheers Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Hi Bill, On the Welcome Tape you will find a program "pirate/src/dump.bas" this converts "pirate.dat" to "pirate.dmp". "pirate.dmp" is designed to show the data using the mnemonics described in https://github.com/pdxiv/LuaScott/blob/master/doc/The_ADVENTURE_Data_Base_Format_(1980).md For example line 2 of "pirate.dat": 80, 422, 342, 420, 340, 0, 16559, 8850, 80, 462, 482, 460, 0, 0, 15712, 1705 Is decoded into the first two actions: 0: 0 80 IN/W 21 IN/W 17 Par 21 Par 17 Par 0 MSG:60 x->RM0 x->RM0 0 1: 0 80 IN/W 23 IN/W 24 Par 23 Par 0 Par 0 MSG:54 MSG:62 MSG:11 x->RM0 But this is somewhat beside the point for the issue you encountered. Basically "interp.bas" does not currently implement commands 73-88 described in the document in the table headed "The possible command codes mean the following:" Your probably won't need to implement all of those commands for any specific adventure, just go through the walkthrough until you hit an "Unknown command" and then implement it. I'm happy to help with any specifics, including hand-holding if necessary, no giving up is allowed , when I get back to flashing LEDs then you can reciprocate. Best wishes, Tom Edited 2020-11-28 02:07 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Thanks Tom, I've got that far already. Maybe easy for you. Command 84 is: That seems simple enough but I have a nasty feeling that that's just the start of a bigger headache. I'll have a go. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
I ran DUMP on the Adventureland database and noticed a few "Huh?" entries in there so I modified the GET_CMD$(C) function to display the code number instead: Case 72: s$ = "EXx,x" Case 102 To 149 : s$ = "MSG:" + Str$(c - 50) Case Else: s$ = "<"+str$(c)+">" '"Huh?" End Select get_cmd$ = s$ End Function This shows me that codes 73, 74, 76, and 85 are not catered for. My quote from the database format document should have been: I'll try to get back to it later. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
OK, This is an extract from the dump for adventureland: I know I need to implement something like: But I am struggling to find the variable containing the noun. Also what is the significance of -IN 26 against IN 26? and HAS 11 against IN/W 11? and I haven't worked out the Par x bit yet Cheers Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Good morning Bill, or should that be good evening The text of the noun is in the parameter nstr$ passed to do_actions(). You need to add that parameter to do_commands() and then pass it through when do_actions() calls do_commands(). I'll backup a bit just in case you haven't grasped the following: The 11 values for each row in the action table are: VERB, NOUN, CONDITIONS 1-5, COMMANDS 1-4 In general when processing actions the VERB and NOUN the user supplied are checked against each row, if they are the same then the 5 CONDITIONS are checked to see if they are true, if they are all true then the COMMANDS are performed in sequence. Sometimes one or more of the CONDITION slots is instead used to hold a parameter to be "consumed" by a COMMAND. -IN 26 and IN 26 are CONDITIONS: IN 26: is true if the player is in room 26 -IN 26: is true if the player is not in room 26 Again these are CONDITIONS: HAS 11: is true if the player is carrying object 11 IN/W 11: is true if the player is in the same room as object 11 AND is not carrying object 11. I agree this is a little confusing because of the (historical) way the data was packed to allow Scott Adams' games to be run in as little as 16K. Let's take an example entry from the action table: 103: SAY BUN AVL 47 HAS 11 Par 11 Par 25 Par 7 SAYwCR MSG:18 x->y SETz This should be interpreted as: IF Verb = "SAY" AND Noun = "BUN" - note the parser only considers the first 3 letters so this also pass if the user typed "SAYONARA BUNGALOW". AND (AVL 47) the player is carrying or in the same room as object 47 AND (HAS 11) the player is carrying object 11 The next three CONDTIONS are the parameter values (11, 25, 7), we remember them for later. THEN (SAYwCR) print the current noun "BUNYON" to the screen followed by carriage return (MSG:18) print message 18 (x->y) move parameter #1 object to parameter #2 room. Looking back we see that the first Par = 11 and the second Par = 25, so object 11 is moved to room 25. (SETz) set parameter #1 status bit. Since we have already "consumed" the first two parameters processing the previous command this actually refers to the third parameter (Par = 7) in the CONDITION list, so status bit 7 is set. Hope this was clear, Tom Edited 2020-11-29 20:58 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Hi Bill, In case you haven't noticed, the interpreter includes some meta-commands you can type to help with debugging/testing. *debug {on | off} With debugging on: - room descriptions are prefixed with the room number. - object names are prefixed with the object number. - messages are prefixed with the message number. *record {on | off} Typing *record prompts you for a filename for a "script" and then starts copying every subsequent command you type into that script. *replay {on | off} Typing *replay allows you to replay a script created by "record". *seed Seeds the random number generator with a fixed value. Useful to ensure that any supposedly "random" behaviour is actually consistent. *state Prints the current game state: - the number of the current room - the value of the "dark flag" - the value of the "remaining light" counter - the indexes of the status bits that are currently set. Best wishes, Tom Edited 2020-11-29 21:21 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Thanks Tom, Most of that Adventure database stuff would be clear if I had RTFM. Sorry to bother you about that. I did notice some Debug instructions in the code but did not realize the full capability that you described. Very useful, as is the Dump information. Thanks for that, I'll have a go at that later today if I get time. If that is successful then I'll look at codes 73, 74 and 76. Code 73 looks a bit tricky though, you may want to be prepared for queries on that one. I'm not sure whether the Interpreter can handle the actions. I suspect not because I see nothing like this in the Pirate.dmp: It also mentions a 'continue flag' but that is the only mention of it in the document? So I'm suspecting that it's not one of those BIT-flags but a variable that needs to be defined in the Interpreter. This is looking way beyond my pay grade. Are you sure no giving up is allowed? Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Hi Bill, Not a problem, I didn't think it, and I didn't say it. I'm not keen on people who say RTFM, especially for the first few "offences". Frequently the FM isn't that friendly if you don't already have the correct background and if you must say it you should at least give a page number. Yes, I'm aware of that particular land mine and it will be my pleasure to help you defuse it. Correct this is new and will require some changes. At a first suggestion do_command() and do_commands() should become FUNCTIONs that return TRUE (1) if they process a CONT command. If do_commands() returns TRUE then do_actions() can check if the next action has VERB&NOUN=0 and if it does execute the next set of commands. My understanding is you're old enough to make up your own mind, but as long as you are enjoying yourself I'm happy to keep helping. Best wishes, Tom Edited 2020-11-30 20:02 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Thanks Tom, Previously you said: and also pass it from do_commands() to do_command() where the command will be executed unless I am wrong. I have not done that yet although it appears to be a simple change because I would like to go through the code again and gain a bit more of an understanding of what each SUB is doing. Regarding the CONT flag: Could this be a global variable which is set when an CONT command is found and then reset when the next action has a non zero verb/noun entry? This was my first thought but I have not followed it any further. Thinking about that, nstr$ could also be a global variable too? I don't think that's the way you work but then I'm NOT a programmer. Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Hi Bill, "Yes", well observed, you do need to pass nstr$ through to do_command(). "Yes", you can use global-variables if you must . "Best practice" is that global-variables should be the last resort, but this is your hobbytime; though if you do use global-variables I hope you won't mind if I change it should I have cause to work on this myself again at a later date. Best wishes, Tom Edited 2020-11-30 22:29 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
I understand. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Well that's enough for the day. I've added the missing commands (73, 74, 76, and 85) to Dump.bas. Added commands 76 and 85 to Interp.bas and all of that worked OK. Now I'm about half way through with no problems except one small one with the walk through where I have to drop the NET and the FISH, it gives the wrong order to drop them. The fish escape back to the water. Maybe I can go back and catch them again but I didn't try. Maybe next time I'll Try it just to make sure it works. Tom, I must say that I am very impressed with the way it all works! I had expected insurmountable problems with some incompatibilities but it's been relatively smooth so far. It would be good in the future to have the system suitable for multiple adventures, each with their own subdirectory and support files. It's a pity if all that work of yours is only used for one adventure. Maybe one day. Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Hi Bill, Added commands 76 and 85 to Interp.bas and all of that worked OK. Well done Bill, sounds like you are making good progress, I had every confidence. Next time use *record to create a script as you play, then you don't have to play through it manually each time you test, you can just use *replay. You can also copy the walkthrough from the internet direcly into a .scr file and *replay that, you need to prefix with a 2 line header consisting of: # DD-MM-YYYY hh:mm:ss # ScriptName There is a "gotcha" if the adventure has any random behaviour. Including *seed at the start of the script fixes that random behaviour, but it's still possible that any given walkthrough you find might need tweaking to get past the random spots the first time. If you need the script to stop at any given point then insert *replay off into it at that point. Thanks, but that's largely down to Scott Adams' original design. You are moving us towards that point. Don't forget to add your name to the developer credits. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Thanks, I'll try that. I've been saving the game at the treasure room each time I get there. That's true of the database but the Interpreter and it's support files are all your original work. The only things I recognise are the variable names and some of those had to be changed because MMBasic wont allow string variables and numerical variables to have the same name (and rightly so). I don't think so. I'm just mucking around the edges. I'll add comments as to the changes that's all. Some of your instructions you have given above on debug, record etcetera could be available in a Readme file. I'll have a look at that. Bill Keep safe. Live long and prosper. |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Tom, I have noticed that in your CONSOLE.INC file there is a subroutine called PRINTLN. Sub con.println(s$, center) The parameter 'center' intrigues me for two reasons: 1. I can't find where that variable is declared. Is it 'declared' by using it in the subroutine definition? I can't find that suggested in the manual. Edit: Just realized that OPTION EXPLICIT is not used in the include file but it is in the main INTERP.BAS file and I would have thought that would have been in force on any include files. Maybe that's one for Peter? 2. The spelling. Do you work with Americans in your day job? Bill Edited 2020-12-02 08:04 by Turbo46 Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
Hi Bill, 1. I can't find where that variable is declared. Is it 'declared' by using it in the subroutine definition? I can't find that suggested in the manual. Edit: Just realized that OPTION EXPLICIT is not used in the include file but it is in the main INTERP.BAS file and I would have thought that would have been in force on any include files. Maybe that's one for Peter? I'm not sure I even understand the question Sub con.println(s$, center) Says that there are two arguments/parameters 's$' and 'center' which are passed to and can be referenced from within the SUB. Note that 'center' is an INTEGER due to the OPTION DEFAULT INTEGER in the "interp.bas" file - just think of the .inc files as being pasted into the .bas file where their corresponding #INCLUDE is, you can even paste/#INCLUDE them multiple times. If there were global variables (i.e. declared with DIM) also called 's$' and 'center' declared elsewhere then these would not be visible within the SUB, they would be shadowed by the parameters with the same name. See the section on "Subroutines" in https://geoffg.net/Downloads/Maximite/Programming_with_the_Colour_Maximite_2.pdf, specifically p33: "Within the subroutine the arguments act like ordinary variables but they exist only within the subroutine and will vanish when the subroutine ends. You can have variables with the same name in the main program and they will be hidden within the subroutine and be different from arguments defined for the subroutine." I work with people from literally all over the world though my immediate boss is Welsh and his boss is a Cypriot. It's just one of those words I can't spell, I blame all the American technical books that I have read. Best wishes, Tom Edited 2020-12-02 09:01 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1584 |
Hi Tom, As far as I can see 'center' is declared here. Sub con.println(s$, center) That's in the included file CONSOLE.INC and it is used in other places when calling the subroutine. But OPTION EXPLICIT is used in the main INTERP.BAS program so 'center' should be explicitly declared using the DIM, LOCAL or STATIC command. But it isn't? Bill Keep safe. Live long and prosper. |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3807 |
As far as I can see 'center' is declared here. Sub con.println(s$, center) That's in the included file CONSOLE.INC and it is used in other places when calling the subroutine. But OPTION EXPLICIT is used in the main INTERP.BAS program so 'center' should be explicitly declared using the DIM, LOCAL or STATIC command. But it isn't? Sorry Bill, but where are these "other places" you are talking about? Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Page 1 of 5 |
Print this page |