New Scott Adams format interpreter "PerlScott"

I wanted to share the Scott Adams interpreter I’ve been making: PerlScott

Prerequisites: A computer with Perl 5 installed, with the “Readonly” and “Carp” modules installed

The interpreter should be complete, even though some more testing (especially on Brian Howarth games) is probably needed. Big thanks to auraes for his sharp eyes and help in improving it by logging issues on things that needed doing. Glaringly obvious bugs, problems and omissions probably remain, and I’m happy for any feedback. :laughing:

The PerlScott interpreter wasn’t created because the world really needs another Scott Adams interpreter, but rather as an intellectual exercise in translating 8 bit Basic code to a more modern, structured code format. The version 4.6 TRS-80 Level II Basic source code, which was published in the December 1980 issue of Byte Magazine (page 192), was painstakingly converted to Perl. The choice of Perl as the language to use, was down to it having most variation in possible syntax (TMTOWTDI), allowing you to write both “basic style” code initially and more structured code as the code was gradually refactored. Even though Perl is infamous for poor readability, the interpreter, in its’ current state, is written with as much regard as possible for Perl Best Practices, to have as much readability and maintainability as possible. Hopefully, this will not only allow people to use it for playing games, but to easily be able to read the code and understand the underlying concepts of the ingenious game engine that Scott Adams created, 40 years ago.

I’ve been playing through the games in order, and so far no issues have come up.

One thing I do appreciate, though, is the inclusion of the original basic code in your git repo. It was quite fascinating to do a comparison. =)

There are several errors in that basic listing!

do you have a scan of the original?

some obvious bad lines are; 140,470,1260,1300. Probably a lot more too!

I agree with that as I have compared it to the original listing in Byte magazine, which I still have after all these years.
It looks like some of the : have been replace with = and , replaced with . to mention 2 of the errors I can see among others.
Possibly the OCR didn’t interpret the scan as well as it should.

Thanks for the valuable comments, and for taking a look! Honestly, i never thought anybody had any sort of interest in something like this. The Scott Adams system and all the various things around it developed into a bit of a personal obsession at some point.

I’ve added the scanned image version of the code to the repository, for comparison. Corrections have been made to the basic listing on lines 80, 120, 140, 250, 470, 590, 720, 1170, 1260, 1300, so far. Probably some more errors remain, and i’ll need to go through it in more detail in the future. OCR has been anything but perfect so the basic listing is a combination of OCR with corrections for more obvious things and manually typed in bits. It proved to be enough at the time, for automatic translation into skeleton Perl code to work.

Pull requests are always welcome, as well, if somebody doesn’t want to wait for me to make the required changes :slight_smile:

I also converted and reformatted two old sources of information to Markdown, for easy reference:
The ADVENTURE Data Base Format (1980) by Alan Moluf
Adventure Editor Manual (1981) by Bruce Hansen

Thanks for the updates!

I’m looking at line 1290 in the listing,

1290 FORX=0TONLSTEP10:FORY=0TO1:INPUT#D,NV$(X,Y),NV$(X+1,Y),NV$(X+2,Y),NV$(X+3,Y),NV$(X+4,Y),NV$(X+5,Y),NV$(X+6,Y),NV$(X+7,Y),NV$(X+8,Y),NV$(X+9,Y):NEXTY,X

But it seems that the noun/verb list is interleaved. From your perl version, you have;

# Words { my $word = 0; while ( $word < ( ( $number_of_words + 1 ) * 2 ) ) { my $input = read_string($handle); $list_of_verbs_and_nouns[ int( $word / 2 ) ][ $word % 2 ] = $input; $word++; } }

How does line 1290 do that? I was expecting something like:

1290 FORX=0TONL:INPUT#D,NV$(X,0),NV$(X,1):NEXTX

Was the basic listing for an earlier version of the data format?

Your little translation arrived at the perfect time for me, and testing it certainly opened doors for my own personal obsession with the system, though as an archivist instead of as a programmer.

=)

This is an interesting line that i had forgotten about. The best way i can describe it, is that it’s a “loop unrolling” optimization. It has the slightly unfortunate side-effect of only allowing you to define words in the data files in groups of 10. You may notice in some game data files, that there are empty words in the end of the word list. It’s because of this. If you were to write an editor this would be a very good thing to keep in mind, for the sake of backward compatibility.

For the Perl version, just in case, i didn’t want to adhere to this limitation for the sake of robustness. My thinking was that some newer game data files may not adhere to this arbitrary convention and cause breakage.

The Basic listing was for an earlier version of the data format, which was basically Basic DATA statements. The underlying data structure wasn’t too different though. I haven’t bothered to transcribe the two games available in the original format, since it’s a bit too much of a time-consuming and error-prone activity at the moment. (It would be a fun project, at some point.)

Not sure if this answers the questions properly :slight_smile:

That’s fun to hear. I think there are probably a lot of undiscovered and obscure games that use the Scott Adams format still out there. It’s a simple system to get your head around, and given the availability of authoring systems and documentation, I find it hard to believe that we’ve seen all there is already.

I’ve been toying with a user friendly authoring system for Scott Adams format games for what seems like forever. Perhaps, it’ll be done one day. The basic structure of a Scott Adams interpreter could also lend itself quite well to non-typing user interfaces on smartphones or a voice recognition assistant. Perhaps there could be an interesting future for the format as a whole. I’d like to think so :slight_smile:

