Experiment: Scott Adams to Dialog translator

Do you ever get a random whim that won’t let you rest until you code it? I noticed that the Z-machine versions of the old Scott Adams adventures are notoriously bad, but the execution style of his language is pretty similar to Dialog—run through the rules in source code definition order, try each matching one in turn, stop on the first success. So I was curious if it would be possible to translate the old files mechanically into Dialog code, despite all the limitations of the language.

Turns out you can! The hardest part was making the translator choose useful object names for the rooms and items, without resulting in invalid Dialog code, and kludging together some sort of word-wrapping when Dialog really doesn’t want to make that possible. For example, here’s Adventureland.

The repository includes Dialog versions of the first 11 adventures (*.dg), plus compiled Z-machine versions (*.z5) and HTML-ified Parchment versions (*.html). The Makefile includes instructions on how to use the code.

However, I don’t really know these games well enough to test them. I’ve made sure it’s possible to reach the end of Adventureland using a walkthrough, but for the rest, haven’t done anything beyond ensuring it compiles. So please, take a look, try them out, and let me know how they work!

13 Likes

That is just crazy sauce.

2 Likes

To be clear, that’s intended as a compliment.

2 Likes

That is very true! And the games map very nicely to Dialog (from what I’ve looked at so far).

I think the “(carried X) (or) (here X)” construct would be nicer as a single predicate in the library.

I really appreciate your “scottlib.dg” library, the standard Dialog library is pretty big and hard to understand, having this smaller and simpler library will be very useful for me.

Big thumbs up from me :+1:

1 Like

I tested Adv05, “The Count” a bit, because I know it has a tricky bit where you light your match in a dark place and you only can see the room description for a limited time.

Here is a transcript (there's also some strange casing going on, but I guess they are a SA feature).
Adventure 5, version 1.15, serial 250106
Dialog translator version 0.1, Dialog compiler version S/
Scott Adams Dialog library 0.1 by Daniel Stelzer

This game is generated from the original Scott Adams
database file, with only a few modern conveniences added:
UNDO, RESTORE, RESTART, SCRIPT ON, SCRIPT OFF. Only these
exact words are recognized, so if they conflict with game
commands, add extra letters: to the game, UNDO and UNDOXX
are indistinguishable. Report any issues to Draconis on
the forum!

[Press a key] 
I've a hunch I've been robbed!
I see I was put to bed. Its AFternoon & I overslept!
> 
Tell me what to do?
> l
You use word(s) I don't know!
> open eye
You use word(s) I don't know!
> get up
OK
I see I was put to bed. Its AFternoon & I overslept!
My neck looks BITTEN!
> get she
OK
> get up
OK
> n
OK
> w
OK
> go dum
OK
> rai dum
OK
> go roo
OK
> get gar
OK
> get mat
OK
> inv
I'm carrying:
Sheets. Sulfur mAtches. 2 small holes in my neck.
  Dusty clove of garlic.
> go dum
OK
> low dum
OK
> low dum
OK
> go roo
OK
> d
OK
> tie she
Tell me to what? i.e. "TO TREE"
> to rin
OK
> cli she
OK
> light match
The match flares up briefly...
[Press a key] 
and then goes out!
> 

I think this is the use of action 88, “Delay”. In my Zil-wrapper for SA-games (scott2zil) I use the z-opcode read with a timed input, like this

<ROUTINE EXECUTE-INSTRUCTION (ACTION-ID CODE "AUX" STORED-TREASURES ITEM-FOUND NOT-FIRST-ITEM CURPOS ARG1 ARG2 TEMP)
  .
  .
  .
	;"88 DELAY - pause - Wait 1 seconds"
	<COND (<=? .CODE 88>
		<DELAY>
	)>
  .
  .
  .
>

<ROUTINE DELAY ()
	<INPUT 1 10 ABORT-WAIT>		;"Wait for input 1 s (10 x 0.1 s) then call a routine that returns true and aborts the input."
	<RTRUE>
>

<ROUTINE ABORT-WAIT () <RTRUE>>

This is much closer to how it worked in the original, but maybe this isn’t accessible from Dialog?

EDIT: I looked it up in the manual, and (get key $) doesn’t support it, it seems…

Yeah, Dialog doesn’t support real-time delays, so I made it wait for a keypress instead. I’m just going to pretend my main concern was accessibility—this makes it easier to use with a screen reader, for example, or in something like ClubFloyd!

Honestly it might be; my main concern was that I would always forget the difference between “here” and “present”, so being explicit about it helped me remember.

Actually, you might know the answer to this: I’d originally had a definition like this in the library, for readability.

@($Obj is at $Parent)
    *($Obj has parent $Parent)

But this would crash the compiler unless I removed the multiquery, which means I have to use the raw ($ has parent $) in all the multi-queries in the library. Any idea why?

Perhaps some combination of (a) being used in an access predicate, (b) the query is a special built-in thing, (c) the query is a dynamic predicate thing.

That would make sense, but it doesn’t seem to cause a problem with the library’s @($Obj is $Rel $Parent). Maybe I just need to set a useless flag alongside it…

One small issue I noticed is that the upper window may get out of date when an action moves an object.

For example: in Adventureland, go to the shore of the lake and GET FISH – it will often escape back to the lake, but the item listing will not show it as being present.

1 Like

I have made a version of the library which implements a simple screen model: no status bar, everything in the lower window. It also lists objects in rooms and your inventory differently, one object per line and indented, more like the old Infocom games.

This package contains “otherlib.dg” and the 11 games built for the Z-machine:
otherlib.zip (209.1 KB)

1 Like

Good catch! I need to call (show room) if something is moved to the location too.