Scott Adams interpreter discrepancies

I’ve been playing around with ScottKit and PerlScott, and I’ve noticed that they handle the light timer/countdown differently.

If you compile the following ScottKit code and play it in ScottKit and then in PerlScott, you’ll find that the command-sequence GET LAMP, LIGHT LAMP, DROP LAMP, LOOK will result in the light running out in ScottKit — but in PerlScott the light will shine indefinitely until you pick the lamp up again!:

action score: score
action inventory: inventory
action look: look

room chamber "square chamber"

item lamp "old-fashioned brass lamp"
	called "lamp"

item lit_lamp "lit lamp"
	called "lamp" nowhere

item empty_lamp "empty lamp"
	called "lamp" nowhere

lightsource lit_lamp
lighttime 3

action light lamp when present lamp
	swap lamp lit_lamp
	print "OK, lamp is now lit and will burn for 3 turns."
	look

occur when flag 16
	clear_flag 16
	swap lit_lamp empty_lamp
	look
	comment "The engine sets flag 16 when the lamp runs out"

It seems that PerlScott decrements the available-light counter only when you’re carrying the lamp, whereas ScottKit seems to decrement the counter whether you’re carrying the lamp or not.

Which behaviour is “correct”? If I were starting from scratch, then I would tend to think that the behaviour I’d implement would be ScottKit’s, simply because it seems more realistic that a lamp would continue to run down even though it’s not being carried!

PerlScott’s behaviour is probably due to the codebase it’s derived from, which I believe is the v4.6 interpreter in BASIC, for Pirate Adventure, as published in BYTE magazine. My BBC BASIC port of BYTE’s Pirate Adventure behaves in the same way as PerlScott, but I wonder if PerlScott’s behaviour differs from that of the latest iteration of the Scott Adams interpreter, which was at least v8.2, I think…? In contrast, perhaps ScottKit behaves in the same way as the latest version of the terp and hence is compatible with the most recent of the official Scott Adams game releases…?

EDIT: I compiled the test game code (above) with ScottKit, manually edited the resultant .sao file, and changed the filename extension to “.dat”. Attached.

advent-q9-testlight-edited.dat.zip (500 Bytes)

2 Likes

Thanks for bringing this up. This is an excellent observation. The light source logic is one of the things that I understand the least, and it’s a small source of bad conscience. There’s an imaginary post-it note stuck to the back of my mind saying “light source needs further investigation”. :slight_smile:

I agree that the ScottKit behavior is more common sense. ScottFree exhibits the same behavior as the ScottKit interpreter here. I always assumed ScottKit was based on ScottFree.

Another dissimilarity between ScottKit/ScottFree and PerlScott/tensodoct, is that ScottFree doesn’t print the Light runs out in 1 turns! warning that the original version 4.6 interpreter has, unless you specify the -s commandline option. I can’t find a way to enable this in ScottKit.

It would be good to try this on a later “official” interpreter. I’m pretty bad at using TRS-80 emulators though.

I seem to recall from semi-recent discussions that the original BYTE listing was later found to have various bugs (like, both in the code and in the listing?) that needed cleaning up, this certainly sounds like one of them.

My feeling is that ScottFree should earn the benefit of the doubt (particularly but not limited to in a case like this where a tiebreaking opinion is needed) as far as “what should a reasonably-formatted SA-style gaming experience be?”, particularly in a case like this where it also lines up with basic real-world expectations.

1 Like

Yeah, my personal gut feeling is that ScottFree is probably as close to a reliable reference implementation as we have. I’m mostly interested in in “why”, “when” and “how” these things work as they do, for the sake of pure curiosity. If nothing else, it feels a bit uninspired to simply copy ScottFree. :slight_smile:

2 Likes

So am I. But against all odds I managed to get something working. Using TRSTools, I added a slightly amended copy (attached) of the compiled version of the code from my original post to a TRS-80 disk-image which I had found a while ago.

The disk-image in question was called “adams2_80sssd_jv1.DSK”. Don’t ask me where I got it from. I can’t remember. I must have picked it up on my cybertravels at some point. But there seems to be a copy of it here.

The disk-image seems to contain Bruce Hansen’s ADVEDIT together with several of the Scott Adams adventures in TRS-80 .DAT format (albeit without the actual “.DAT” filename extension!). I gave my little test program the filename “ADVENT/Q9” and added it to the disk-image.

I was then able to run the “ADV/CMD” program on the same disk and play my test adventure by entering “9” when prompted. Screenshots follow:

ADVENT.Q9.zip (458 Bytes)

3 Likes

Excellent investigation! That’s a thing that needs fixing then. :slight_smile:
Also good to know that the “Light runs out in XX turns” warning stuck around, and that it can just be left as-is in PerlScott/tensodoct (and also your BBC BASIC implementation, I assume).

1 Like

The manual for Hansen’s ADVEDIT knows of two SA adventure “driver” (interpreter) programs: ADV/CMD and ADVENTUR/CMD. The latter is described as “Scott Adams’ ADVENTUR program”, and I’ve now tracked down a copy, and I can confirm that it exhibits the same light-rundown behaviour as ADV/CMD.