CASA - The Classic Adventures Solution Archive, is the right place for that.
http://www.solutionarchive.com/list/system%2C11/

Some game databases would need to be cleaned and completed: some header and trailer are incomplete. There is a data structure problem in recent games, they cannot be played with the Adams interpreter 8.5 for TRS-80.

I agree with you. But what the Adams system may lack is the ability to intercept the player’s movements.

I had decompiled adv05 “The Count”, and other games, with The Adventure System instruction set. It’s simple and readable and very useful to solve and fixe game.
In my post in SPOILER:SHOW
https://intfiction.org/t/if-archive-hugo-downloads/59/1

Ok. Here is a trickier problem. If I have an action with more than 4 instructions it’s split with 3 instructions + “CONT” in the action and the rest is pushed to an “occur 0%” directly after with the rest of the instructions.

Example:

ident 1
version 416
wordlen 3
maxload 6
lighttime 125
unknown1 5953
unknown2 819
start forest
treasury forest

room forest "forest"

action SAY HEL
	set_flag 2
	set_flag 2
	set_flag 2
	set_flag 2
	print "Hello Sailor!"

Plays like this (with debug):

I'm in a forest


DEBUG: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
DEBUG: 0 0 0 0 0 0 0 0 125
Tell me what to do
say hello

DEBUG: Action 0. verb 2 (SAY), noun 7 (HEL) (CONT 0), ""
DEBUG: Condition 0 Par with parameter 2
DEBUG: Condition 0 Par with parameter 2
DEBUG: Condition 0 Par with parameter 2
DEBUG: Condition 0 Par with parameter 0
DEBUG: Condition 0 Par with parameter 0
DEBUG: Command code 6 SETz
DEBUG: Command code 6 SETz
DEBUG: Command code 6 SETz
DEBUG: Command code 21 CONT
DEBUG: 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
DEBUG: 0 0 0 0 0 0 0 0 125
Tell me what to do

If you try adventure #3 “Mission Impossible” and frisk the dead saboteur he never drops the map, the case or the leaflet and you never get the message!

Source (decompiled with scottkit):

action FRI SAB when present saboteur and !exists envelope
	drop envelope
	drop yarn
	drop maintance
	continue

occur 0%
	drop map
	drop case
	print "Something fell to the floor."
	drop leaflet
	comment "FRISKING SABOTEUR"

Show like this in perlscott:

Tell me what to do
fri sab

Tell me what to do
look

I see nothing special.
I'm in a yellow room. Visible items here:
Yellow door with tv camera over it. Empty manila envelope. Piece of yarn. Picture of saboteur stamped -window maintance-. Dead saboteur.
Obvious exits: SOUTH

Tell me what to do

should this not work in 4.6? But my copy of Adventureland have a “CONT”?

Anyhow, the “CONT” instruction doesn’t seem to work.

I have a possible solution to the “CONT”-problem. I have logged a ticket at the project - PerlScott

1 Like

That issue is now fixed. Thanks for the feedback! The fix isn’t very elegant but it works, and it’s hard to tell how it was solved originally.

It seems likely that the “continue” command may have been introduced with adventure #3. (Even though commonly available files for adventure #1 and #2 use continue, they didn’t do so originally.) If the first release of adventure #3 was bundled with a Basic interpreter on TRS-80 that supports “continue”, the exact mechanism could be determined, but I haven’t tried to verify that.

Update: I’m clearly full of it, when it comes to this. Continue seems to be part of the original implementation, and i just failed to translate the functionality correctly, somehow, and my memory was a bit hazy here.

1 Like

I’ll try it now. I’m testing “Ghost King” in it now. Let’s see if I’ll can finish it in PerlScott!

Ok. I played a little bit and I’m sorry to report that the fix broke something.

Not every item is “gettable”. If you test Adv #3 and move west, west from your starting point and try to pick up the pail it’ll fail.

I think it’s the line 1254 that is the problem because if I remove that line everything seems to work.

if ( $word_action_done == $TRUE ) { return 1; }

I’m of course not certin what this line is there for so removing it might cause other problems…

Another problem is command 23 BYx<-x (put_with). It takes two items as parameters and both ScottFree and SkottKit put item1 at item2:s location. PerlScott does it the other way around. In Adv #2 there is:

occur 30% when present Parrot and !present crackers and !present pirate
	print "Bird flys off looking very unhappy"
	put_with Parrot crackers
	comment "BIRD FOLLOWS CRACKERS"

I’m also logging this in GitHub.

1 Like

Thanks a lot for this! Sometimes maintaining old code is like playing whack-a-mole :slight_smile:
Corrected the two problems you mention above, and fixed another problem that was caused by the “continue” fix.

1 Like

Thanks! I’ll try it tomorrow.

Ok. You got another mole to whack.

It’s still the “continue”-command. The continue doesn’t work if your action only have a verb and not a noun.

I think the return-statement on line 1272 should have a condition just like the return-statement on line 1280.

Sorry…

Haha, thanks a lot - again! That should be a quick one line fix at least. :sweat:

I agree, and it’s been corrected just like you said. I do accept pull requests, if you feel that there’s anything else that needs correcting and you don’t feel like waiting for me to wrap my head around it. :slight_smile:
Thanks again!