The attached TRS-80 disk-image contains two copies of my test game, ADVENT/Q9 and ADVENT/D9. The latter is the file that’s recognised by “Scott Adams’s” ADVENTUR/CMD interpreter. (Enter “9” to play my test game.)

Btw, I discovered a couple of possibly interesting tidbits while trying to get the test game running in TRS-80 emulation:

  1. ADV/CMD won’t accept a value of “-1” for the inventory limit (the maximum number of objects the player can carry in the game). I suspect ADVENTUR/CMD won’t accept “-1” either. But “-1” seems to be ScottKit’s default when you don’t specify a limit. I manually edited the .sao file to change the value to a positive integer.

  2. ADV/CMD (and BYTE’s v4.6 Pirate terp (and probably ADVENTUR/CMD too)) won’t recognise the automatic action in my test game unless it precedes all the non-automatic actions. (The auto action in my test game is the one that begins “occur when flag 16”.) I suspect that this is an optimisation to speed up the processing of auto actions on 8-bit machines (because the terp can stop scanning for auto actions once it hits a non-auto action, which will have a non-zero verb-code). But ScottKit placed the auto action in my test game at the end of the list of actions, so I had to manually move it to the beginning before ADV/CMD would find and execute it.

  3. [See later post, below.]

adams1_ahope1_test.DSK.zip (61.2 KB)

Item 2 sounds familiar from feedback I was hearing about the experiments making Ghost King run on classic interpreters.

2 Likes

I forgot to mention:

  1. The checksum. ADV/CMD refuses to run the game if the checksum (the final integer in the game data file) is incorrect! Fortunately, the ADVEDIT manual explains how to calculate it.
1 Like

Could you please post the compiled DAT-file for your testprogram?

I would like to test it in scott2zil and I don’t have a working ScottKit for the moment (yes, I’m that lazy…).

Adams 2

1 Like

If I remember correctly, Advent/D is the format of Advedit and Advent/Q is the format of Scott Adams’ driver; it is easy, with a hexadecimal editor, to replace /Q by /D, by searching ADVENT/ in the interpreter binary to have only one format.

It’s the other way round:

Now attached to original post.

1 Like

Thanks!

Yes, that’s right.

The point of changing /D by /Q in Adams’ interpreter is to be able to edit the game file with The Adventure System to make changes, but also to test the interpreter without having to rename the file. That’s what I was doing and it seemed very useful.

Found some more terp differences. It seems that ScottKit and PerlScott don’t handle the getting of objects in the same way as the allegedly official Scott Adams terp “ADVENTUR/CMD”.

Consider the following ScottKit code:

start cave

maxload 10

action score: score
action inventory: inventory
action look: look

occur when !flag 1
	print "Welcome to this test adventure."
	set_flag 1

room cave "cave mouth"

item fox "a fox"
	called "fox"
	at cave
	
item box "a box"
	called "box"
	at cave

item bat "a bat"
	called "bat"
	at cave

item hat "a hat"
	called "hat"
	at cave

action get fox when !carried box
	print "Can't get fox when !carried box"

action get bat when carried hat
	get bat

Here’s what you get when you compile the code in ScottKit, tweak the resultant .sao file to get it into .DAT format, and load the .DAT into Scott Adams’s TRS-80 terp ADVENTUR/CMD:

Those results agree with the results from (a slightly updated version of) BYTE’s v4.6 Pirate terp.

But here’s what you get when you play the .DAT file directly in ScottKit and PerlScott respectively:

It seems that ScottKit and PerlScott don’t handle (the “interception” of) AUTOGET (and AUTODROP?) in the same way as ADVENTUR/CMD.

(I’m presuming that the copy of ADVENTUR/CMD I’m using is a copy of the official Scott Adams terp from way back when. But of course you can never be 100% sure of things like this such a long time after the fact, and with files downloaded from various randoid repos.)

This is the output when I run your first example in scott2zil:


There is a small difference, but it should be easily fixed.

Thanks for spotting this. Now on to test your second example…

Can you explain in plain words what the intention of the bat/hat business is? I’m struggling to understand why that code would exist.

1 Like

The bat/hat test occurred to me after I found that the fox/box test gave different results in different terps.

The fox/box test is adapted from code I found in one of the test games in the ScottKit tutorial, but it seems to be a realistic code example (I think I’ve seen something similar “in the wild”): if you want to prevent the player from taking an object (e.g. the fox) unless they’ve already picked up a different object (the box), then you have to explicitly add code to allow the fox to be picked up once the box is being carried, or else the official terp (ADVENTUR/CMD) will never allow the player to pick up the fox! As the second screenshot shows.

The hat/bat example just flowed as a logical consequence of the way that ADVENTUR/CMD handled the fox/box test. I’m not saying the hat/bat example is code that you’d use in a real game, but it is another example of how ScottKit and PerlScott’s behaviour diverges from that of ADVENTUR/CMD.

(EDIT: Basically, the hat/bat code is another way of achieving the same end as the fox/box code. What the hat/bat code does is prevent the player from getting the bat unless they’ve already picked up the hat. But I’m not sure that Adams really intended that sort of scenario to be coded in this way because when you do pick up the hat and then the bat, the ADVENTUR/CMD terp doesn’t print any sort of response on screen at all, even though it has finally allowed you to take the bat…!)

1 Like