Style | StandardCards

Planet Interactive Fiction Last Update: Thursday, 22. January 2026 09:01

My So Called Interactive Fiction Life - Jan 22

Little Bits and Pieces

In the last week I've been play-testing the port of Dungeon which has exposed many things about Sharpee and the Dungeon implementation. Many many things.

Just the first ten to twenty turns of Dungeon have uncovered a lot of issues. The troll logic is actually quite complicated. Had

7 hours ago

In the last week I've been play-testing the port of Dungeon which has exposed many things about Sharpee and the Dungeon implementation. Many many things.

Just the first ten to twenty turns of Dungeon have uncovered a lot of issues. The troll logic is actually quite complicated. Had to scour through the 1981 source for that logic.

I clarified with Claude that events in Sharpee are not true Domain Events and certainly not pub/sub events. They are Command Events and though they bear a striking similarity to Domain Events, there is not way to replay a list of them to reach the current state of the game. But this clarification cleaned up a lot of confusion in the layers and was a surprisingly easy refactor.

We refactored meta commands to execute outside of normal turn processing.

We implemented save/restore/restart/version/diagnose.

We added transcripts to the web client save command (it copies inner HTML, compresses it, and stores it with the save instance).

We added a proper banner, although I just realized the IFID is not displaying.

We added the grue->death logic.

We added the attic block (must be two items and one has to be the lamp).

We implemented dual mode for entities. The author can create their story using string literals OR push all strings through language packages and provide multilingual support and the client can switch languages mid-game.

We implemented player character variability so the author can define the PC, their identify, and switch between player characters at any time.

We fixed the leaflet and ABOUT text to match this implementation.

We implemented proper build versioning to platform, story, and client and created bash scripts to automate builds.

I'm sure I'm missing something, but a lot of nit picky changes that help move Sharpee and Dungeon to completion.

7 hours ago

Renga in Blue - Jan 21

PRISM (1982)

PRISM is an ISM Storydisk which tells the wonderous tale of the theft of the three ancient Keys of Color, and the adventures of the young boy who must seek them in the monstrous kingdom of Yolsva, Plane of Darkness. All is chaos, and the story contains many levels of hidden meaning through which the […] 19 hours ago

PRISM is an ISM Storydisk which tells the wonderous tale of the theft of the three ancient Keys of Color, and the adventures of the young boy who must seek them in the monstrous kingdom of Yolsva, Plane of Darkness. All is chaos, and the story contains many levels of hidden meaning through which the Keys may be found and reunited with the prism. When this occurs, and only then, can the mysterious and magical ending of PRISM unfold.

— From the instructions for PRISM

Six years ago this blog tackled the game Alkemstone (1981), a contest leading to a buried treasure with clues in an Apple II game (the Alkemstone itself did not have value, but you could win money from the company for finding it). A year after Alkemstone there was another Apple II program, but this time hiding real buried treasure. As far as anyone knows this treasure is still buried.

In 1980, Stephen Brightbill founded International Software Marketing, Inc. in Syracuse, New York. They launched with the product MatheMagic in 1981, software that “harnesses the power of your Microcomputer to perform simple arithmetic to sophisticated mathematics.” It had versions for DOS, CP/M and Apple II and sold for $89.99.

Where this put them on their main product line was a 1982 extension, Graph Magic, which allowed for “figures in graphic form and full color”. From there they followed with Color Magic and essentially pivoted to graphic presentation software for the duration of their lifetime (folding in 1992, according to Brightbill, due to “competition” and the “rise of Windows”; they were DOS-only by this time).

The “International” part of the name is significant as while it might have been a little aspirational, they did list a UK office branch in their ads. This connection means they likely had strong familiarity with the book Masquerade which was still being a smash hit at the time.

I bet you can do something with books that no one has ever done before.

— Tom Maschler of the publisher Jonathan Cape, directed at the artist Kit Williams, author and illustrator of Masquerade

I’m not giving a history of Masquerade but rather deferring to Jimmy Maher; the important points are that it was a real-life treasure hunt for a buried hare designed by a real jeweler, and the hints to find it were inside the pages of a lavishly illustrated “children’s” book.

We’ve already encountered several “contest games” on this blog, including the previously mentioned Alkemstone, but also Krakit and Pimania. While it is almost certain they happened because of Masquerade-mania, none of them tried to match the form factor. Alkemstone had clues hidden in a first-person maze, Krakit just had a series of puzzles on ZX81 (and no buried treasure!), and Pimania was an adventure game where the clues suggested a particular time and place to go (but again, nothing buried).

That’s not the case for PRISM. PRISM has not just one buried treasure, but three: keys designed by the Syracuse Jewelry Manufacturing Co.

Blue: 18K gold key with 3/4 carat Blue/White Diamond

Red: 14K gold key with 3/4 carat Ruby

Yellow: 10K gold key with 3/4 carat Topaz

The value given by a 1983 review is $15,000 (I believe that’s all three keys together).

The people involved (besides presumably the CEO) are all listed. Mark Capella and Ronald Roberts are “co-designers”, Mike Sullivan did art, and Carol Keller did editing. We’ve seen Mark Capella here before; Mike Sullivan of Microstar Graphics later did the disk magazine PC Life. Relevant for today, here’s Sullivan’s “Musical Christmas Disk” called ‘Twas the Night Before Christmas disk from 1987 (if it embeds correctly, it is interactive and you can try it right in the browser):

If you’re wondering how a business-software company got involved with making a game, in some sense, it isn’t a game at all. The software is merely a “Storydisk” for Apple II which is a “slideshow” much like the ones people could make with their own software. It presents a book that bears strong similarity to Masquerade and hence PRISM represents the closest thing Masquerade had to an actual clone.

Now, a huge disclaimer: just like Alkemstone, it is quite possible the contest landed somewhere too ambiguous to solve (explaining why they never announced a winner, even though the company lasted for ten more years). On the other hand, we discovered things out of Alkemstone nobody had seen before, and there’s three locations rather than just one, so it is still faintly possible something of real money value may come from this exploration. I cannot prevent anyone searching on the basis of information here. I will state myself outright if I find anything myself personally I will be donating it to a gaming museum like The Strong. I cannot speak for anyone else. You can assume anything posted here is public.

The pages that do have art have some animations, so while I’m going to be showing pages from the “book”, there’s going to be a little more going on than with Masquerade; it’s even possible there’s “hidden keypresses” or the like which are part of the game. At least in general the only options are “left arrow” and “right arrow” to move between pages.

Not including the start and end, there’s forty pages total. I’m going to just give the first seven for now, but I’ll give out later sections in larger chunks. I expect to make at least six posts and possibly a few more; feel free to chime in with theories in the comments about what’s going on.

For the text-only pages I’m going to give text rather than screenshots, although I did want to show the first page off as an example.

Hubert stretched luxuriously in his comfortable bed, rubbed his eyes and met the brilliant colors of the morning with a smile. His first thought, as always, was of his favorite little puppy, Uanna. A whistle, a clap of his hands, and she was there on the coverlet, her playful green eyes urging him to get up and about for their morning frolic. Like any hearty lad, Hubert dressed without losing a moment… looking forward to the fun and sport he knew lay ahead. Calling the pup to his heel, he strode happily through the door.

It was a glorious day in spring, and the sun shone down on the myriad and beautiful colors of the world. The brightly clad people of Hubert’s town seemed to bloom with the splendor of the flowers around them. In the golden sunlight, the gentlefolk exchanged pleasantries and basked in the splendor of Nature.

I find the transcription much easier to read!

The rays do some color cycling.

The first graphical page; notice the words along the border as well as colored letters. These are both clones of Masquerade, although there is no implication they get used in the exact same way (the solution hadn’t been released yet of the original book!) Hence we have the curious situation of someone copying what a puzzle looks like but quite possibly doing something very different with it.

Hubert, a small but sturdy lad, smiled as he watched the congenial fellowship of his townspeople. Around them, the festively colored birds chatted as they built their nests, and the animals lazily stretched their muscles after a satisfying winter’s nap. With Uanna following close behind, the boy whistled as he strode down the road, with not a care in his mind.

And it was then that. . . A sudden hush descended upon the street. Hubert cast an anxious glance about, then started in disbelief. Around him, HIS WORLD WAS CHANGING !!!

Two more text pages (page 5 and page 6), and then I’ll give the image after, and that’ll be enough for today.

Where the warn golden sun had beamed, only a white blaze appeared. The gaily clad people looked down at themselves in disbelief as the colors slowly drained from their brilliant clothes. Before their eyes, their splendid world was turning black and white and every shade of grey in between!

Young Hubert felt a chill run through him as he witnessed this stupendous horror. ‘How can this be?’ he wondered. Even the animals seemed to sense the transformation as they scampered back into their burrows. The townsfolk silently dispersed, shaking their heads in wonderment.

Suddenly, Hubert found himself alone on the stark, black pavement, his puppy pressed up against his leg in her anxiety. The once, and so recently colorful world was rapidly beginning to resemble the pallid grey images on one of his grandmother’s old photographs. As he turned the corner in the direction of his home, he found himself confronting the gigantic figure of a strangely garbed individual. The apparition wordlessly reached for Hubert and as he lifted, they both seemed to fade into nothingness.

The above images animates with the two figures disappearing:

I’m stopping here (page 7) to give people time to comment and will continue on page 8 next time.

19 hours ago

The People's Republic of Interactive Fiction - Jan 19

January meeting (online)

The Boston IF meetup for January will be Wednesday, January 21, 6:30 pm Eastern time. We will post the Google Meet link to the mailing list on the day of the meeting. 3 days ago

The Boston IF meetup for January will be Wednesday, January 21, 6:30 pm Eastern time. We will post the Google Meet link to the mailing list on the day of the meeting.

3 days ago

Renga in Blue - Jan 18

Sword of Raschkil (1981 / 1983)

Written in 1981, not published until 1983. Take your pick. I didn’t have this one on any of my lists but El Explorador de RPG recently pointed it out; since it was not preserved otherwise, gschmidl then put the source of the game on his Github. It was printed in the magazine H & E […] 4 days ago

Written in 1981, not published until 1983. Take your pick. I didn’t have this one on any of my lists but El Explorador de RPG recently pointed it out; since it was not preserved otherwise, gschmidl then put the source of the game on his Github.

It was printed in the magazine H & E Computronics, which has barely had any mention here at all, so a brief history–

From the first issue of the newsletter (July 1978) that would eventually be the magazine called H & E Computronics.

Howard Y. Gosman, former math teacher out of New York, ran one of the first personal computer magazines kicking off in July of 1978; their June 1979 issue specifically bragged they were “the first TRS-80 PUBLICATION to last a year” as well as “the largest publication devoted to a single computer (over 16,000).”

This is an oddly specific claim meant to work around existing alongside things like PCC’s newspaper/magazine which launched in the early 70s and Kilobaud launching in January of 1977 (“The Small Computer Magazine”). One of their main competitors was Softside which was still TRS-80-only from 1978 through 1979 although it launched later (October 1978). Softside has been mentioned here now quite a few times; they printed, for instance, Dog Star Adventure, the first full-parser adventure game in a magazine.

Softside tended to be quite game-friendly; with the exception of the tax software from the February 1979 issue, every issue from ’78 through ’79 featured a game on its cover.

While H & E included games once in a while, they tended to be a seller of “serious” software; their catalog was heavy on the business side and they even kept this going past their own magazine’s existence, selling their own VersaBusiness software into the late 80s on a variety of platforms.

They did have one gaming landmark worth noting, possibly a side effect of their “serious” positioning: they have the first ad I can find for an adult game. Back in that June 1979 issue the company Phase-80 includes a mention of their games Strip Dice and Strip Concentration. (“Each player must follow ALL directions of the computer … The game may be played by ‘CRT’ light if desired.”) H & E Computronics later sold the infamous “activity catalog” Interlude, which you might remember from City Adventure.

The Phase-80 ad notably beats out the first commercial adult game in Japan, Yakyūken, although Yakyūken is far more significant in being a single-player erogē rather than a “party game” facilitated by the computer. (Joey Wawzonek has a terrific essay here about the game, answering the question “why are we stripping while playing rock paper scissors in the first place?”)

After their August 1983 issue, the publication (not company) of H & E merged with Basic Magazine (formerly 80-U.S. Journal, another magazine founded almost exactly the same time as H & E). Today’s game, Sword of Raschkil by Mac Vaughn, came from one of their last issues, May 1983. Comments from the code identify Vaughn as being at Henderson High School in Georgia.

Our author is standing second from the right, clearly demonstrating that Math is Cool. Via one of his school yearbooks.

True to form, the magazine the game appears in has a super-serious cover. This seems to be why their games have generally been overlooked in the various TRS-80 archives, even though this isn’t the only game in this issue (although it is the only adventure). From a different issue, Castle Adventure is another game I need to loop back to that again seemingly was never archived.

Our objective is to find the long-lost sword of a warrior from the distant past.

Several hundred years ago, the warrior Raschkil was slain in battle. It was rumored that he had had a magical sword, but when it was not found on him, many assumed that it had never existed.

Just a few months ago, you were digging in a garden near your small house when you unearthed a small, unlocked iron box. Within it was a map giving the approximate location of the sword of Raschkil! How did it get under the soil of your garden? No one will ever know.

You decided to find the sword, and had little difficulty finding the area on the map: an area surrounding a small castle. Now, using your wits, you must find the sword within the area named. Any further instructions are included in the program. Good luck you’ll need it!

We start, as is tradition, in a forest.

The game fortunately does not start with a maze; the forest is tiny, and it leads to an even tinier castle. The starting area map first, though:

Just to the south is a “hole” where ENTER HOLE puts you on a ledge of a bottomless pit, with a staff you can take. You can only get out with CLIMB LADDER so you can’t take the ladder with you.

Heading further south, there’s a meadow followed by a large oak you can climb. Along the way you can pick up a “golden leaf” and the top of the tree has a jar because … squirrels need jars?

Back to the start, heading east you can find a pool; you can FILL JAR at the pool.

I was expecting the water to be toxic and kill you. I’ve been in too many death-every-corner games lately, I suppose. You can also POUR WATER in any room where it “makes a puddle on the floor.”

The game also lets you SWIM, and I was briefly worried I had a broken-code issue for a moment afterwards.

YOU ARE SWIMMING IN A POOL OF WATER.
AT THE BOTTOM OF THE POOL IS A KEY.
? GET KEY
I CAN’T DO THAT AT THIS TIME.

The reason for my concern is I had discovered by now the game has a bug: if you drop any item you can’t pick it up. DROP STAFF cheerfully gets the response of “O.K.” but then trying to GET STAFF yields the response I CAN’T DO THAT AT THIS TIME. I checked with gschmidl who assured me the game was beatable as is, before arriving at DIVE.

Just for reference, my verb list, based on typing in all my standard verbs:

CLIMB, SWIM, READ, DRINK, EAT, FILL, THROW, UNLOCK, LOCK, POUR, JUMP, GIVE, ENTER, DIVE

This was a bit fussy to get because typing CLIMB has the response

I DON’T KNOW HOW TO CLIMB SOMETHING!!!!

which is a touch deceptive. The command doesn’t work without a noun.

With all that taken care of (and shockingly, no DIG command used anywhere, not an understood verb!) let’s proceed on to the castle, which might seem a little underwhelming so far but I expect I’m missing a lot.

Heading into the NORTH WING indicates that you feel a DRAFT, indicating perhaps the author was familiar with Hunt the Wumpus, as to the east is a pit. If you’re holding the staff you’ll levitate; if you don’t have the staff you’ll fall.

Dropping the staff is accounted for.

From the east of the start is a wizard with a sign. I haven’t gotten anything to happen here.

Inside joke, maybe?

Finally, to the south is … nothing. Absolutely nothing.

Again, I’ve been assured the game is beatable, but I’m still starting to worry (given the drop bug) I’m running into some other code-related issue. I’ll take suggestions in the comments if anyone thinks there’s something I missed.

And very special thanks to Ethan Johnson for assistance with getting the picture of our author, Mac Vaughn.

4 days ago

Renga in Blue - Jan 16

Haunted House: Pray Hard with a Vengeance

I’ve finished the game (prior posts here). It turned out I had one bottleneck (the wolf) which opened up the rest of the game, and “puzzles” I was spending time on (like the ghost and the lift) were complete red herrings. I’m unclear if they’re “intentional” or not; we’ve certainly had games before where I […] 6 days ago

I’ve finished the game (prior posts here).

It turned out I had one bottleneck (the wolf) which opened up the rest of the game, and “puzzles” I was spending time on (like the ghost and the lift) were complete red herrings. I’m unclear if they’re “intentional” or not; we’ve certainly had games before where I suspect the author just kept writing, ran out of disk space / motivation, and stopped with loose ends still left in. At least they became intentional, and I’ll explain what that means when I get to the end.

Games Computing, July 1984. Haunted House was renamed The House on the Misty Hill and re-purposed as a type-in for ZX Spectrum. More on that at the end as well.

Matt W. suggested using the generic “food” rather than the crisps with the wolf. Doing anything with the wolf that’s wrong will kill you so I hadn’t thoroughly tested all the items yet.

(The coffin contains a dead body; I tried carting the coffin over to the ghost in case they matched, but nothing happened. I didn’t know yet the ghost was a total red herring. I took the coffin back to the starting point and dropped it. Even though the wolf had left, this annoyed the wolf who came back and killed me. Whoops.)

Getting by the wolf opens up the graveyard, the only other section of the game. Heading directly north leads to a “shovel” next to a “newly dug grave” (shovel is total red herring, and I did waste time trying USE SHOVEL across the map a few places, ugh) and farther north you fall in the grave itself and get stuck unless you have the right item.

Specifically, this is where the rope is handy, although I spent some time trying to THROW ROPE and the like before realizing the game just let me CLIMB while holding the rope and the action after was implicit. The game is not consistent about this (implicit action while holding an item); this comes to give me trouble later.

Heading east from where the wolf was leads to a crossroads but also a vase of flowers.

I rather grumpily realized what was going on here, and took the flowers over to the princess who didn’t want to be rescued. I then dropped the vase of flowers on the ground, the customary romantic gesture.

She now is willing to tag along to be carted over to the front step of the house and dropped off. The vase of flowers incidentally stays in place and is left behind. It’s like the world’s worst dating simulator.

North of the crossroads you get shut into a shrine.

Having prayed earlier, it seemed the appropriate place; it was used to solve a puzzle, not just be a joke!

You are informed if you try to take the statue that you are not Superman. That’ll be the last treasure I get.

With that resolved I could head farther north in the shrine to find “an old rusty handcart” and a small alcove with a treasure.

It immediately occurred to me to take the cart over to the giant statue and try to take it, but I was still getting the same Superman message. It seemed fair that it’d be impossible to take the statue even with a handcart.

Leaving that behind for now, I checked to the east of the crossroads…

Complete red herring.

…and to the south.

Here my running gag finally paid off.

Coventry Live has a 2021 story about a dog who loves Quavers Crisps and eats them out of the bag, with a picture.

This leads, straightforwardly, to an “eerie tomb” with a CRUCIFIX. I nearly had all my treasures!

I still thought, perhaps, either the ghost or man in the stocks would help with the statue situation. It was an odd scenario where the game requires all treasures at a particular spot (at the front of the house) but given how close the statue was to the location it seemed almost ridiculous to require moving it.

I warned earlier about implicit actions being done with held items; this time, the action is not done while holding an item. I tried to use a handcart, but you’re supposed to drop it first, then GET STATUE, and the game will automatically load the cart from there.

I don’t necessarily have immediate issues with red herrings; they can add texture and atmosphere to an environment that can seem all too “neat” and like living in a cryptic crossword. However, the parser was so janky it was very hard to tell if I was supposed to, say, keep trying to move the lift, or keep trying to scare the ghost with the uniform; when a book is visible in one room while held but can’t be examined in another, pretty much anything is possible. Red herrings need to come along with a parser that the player trusts is working like they are expecting.

I tried a little bit of House on Misty Hill and it really is almost exactly the same; some rooms have a little more description (“a dirty kitchen is full of pots which haven’t been washed in years”) but the red herrings are “enhanced”. The man in the stocks cries for help, and the magazine is now a “monster gazette” which seems more likely to be helpful / not a red herring than the old magazine. Thus, Lucas was clearly happy solidifying the red herrings; that doesn’t mean they were introduced intentionally at first, especially given my suspicion this was the first game he wrote. There’s parser jank in Journey of a Space Traveller, but not nearly to the same level.

I checked his later books (or book, the Amstrad and MSX books about adventure programming merely convert the code) to look for comments on his philosophy on red herrings, and found two notes:

Ardent adventurers don’t like games where they lose their lives too often, so don’t go overboard with traps like this one and do try to keep the responses humorous.

Beware, however, of writing too many red herrings into your game as they can waste an enormous amount of RAM.

Death can represent a punch line of sorts; the issue here is that there is no punch line, just hanging puzzles that seem like they are bugs.

In addition to Misty Hill, the game has yet another remix (somewhat) in The Monster’s Final Hour which gets remade yet again into The Monster Returns. I only say kind of because what seems to have happened is two distinct rip-offs, both off the same game: John R. Olsen’s Frankenstein Adventure.

In Frankenstein Adventure, you need to revive the monster (and then kill the monster in the grand finale). Haunted House / Misty Hill instead grabs a few characters from the game, similar to what Peter Smith’s Hitch-Hiker did with the Supersoft Hitchhiker game. The wolf is in both games (with the same death-message, even); the bog you can fall in without a map is in.

The house structure is vaguely similar and there is a secret passage opened essentially the same way. Haunted House then veers course and has the monster already awake (and distracted by some electrodes); it’s like Lucas grabbed a couple themes to start and then went free-form from there.

Monster’s Final Hour (1985, see above) is much more directly a remake of Olsen’s Frankenstein, where the main goal (revive the monster) is maintained. You’ll also notice the verb list is quite different. So while it seems like Monster’s Final Hour might come from Haunted House, it’s really just that Lucas went back to the original source. A diagram to help:

Absolutely staggering. I can see why the games have been so hard to sort out.

We still have many Lucas games in the future, but coming up: another type-in, this one from the United States, followed by an Apple II game involving real buried treasure.

6 days ago

My So Called Interactive Fiction Life - Jan 14

Sharpee Parsing Comparison

Classic IF Systems and Sharpee

A detailed comparison of how TADS, Inform 6, Inform 7, Hugo, and Sharpee handle the journey from player input to executed action.

Overview

All parser-based IF systems solve the same fundamental problem: transform natural language input into game actions. The solutions share common ancestry but

8 days ago

Classic IF Systems and Sharpee

A detailed comparison of how TADS, Inform 6, Inform 7, Hugo, and Sharpee handle the journey from player input to executed action.

Overview

All parser-based IF systems solve the same fundamental problem: transform natural language input into game actions. The solutions share common ancestry but diverge in philosophy and implementation.

Player Input: "put the red book on the wooden shelf"
                            ↓
              [GRAMMAR / PATTERN MATCHING]
                            ↓
              [SCOPE / ENTITY RESOLUTION]
                            ↓
              [VALIDATION / PRECONDITIONS]
                            ↓
              [EXECUTION / STATE CHANGE]
                            ↓
              [RESPONSE / OUTPUT]

Each system implements these stages differently. This document explores those differences without judgment—each approach reflects valid design tradeoffs.


1. Grammar Definition

How does each system define what commands look like?

TADS 2/3

TADS uses VerbRule declarations that combine syntax patterns with semantic requirements:

// TADS 3
VerbRule(PutOn)
    'put' dobjList 'on' singleIobj
    : PutOnAction
    verbPhrase = 'put/putting (what) (on what)'
;

// The grammar IS the action definition
// Verb synonyms defined separately
modify VerbRule(PutOn)
    'place' dobjList 'on' singleIobj : ;

Characteristics:

  • Grammar tightly coupled to action definitions
  • Verb phrases carry semantic metadata (for NPC commands, messages)
  • Slot types (dobjList, singleIobj) encode cardinality
  • Synonyms added via grammar inheritance/modification

Inform 6

Inform 6 uses Verb directives with pattern lines:

Verb 'put' 'place' 'drop'
    * held 'on' noun -> PutOn
    * held 'in' noun -> Insert
    * multiexcept 'on' noun -> PutOn
    * multiexcept 'in' noun -> Insert;

Characteristics:

  • Compact, terse syntax (classic Infocom heritage)
  • Token types define scope constraints: held, noun, creature, multi
  • Multiple patterns map to same action (PutOn)
  • Synonyms listed in verb header
  • Grammar INCLUDES scope requirements (held = must be carried)

Inform 7

Inform 7 uses natural language grammar definitions:

Understand "put [things preferably held] on [something]" as putting it on.
Understand "place [things preferably held] on [something]" as putting it on.

Putting it on is an action applying to two things.

Characteristics:

  • Human-readable grammar specifications
  • Bracketed tokens: [something], [things], [text]
  • Scope hints in token names: preferably held, visible, touchable
  • Actions declared separately from grammar
  • Multiple Understand lines for synonyms

Hugo

Hugo uses verb and xverb declarations with grammar patterns:

verb "put", "place"
    *                           DoVague
    * object "on" xobject       DoPutonGround
    * multi "on" xobject        DoPutAll

xverb "inventory", "i", "inv"
    *                           DoInventory

Characteristics:

  • verb for world-affecting actions, xverb for meta actions
  • Token types: object, xobject (indirect), multi, number, string
  • Routines named directly in grammar (DoPutonGround)
  • Concise, script-like syntax

Sharpee

Sharpee uses a fluent builder API with action-centric organization:

// Action-centric definition (preferred) - ADR-087
grammar
  .forAction('if.action.pushing')
  .verbs(['push', 'press', 'shove', 'move'])
  .pattern(':target')
  .build();

// Phrasal patterns with slot-specific trait constraints
// .hasTrait(slotName, traitType) - constrains which entities match that slot
grammar
  .define('put :item on :supporter')
  .hasTrait('supporter', TraitType.SUPPORTER)  // :supporter slot must have SUPPORTER trait
  .mapsTo('if.action.putting')
  .withPriority(100)
  .build();

// Container operations - same pattern
grammar
  .define('put :item in|into|inside :container')
  .hasTrait('container', TraitType.CONTAINER)  // :container slot must have CONTAINER trait
  .mapsTo('if.action.inserting')
  .withPriority(100)
  .build();

// Direction slots use type constraint, not trait
grammar
  .define('go :direction')
  .where('direction', { type: 'direction' })
  .mapsTo('if.action.going')
  .withPriority(100)
  .build();

Characteristics:

  • TypeScript fluent API with IDE autocompletion
  • Action ID is the organizing principle (not the verb)
  • Verb synonyms declared once per action via .verbs([...])
  • .hasTrait(slotName, traitType) — slot-specific semantic constraint
    • First arg: which slot (:container, :supporter, etc.)
    • Second arg: required trait (TraitType.CONTAINER, etc.)
  • NO scope/visibility in grammar — scope resolved at runtime by action
  • Grammar defines SYNTAX + semantic constraints only
  • Comments in grammar.ts explicitly note: "Scope handled by action validation"

Comparison Table: Grammar

Aspect TADS 3 Inform 6 Inform 7 Hugo Sharpee
Syntax style VerbRule classes Verb directives Natural language verb declarations Fluent builder API
Synonym handling Inheritance Verb header list Multiple Understand Verb header list .verbs([...]) array
Scope in grammar Implied by slot types Token types (held/noun) Token hints object/xobject None (action validates)
Semantic constraints Slot types Token types Token descriptions Slot types .hasTrait(slot, trait)
Multi-object dobjList/multiexcept multi/multiexcept [things] multi Handled by parser
Action binding VerbRule → Action Pattern → routine Understand → action Pattern → routine Pattern → action ID

2. Parsing and Tokenization

How does each system break apart player input?

TADS 3

TADS has a sophisticated tokenizer and grammar parser:

Input: "put the red book on shelf"
         ↓
Tokenizer: ["put", "the", "red", "book", "on", "shelf"]
         ↓
Grammar Parser: Match against VerbRules
         ↓
Best Match: VerbRule(PutOn) with dobj="red book", iobj="shelf"

Key features:

  • Built-in tokenizer handles contractions, abbreviations
  • Grammar is a true parser (can backtrack)
  • Disambiguation happens during parsing
  • Returns structured parse tree with action + objects

Inform 6

Inform 6 uses a two-pass parser:

Input: "put red book on shelf"
         ↓
Pass 1: Tokenize into dictionary words
         ↓
Pass 2: Match verb patterns, consume tokens left-to-right
         ↓
Match: Verb 'put' pattern "held 'on' noun"
         ↓
Scope Check: Is "red book" held? Is "shelf" in scope?

Key features:

  • Dictionary-based tokenization (words must be in game dictionary)
  • Left-to-right pattern matching (no backtracking)
  • Scope checking integrated into parsing
  • Parser decides entity resolution during parse

Inform 7

Inform 7 compiles to Inform 6, but adds:

Input: "put the red book on the shelf"
         ↓
Understanding Phase: Match against Understand patterns
         ↓
Disambiguation: "Which do you mean, the red book or the red apple?"
         ↓
Action Creation: Create "putting red book on shelf" action

Key features:

  • Same underlying I6 parser, but abstracted
  • Richer disambiguation ("Did you mean...")
  • Actions are first-class objects (can be stored, examined)
  • "Deciding the scope" activity for custom scope rules

Hugo

Hugo uses a simple token-based parser:

Input: "put book on shelf"
         ↓
Tokenize: Split on spaces, look up in dictionary
         ↓
VerbRoutine: Match verb, call FindObject for each slot
         ↓
Object Resolution: Search rooms, containers, inventory

Key features:

  • Straightforward, predictable parsing
  • FindObject routine handles scope
  • Less sophisticated disambiguation
  • Fast and efficient for simple games

Sharpee

Sharpee uses a multi-phase approach:

Input: "put the red book on the wooden shelf"
         ↓
Phase 1 - Tokenization:
  tokens: [{text: "put", ...}, {text: "the", ...}, ...]
  Each token gets vocabulary candidates (verb? preposition? noun?)
         ↓
Phase 2 - Pattern Matching (Grammar Engine):
  Try patterns by priority
  Match: "put :item on :supporter"
  Slots: item="the red book", supporter="the wooden shelf"
         ↓
Phase 3 - Output (Parser):
  IParsedCommand {
    action: 'if.action.putting_on',
    directObject: { text: 'the red book', entity: null },
    indirectObject: { text: 'the wooden shelf', entity: null }
  }

Key features:

  • Entities NOT resolved during parsing (text only)
  • Pattern matching is priority-ordered (story patterns > stdlib)
  • Confidence scoring for ambiguous matches
  • Parser output is intermediate representation (IR)

Comparison Table: Parsing

Aspect TADS 3 Inform 6 Inform 7 Hugo Sharpee
Tokenization Built-in sophisticated Dictionary-based I6-based Dictionary-based Vocabulary registry
Pattern matching Full grammar parser Left-to-right I6-based + rules Left-to-right Priority-ordered
Backtracking Yes No Limited No No (by design)
Entity resolution During parse During parse During parse During parse After parse (separate)
Output type Parse tree + objects Populated globals Action object Populated globals IParsedCommand (IR)

3. Scope and Entity Resolution

How does each system determine what the player can interact with?

TADS 3

TADS 3 has a comprehensive scope model:

// Scope is determined by sensory context
class Thing: object
    canSee(obj) { ... }
    canHear(obj) { ... }
    canSmell(obj) { ... }
    canReach(obj) { ... }

// Resolvers determine valid objects
class Resolver: object
    filterAmbiguous(lst) { ... }
    filterPossessive(lst) { ... }

Key features:

  • Multi-sensory scope (see, hear, smell, reach)
  • Resolver classes for different contexts
  • Disambiguation through resolver filtering
  • Scope is property of actor (NPCs have their own scope)

Inform 6

Inform 6 uses scope routines and token types:

! Token types define scope requirements
! held   = in inventory
! noun   = in scope (visible/touchable)
! creature = animate beings
! multi  = multiple objects

! Custom scope via scope_stage
[ InScope actor;
    PlaceInScope(lamp);  ! Always visible
    if (location == dark_room) {
        PlaceInScope(grue);  ! Only in this room
    }
];

Key features:

  • Scope types in grammar (held, noun, etc.)
  • InScope hook for dynamic scope
  • Darkness handling built-in
  • Scope is global state during parsing

Inform 7

Inform 7 abstracts scope through activities:

Definition: A thing is visible if the player can see it.
Definition: A thing is touchable if the player can touch it.

Before deciding the scope of the player when in darkness:
    place the glowing orb in scope.

The carrying capacity of the player is 7.

Key features:

  • Declarative visibility/touchability definitions
  • "Deciding the scope" activity for customization
  • Reaching inside rules for containers
  • Abstracted but still fundamentally I6 scope

Hugo

Hugo uses FindObject and scope flags:

! FindObject searches in order:
! 1. Held objects
! 2. Room contents
! 3. Objects in open containers

routine FindObject(obj, objloc)
{
    if Contains(player, obj) return true
    if Contains(location, obj) return true
    if obj in something && IsOpen(something) return true
    return false
}

Key features:

  • Procedural scope checking
  • Explicit search order
  • Simple, predictable rules
  • Game author controls via routine overrides

Sharpee

Sharpee uses a dedicated ScopeResolver with scope levels:

enum ScopeLevel {
  UNAWARE = 0,    // Doesn't know it exists
  AWARE = 1,      // Knows it exists (heard, smelled)
  VISIBLE = 2,    // Can see it
  REACHABLE = 3,  // Can touch it
  CARRIED = 4     // In inventory
}

// Resolution happens AFTER parsing
class CommandValidator {
  resolveNounPhrase(noun: INounPhrase, world: WorldModel) {
    // 1. Find entities matching noun text
    const candidates = world.findEntitiesByName(noun.head);

    // 2. Filter by adjectives
    const matching = candidates.filter(e =>
      this.adjectivesMatch(e, noun.adjectives)
    );

    // 3. Check scope for each candidate
    const inScope = matching.filter(e =>
      scopeResolver.getScope(actor, e) >= ScopeLevel.VISIBLE
    );

    // 4. Disambiguate
    return this.disambiguate(inScope, noun);
  }
}

Key features:

  • Scope is numeric level, not boolean
  • Resolution is separate phase after parsing
  • ScopeResolver handles all perception logic:
    • Darkness (need light source)
    • Container blocking (closed containers)
    • Distance (same room, adjacent room)
  • Actions specify required scope level
  • Adjective filtering is explicit step

Comparison Table: Scope

Aspect TADS 3 Inform 6 Inform 7 Hugo Sharpee
Scope model Multi-sensory Token types Activities FindObject Scope levels (0-4)
When resolved During parsing During parsing During parsing During parsing After parsing
Customization Resolver classes InScope hook Deciding scope Routine override ScopeResolver
Darkness Built-in Built-in Built-in Manual Built-in
NPC scope Per-actor Limited Per-actor Limited Per-actor

4. Action Validation and Execution

How does each system check preconditions and apply state changes?

TADS 3

TADS 3 uses action methods with implicit preconditions:

class PutOnAction: TIAction
    // Preconditions checked automatically
    preCond = [touchObj, objVisible]

    // Verify phase - soft checks
    verifyDobjPutOn() {
        if (!isDraggable) illogical('{I} {can\'t} move that.');
    }

    // Check phase - hard checks
    checkDobjPutOn() {
        if (getWeight > supporter.maxWeight)
            failCheck(tooHeavyMsg);
    }

    // Action phase - mutation
    actionDobjPutOn() {
        moveInto(gIobj);  // gIobj = indirect object
        say('Done.');
    }
;

Phases:

  1. PreCond - Automatic implicit actions (take if not held)
  2. Verify - Soft checks (illogical suggestions)
  3. Check - Hard preconditions (fail = block action)
  4. Action - State mutation + output

Key features:

  • Implicit actions (auto-take before put)
  • Verify vs Check distinction (suggestion vs error)
  • Preconditions are object properties
  • Failure messages in check phase

Inform 6

Inform 6 uses before/after rules:

[ PutOnSub;
    ! Parser has already checked scope
    if (noun notin player) {
        print "You need to pick that up first.^";
        rtrue;
    }
    if (second hasnt supporter) {
        print "That's not a surface.^";
        rtrue;
    }
    move noun to second;
    print "You put ", (the) noun, " on ", (the) second, ".^";
];

! Objects can intercept
Object -> table "wooden table"
    with before [;
        PutOn: if (children(self) >= 5) {
            print "The table is full.^";
            rtrue;
        }
    ];

Key features:

  • Single routine per action (PutOnSub)
  • Objects intercept via before and after
  • Return true to block, false to continue
  • No formal phase separation

Inform 7

Inform 7 uses rulebooks with explicit phases:

Before putting something on something:
    if the noun is not carried, try taking the noun.

Check putting something on something:
    if the second noun is not a supporter:
        say "[The second noun] isn't a surface." instead.

Carry out putting something on something:
    now the noun is on the second noun.

Report putting something on something:
    say "You put [the noun] on [the second noun]."

Phases:

  1. Before - Pre-processing, implicit actions
  2. Instead - Replace default behavior entirely
  3. Check - Preconditions (stop if failed)
  4. Carry out - State mutation
  5. After - Post-mutation, before report
  6. Report - Generate output

Key features:

  • Explicit named phases
  • "Instead" for complete override
  • Rules can be ordered (first/last)
  • Natural language syntax

Hugo

Hugo uses action routines with informal checks:

routine DoPutOn
{
    if not Contains(player, object)
    {
        "You need to be carrying that."
        return false
    }
    if xobject is not supporter
    {
        "That's not a surface."
        return false
    }
    move object to xobject
    print "You put "; The(object); " on "; The(xobject); "."
    return true
}

Key features:

  • Single routine per action
  • Checks and execution interleaved
  • Return true/false for success
  • Straightforward procedural style

Sharpee

Sharpee uses a strict four-phase pattern:

const puttingOnAction: Action = {
  id: 'if.action.putting_on',

  // Phase 1: VALIDATE - Check preconditions (no mutations)
  validate(context: ActionContext): ValidationResult {
    const item = context.command.directObject!.entity!;
    const supporter = context.command.indirectObject!.entity!;

    // Scope check
    if (!context.canReach(item)) {
      return { valid: false, error: 'cant_reach', params: { item: item.name } };
    }

    // Trait check
    if (!supporter.has(TraitType.SUPPORTER)) {
      return { valid: false, error: 'not_a_surface', params: { target: supporter.name } };
    }

    // Capacity check
    const capacity = supporter.get(TraitType.SUPPORTER)!.capacity;
    if (getChildCount(supporter) >= capacity) {
      return { valid: false, error: 'supporter_full', params: { target: supporter.name } };
    }

    return { valid: true };
  },

  // Phase 2: EXECUTE - Apply mutations (no output)
  execute(context: ActionContext): void {
    const item = context.command.directObject!.entity!;
    const supporter = context.command.indirectObject!.entity!;

    // Capture pre-mutation state
    context.sharedData.previousLocation = context.world.getLocation(item.id);

    // THE MUTATION
    context.world.moveEntity(item.id, supporter.id);
  },

  // Phase 3: REPORT - Generate success events (read-only)
  report(context: ActionContext): ISemanticEvent[] {
    const item = context.command.directObject!.entity!;
    const supporter = context.command.indirectObject!.entity!;

    return [
      context.event('if.event.put_on', {
        item: item.name,
        itemId: item.id,
        supporter: supporter.name,
        supporterId: supporter.id,
        previousLocation: context.sharedData.previousLocation
      }),
      context.event('action.success', {
        actionId: context.action.id,
        messageId: 'put_on',
        params: { item: item.name, supporter: supporter.name }
      })
    ];
  },

  // Phase 4: BLOCKED - Generate error events (on validation failure)
  blocked(context: ActionContext, result: ValidationResult): ISemanticEvent[] {
    return [
      context.event('action.blocked', {
        actionId: context.action.id,
        messageId: result.error,
        params: result.params
      })
    ];
  }
};

Phases:

  1. Validate - Preconditions only, no mutations, returns pass/fail
  2. Execute - Mutations only, no events
  3. Report - Success events (semantic, not text)
  4. Blocked - Error events (called instead of execute+report)

Key features:

  • Strict separation: mutations in execute, events in report
  • Events carry message IDs, not English text
  • Language layer converts IDs to prose
  • sharedData for inter-phase communication
  • Validation result passed to blocked phase
  • Multi-object support built into pattern

Comparison Table: Action Execution

Aspect TADS 3 Inform 6 Inform 7 Hugo Sharpee
Phases PreCond/Verify/Check/Action before/action/after Before/Instead/Check/Carry out/After/Report Single routine Validate/Execute/Report/Blocked
Implicit actions Built-in (preCond) Manual Before rules Manual Via event handlers
Mutation location Action phase In routine Carry out In routine Execute only
Output location In action In routine Report In routine Report (as events)
Override mechanism Object methods before blocks Instead rules Routine override Entity event handlers

5. Output and Response

How does each system generate player-facing text?

TADS 3

TADS 3 uses embedded text and message objects:

// Embedded in action
actionDobjTake() {
    "You pick up <<theName>>. ";
}

// Or via message objects
playerActionMessages: MessageHelper
    takeMsg = '{I} {take} {the dobj}. '
    alreadyHaveMsg = '{I} already {have} that. '
;

Key features:

  • Template strings with placeholders
  • Conjugation for perspective ({I}, {take})
  • Message objects for i18n potential
  • Text typically in action code

Inform 6

Inform 6 uses print statements with library messages:

[ PutOnSub;
    ! Direct printing
    print "You put ", (the) noun, " on ", (the) second, ".^";
];

! Or library messages
Object LibraryMessages
    with before [;
        PutOn: print "You put ", (the) noun, " on ", (the) second, ".^";
    ];

Key features:

  • Direct print in routines
  • Library message override for customization
  • (the), (a), (The) for article handling
  • ^caret for newlines

Inform 7

Inform 7 uses say phrases with text substitutions:

Report putting something on something:
    say "You put [the noun] on [the second noun]."

! Custom responses
Report taking the crystal ball:
    say "The ball pulses with inner light as you lift it."

Key features:

  • Natural language say phrases
  • Text substitutions [the noun], [a thing]
  • Adaptive text (he/she/they)
  • Unicode support

Hugo

Hugo uses print statements:

routine DoPutOn
{
    print "You put "; The(object); " on "; The(xobject); "."
}

Key features:

  • Procedural print statements
  • The(), Art() for articles
  • Simple string concatenation
  • Straightforward control

Sharpee

Sharpee uses semantic eventslanguage layer:

// In action (report phase)
report(context): ISemanticEvent[] {
  return [
    context.event('action.success', {
      messageId: 'put_on',
      params: { item: 'book', supporter: 'table' }
    })
  ];
}

// In language layer (lang-en-us)
const puttingOnMessages = {
  put_on: (p) => `You put ${p.item} on ${p.supporter}.`,
  not_a_surface: (p) => `${p.target} isn't a surface.`,
  supporter_full: (p) => `There's no room on ${p.target}.`,
};

Key features:

  • Complete separation: actions emit IDs, language layer emits text
  • Enables true i18n (lang-es-mx, lang-de-de)
  • Parameters passed to message functions
  • Perspective handling in language layer
  • Events can be intercepted/modified before rendering

Comparison Table: Output

Aspect TADS 3 Inform 6 Inform 7 Hugo Sharpee
Text location In actions or messages In routines Say phrases In routines Language layer only
Substitution Template strings Print macros [brackets] Print calls Function params
i18n support Message objects Library override Limited Limited First-class (message IDs)
Article handling {the}, {a} (the), (a) [the], [a] The(), Art() In language layer

6. What Sharpee Kept vs. Modernized

Kept from Classic Systems

Concept Origin Sharpee Implementation
Pattern-based grammar All systems Grammar builder with pattern matching
Scope concept All systems ScopeResolver with visibility/reachability
Action phases Inform 7, TADS 3 Four-phase pattern (validate/execute/report/blocked)
Trait/attribute system All systems (has/hasnt) TypeScript traits with behaviors
Multi-object commands All systems (multi/all) Built-in "all", "and", "except" handling
Implicit actions TADS 3 preCond Event handlers can trigger implicit takes
Object interception Inform before/after Entity event handlers

Modernized

Concept Classic Approach Sharpee Approach
Grammar binding Grammar → routine Grammar → action ID → action handler
Scope resolution During parsing After parsing (separate phase)
Text generation In action code Separate language layer (message IDs)
State management Global variables WorldModel with typed entities
Type safety Runtime only TypeScript compile-time checks
Action organization Per-verb files Grouped by semantic category
Extension points Object methods, rule ordering Event handlers, capability dispatch
Multi-object Grammar-level (multi token) Parser-level then action-level
Configuration Compile flags Runtime dependency injection

Key Philosophical Shifts

  1. Separation of Concerns

    • Classic: Grammar, scope, action, and text often intermingled
    • Sharpee: Each concern in its own layer with clean interfaces
  2. Event-Driven Architecture

    • Classic: Actions produce output directly
    • Sharpee: Actions produce events; language layer produces text
  3. Typed Everything

    • Classic: Dynamic typing, runtime discovery
    • Sharpee: TypeScript types, compile-time validation
  4. Action as First-Class

    • Classic: Actions tied to grammar patterns
    • Sharpee: Actions are independent handlers, grammar just routes to them
  5. Internationalization as Core

    • Classic: Afterthought, message object hacks
    • Sharpee: Message IDs from day one, language layer separation

7. Pipeline Diagram Comparison

Classic Model (Inform 6 style)

Input: "put book on table"
         ↓
┌────────────────────────────────────────┐
│  PARSER                                │
│  • Tokenize                            │
│  • Match grammar                       │
│  • Resolve entities (scope check)      │
│  • Populate noun/second globals        │
└────────────────────────────────────────┘
         ↓
┌────────────────────────────────────────┐
│  ACTION ROUTINE                        │
│  • Check preconditions                 │
│  • Apply mutations                     │
│  • Generate output                     │
│  (all interleaved in one routine)      │
└────────────────────────────────────────┘
         ↓
Output: "You put the book on the table."

Sharpee Model

Input: "put the red book on the wooden table"
         ↓
┌────────────────────────────────────────┐
│  PARSER (parser-en-us)                 │
│  • Tokenize                            │
│  • Match grammar patterns              │
│  • Output: IParsedCommand              │
│    (action ID + text slots, NO entities)│
└────────────────────────────────────────┘
         ↓
┌────────────────────────────────────────┐
│  VALIDATOR (stdlib)                    │
│  • Resolve entities from text          │
│  • Check scope (ScopeResolver)         │
│  • Disambiguate (adjectives, recency)  │
│  • Output: ValidatedCommand            │
│    (action ID + resolved entities)     │
└────────────────────────────────────────┘
         ↓
┌────────────────────────────────────────┐
│  ACTION EXECUTOR (engine)              │
│  • Look up action handler              │
│  • Call validate() - preconditions     │
│    ├── Pass? → execute() + report()    │
│    └── Fail? → blocked()               │
│  • Output: ISemanticEvent[]            │
└────────────────────────────────────────┘
         ↓
┌────────────────────────────────────────┐
│  EVENT PROCESSOR (engine)              │
│  • Call entity handlers                │
│  • Generate reaction events            │
│  • Sequence all events                 │
└────────────────────────────────────────┘
         ↓
┌────────────────────────────────────────┐
│  LANGUAGE LAYER (lang-en-us)           │
│  • Map message IDs → prose             │
│  • Apply perspective                   │
│  • Format parameters                   │
│  • Output: final text                  │
└────────────────────────────────────────┘
         ↓
Output: "You put the red book on the wooden table."

8. Summary

Each system reflects its era and design goals:

  • TADS 3: Most sophisticated classic system, OOP-based, multi-sensory scope, verify/check distinction
  • Inform 6: Compact and efficient, Infocom heritage, tight grammar-scope coupling
  • Inform 7: Natural language paradigm, explicit rulebook phases, accessible to non-programmers
  • Hugo: Practical and straightforward, clear procedural model, good balance of power/simplicity
  • Sharpee: Modern TypeScript, strict layer separation, event-driven, i18n-first, type-safe

Sharpee borrows liberally from all four systems while pushing toward:

  • Stronger typing
  • Cleaner separation of concerns
  • First-class internationalization
  • Event-driven extensibility

The core insight remains the same across all systems: transform natural language into structured commands, validate them against world state, execute them, and report the results. The differences lie in where boundaries are drawn and how flexibility is provided.

8 days ago

Renga in Blue - Jan 13

Haunted House (Lucas, 1983)

Writing an adventure game is very similar to writing a novel. Everybody can write a few unrelated sentences, but the novelist’s skill comes from stringing sentences together in such a way as to create a tale combining imagination, flair and ingenuity. — From Steve Lucas, 1985, Adventure Programming on the Amstrad The British company ICL […] 9 days ago

Writing an adventure game is very similar to writing a novel. Everybody can write a few unrelated sentences, but the novelist’s skill comes from stringing sentences together in such a way as to create a tale combining imagination, flair and ingenuity.

— From Steve Lucas, 1985, Adventure Programming on the Amstrad

Two relevant places for today marked: Kidsgrove in red, Burton-Upon-Trent in blue to the southeast.

The British company ICL (International Computers, Limited) has come up here before; their game called Quest by Urquhart, Sheppard and McCarthy came from their computers as an after-hours project. They were curiously formed as sort of a forced integration of multiple companies from the 1960s. ICT (International Computers and Tabulators) was already a merger of elements from BTM (British Tabulating Machines), Powers-Sampas, and the computer divisions of GEC, EMI, and Ferranti; English Electric had merged in Leo, Marconi, and Eliot (changing names each time).

In certain contexts a government might be concerned about monopoly power, but the Wilson government of the late 60s decided the opposite; there was concern that the British computer market was simply going to collapse under outside pressure (especially from IBM). So, the government invoked the Industrial Expansion Act which pushed together the two companies into one in 1968, keeping the name ICL.

The resulting mammoth had a disparate variety of incompatible products; ICL decided to “start fresh” (with government money assistance, 40 million pounds) and develop the 2900 series. (Their own 1900 series was ailing and outdated, using only 6 bit characters.) At Kidsgrove in particular (site originally built by English Electric in the 60s) they made printed circuit boards but also were one of the sites developing software for the new device, in particular the (now well-regarded, unstable at the start) VME/B operating system.

From a 1976 booklet, via the Centre for Computing History.

Early releases of VME/B were characterised by one word – late. At one stage VME/B was being produced in Kidsgrove, but top management and validation remained in Bracknell. As days turned into weeks, management became increasingly impatient. “We haven’t finished it yet” was the reason for a conspicuous delay in handover to system test. “Then just put what you have finished on a tape and send it down here so that we can make a start on validation”.

A couple of days later a tape arrived. It was put up on a tape deck and the machine was booted up. Nothing happened. Consternation ensued. Much diagnostic effort was expended in trying to get the new version of VME to load. Eventually it transpired that the tape contained only an end of file mark.

“That tape you sent us – its completely empty.”

“But that’s what you asked for.” came the reply. Somehow a week’s delay was bought.

— Andrew Mason from Another ICL Anthology

One of the people hired around this time was Andrew Espeland. I’m unfortunately just guessing he was at Kidsgrove but I have decent evidence, as he worked at ICL starting around 1973, had an address at Burton-on-Trent in 1983 and went to Burton Grammar School in the 60s, meaning there’s a fair chance he stayed locally in between. The nearest ICL location from Burton-on-Trent was at Kidsgrove. In the later part of his time there it is possible he did some telework, as we know Kidsgrove specifically was set up for that. You can see a demo below of a worker with Airbus connecting to an ICL terminal, circa 1982:

While ICL expanded all through the 70s (helped along by the government policy of buying homegrown computers) they were starting to be in trouble in the 1980s. They were intending to expand to a factory in Winsford (about an hour northwest of Kidsgrove) and the local government “bent over backwards” to aid in this, with 1,500 new houses built and “sterilising a major factory site” but ICL started to backtrack; from the floor of Parliament:

The matter is urgent because the loss of 1,500 jobs is in an area where unemployment is already at 11 per cent. The only other large employer, Metal Box, is due to close at Christmas with the loss of 500 jobs, many of them directly affecting my constituents, [it] would push unemployment up to 15 per cent by the spring.

This is a death blow to Winsford. I have just learnt that the men’s bitterness is such that they have today occupied the factory, and I submit that the House has a special responsibility to air their grievances as urgently as possible.

While the situation at Kidsgrove wasn’t quite as bad, they still went from 33,000 to 20,000 employees from 1981 to 1984. So it is possible Andrew Espeland was one of the redundancies; whatever happened, he decided to strike it out on his own as a software publisher in mid-1983 and founded Silverlind. He posted solicitations for authors during this time.

Esperland gave an interview to his local newspaper (Burton Mail) on November 23, 1983, featuring the Silverlind Master Diet Planner (written by Professor C. V. Brown and Dr. E. J. Levin of the University of Stirling)…

…although it was the sort of interview where he was starting from scratch with teaching how computers work, including explaining to the reporter “that software and hardware were not related to pornography.”

Silverlind is like a book publishing company, only we sell tapes instead of books. We offer the amateur a chance to turn professional. Everyone who has a computer thinks he’s great at coming up with programs, but not many people have the resources to market them if they’re good. That’s where we come in.

Please note that he went straight from ICL to personal computer tape distribution; this is different from the situation at Sumlock I wrote about recently where there was a branch computer store in the late 1970s that led to software publishing. Put another way, Sumlock’s ads and packaging come across as being sold by someone with product and consumer experience, while Silverland’s come across as being made by someone who came straight from writing operating systems to running a company. Silverlind did not last long, with ads starting by the end of the year and petering out by early 1985 with no increase in catalog size. The late 1983 ads include three adventure games.

All three are (probably) all by the same author, one we’ve encountered before: Steve W. Lucas. He is, as I explained earlier, sort of the British version of Peter Kirsch, writing a staggering number of type-ins starting in 1983, although many are repurposed ones he had already written.

The reason for the “(probably)” is we only have copies of two of the Silverlind adventures: Haunted House and Passport to Death. Gateway to the Stars (AKA Journey to the Stars) is lost, but assuming it is by Lucas we might see it again under a different name anyway. (I’m suspicious of “A Journey Through Space” which is in his Adventure Programming on the Amstrad book; there’s no tiger or lizard woman but Lucas often renamed things. The book game is allegedly “buggy and impossible to finish” which is another thing common amongst Lucas games.)

Via Everygamegoing.

While the previous Lucas game we played had versions for Amstrad and Oric, this one is for BBC Micro! Just like the other Lucas games this does have a clone-situation but I’m going to focus on the original for now and visit the duplicate situation at the end.

I have the full instructions from the inside of the tape, but they don’t give any context other than “you are standing in the doorway of an old mansion” and “you must recover the six treasures”.

You have a lamp which won’t work, a note and a gun when you start. As you visit the other locations you will find a variety of objects which may be of use – or are they red herrings?

Regarding the note:

The note is from my great grandfather ARNOLD J HARBUTHNOT. It reads:

As my sole living heir, I have sent you on this dangerous mission to find 6 treasures and rescue the princess. you must deposit these items on the doorstep.

Apparently there’s a princess too? In a haunted house? Wouldn’t be the first time that’s happened. (I will find the princess this session, but not rescue her yet.)

The overall structure of the complex has a house to the north, a path in the middle, and a castle to the south. Despite the Haunted House name the castle is more extensive than the house, but let’s start with the house first.

There’s no descriptions of rooms beyond their names, so you need to use your imagination.

Doing a grand tour, east of the hallway is a bedroom with a pair of slippers, and “an old four poster bed” with a pillow. North leads to a kitchen with a box of matches, a bottle of spirits, and some food, and going west after leads to a “large dining room full of cobwebs” that contains a candle.

West of the hallways is a library with a map and a “pen in a golden holder”. The map curiously says “not at the moment” when you try to read it; this is a game where items often only can be used in very specific cases, even if there is no logical reason to restrict them (like books). Trying to GET PEN reveals a secret passage…

…and going in is death.

Well, to be fair, the game did start by announcing we had a dead lamp. With the matches and the candle you can LIGHT CANDLE (…normally, one time it caused my game to crash…) and go into the secret passage safely. Not far in, you get stopped by a monster.

There’s a “sharp knife” you can find later but if you try to KILL MONSTER the game says “you’re a coward”, which is rude but fair for a standard adventurer who will likely rely on trickery or some gizmo instead to get by. Let’s turn to the middle path area…

…where off an “old footpath” to start there is a “snarling wolf” at a “coffin”.

Trying to OPEN COFFIN gets a blank response from the game (another thing that’s pretty common; 98% sure this game was written before Journey of a Space Traveller because it has more jank). I can get a reaction from the wolf by trying to GET WOLF…

That makes it mad. It attacks me. I am DEAD

…but that isn’t helpful so let’s move on! Further south is another split in the path where a signpost informs us that “FOOTPATH WEST IS DANGEROUS. YOU NEED A MAP” and this is the one and only spot the map can be READ successfully.

(I originally died while holding the map thinking it would be used passively. Not only can the map only be read in the right room, but you have to do the READ command before moving otherwise you’ll die.)

This leads to an Old Barn with a *PEWTER* trinket and a book of ghost stories, and just past is a tiny cave which appears to be empty. I tried to do SWEEP even though I had no appropriate item and the game told me I couldn’t swim. This is a two-letter parser. (On the BBC Micro, why!)

Reading the book only works in this room.

Moving on you can find a drawbridge (no puzzle, just PULL LEVER) followed by a “drunken man” in a Castle Courtyard that is blocking your way west (you can pass south unfettered). If you take the spirits from the kitchen and drop them he will helpfully pass out.

Go farther west and you’ll find the princess! Except now you are locked in, and typing HELP as the game suggests indicates that if you don’t have a key you should reset your game.

Ignoring the drunk man for the moment and going south into the castle…

…you can do a sweep down various rooms to the south and west and find a sharp knife in a kitchen, a tray of drinks in a restroom, a bar of soap in a bathroom, a packet of crisps in a dormitory, and a uniform in a changing room. (You might think to WEAR UNIFORM while in that room, but there is no response to this.) There is cryptically also a “magazine dated 1893” where READ MAGAZINE gets the message “I can’t make it out.”

35% chance this is a red herring, 30% chance I need an item, 30% chance I need to bring the magazine somewhere else, 5% chance this is a bug.

Heading east instead leads to a most curious room for a game called Haunted House.

You can THROW TOMATOES (as the screen shows me doing) but FREE MAN and RELEASE MAN are right out. Maybe this scene is here to be funny? Just south of here is a “hand-operated lift” with a “rope with a hook” inside but no apparent way to operate the lift.

To the far east you can find a “pair of electrodes” intended for ??? and a painting which the main character is actively offended by.

South is a pottery room with some pots (spooky?) and to the north is a ghost (spooky!)

You might think, ah, the book says the uniform will scare ghosts, but I have not been able to wear the uniform, nor does it get used “passively”. I tried SCARE GHOST and since the game has a two-letter parser it read the command as SCORE instead, telling me I had 1 out of 7 points possible.

There is a solution on CASA and my pain tolerance will not be high, but I admit there are things I haven’t tried like giving the crisps to the wolf, or stabbing the princess with a knife, or entertaining the man in stocks with a puppet show using slippers on my hands. I will also take suggestions in the comments for next time.

9 days ago

Renga in Blue - Jan 10

Adventure 751: Into the Sunset

I’ve never spelunked, although I’ve been in a number of caves around the country as a tourist. Like Carlsbad Caverns, Lava River Cave here in Oregon, Cave of the Winds in Colorado and others I can’t recall. Most of my additions were suggested either by fantasy stories or the many geology texts I’ve read. — […] 11 days ago

I’ve never spelunked, although I’ve been in a number of caves around the country as a tourist. Like Carlsbad Caverns, Lava River Cave here in Oregon, Cave of the Winds in Colorado and others I can’t recall. Most of my additions were suggested either by fantasy stories or the many geology texts I’ve read.

— David Long

I’ve finished the game. You should read my previous posts about Adventure 751 before this one.

Three parts I needed to check the walkthrough on. Two puzzles were sort of fair. The third was absolutely off the charts unfair and I don’t know how anyone ever solved it.

CompuServe in 1995, via The Columbus Dispatch. They had 3.6 million customers, but four years later they would be bought out by AOL. When moving to a new interface, their text-based games shut down.

To start with, a classic, me missing a room exit. This is at the now-defeated leprechaun:

You’re at the east portal of the Gothic Cathedral.

GO NORTHEAST

You’re at sham rock.

GO UP

You are on top of a flat black rock.
There is a small briar pipe here.
There is a suede pouch here.

Whoops! There were “smoke rings” coming up from the rock and there’s also suspicious items on the map picture.

What happens next took place for me later, and is one of the puzzles I needed to just look up the answer. It’s clearer for me to explain it now. I’m referring here to the boulder just north of the sham rock:

Although the boulder moves a fraction of an inch, it is too heavy for you to roll away.

We’ve already had a “get strong” puzzle multiple times along our journey, so the thought passed my mind that this might come up, but I was expecting to find a different kind of mushroom or special cream; getting by the boulder instead involves the food from the beginning of the game.

The food tastes bland, but is not unpalatable.

In Normal Adventure it gets fed to the bear to make it happy; we swapped in the honeycomb in this game as the food is described as “watercress sandwiches” when you try to give them to the bear. The “bland” part of the description is the key, as you’re supposed to use one of your treasures (!) on top of the food (!!) and then eat it (!!!).

PUT SPICES ON FOOD

All the food needed was a bit of spicing up: it smells delicious!

EAT FOOD

Zam! What a meal! Now we’re ready for anything!

This does not consume the rare spices (unlike the cakes you ate to get small). Which makes sense in a pragmatic sense, but the general rule of this sort of game has been that eating something means that thing goes away. It’s still not obvious from the description, but now the boulder can be moved.

Grunt…Pant…You have pushed the boulder to one side, enough to permit you to squeeze past it.

GO NORTH

You are at the bottom of a vertical shaft, apparently a dry well, whose cylindrical wall is lined with smooth stone. Far above your head, you can see daylight!
A heavy iron handle, slotted at one end and rounded at the other, lies at your feet.

At least I knew immediately what the handle goes to!

Back to the castle we go:

You’re in the Central Court.

PUT HANDLE IN WINCH

The iron bar, evidently the winch handle, slips easily into the winch mechanism.

TURN HANDLE

Turning the winch slowly lowers the great wooden drawbridge.

This also suggested another puzzle solution, as this landed me at the ravine area right next to the angry centipede.

You are at cliff by west end of moat.

MOVE VINES

Parting the vines reveals a dim recess in the cliff wall.

IN

You are in the lair of Ralph the Giant Centipede. The air reeks with the stench of rotting bits of flesh. Giant centipedes, in general, are not partial to visitors.
A golden fleece is lying nearby!
A giant centipede is eyeing you with a none-too-friendly look.

GET FLEECE

You have snatched the centipede’s very own security blanket!

Provoked beyond endurance (centipedes have none), the indignant insect lurches to all of its feet and starts towards you.

OUT

You are at cliff by west end of moat.
The cantankerous cootie is heading towards you, and he definitely harbors no goodwill towards you.
A dim alcove can be seen behind the vines.

GO EAST

You’re beside moat.
The angry arthropod is definitely gaining on you. You had better either sprout several more legs or find some way to evade him.
A wooden drawbridge spans the moat.

GO NORTH

You’re in the Central Court.
The incensed insect is in full gear now. If you don’t move quickly, his monstrous mandibles may masticate you into murky mush!
A heavy iron handle is inserted into the winch.
A wooden drawbridge spans the moat.

TURN HANDLE

With a great creaking and groaning, the winch raises the drawbridge to a vertical position against the stone wall.

You have raised the bridge just in time. The centipede stamps furiously up and down in front of the moat, but, finding no way to cross, finally gives up and lumbers back to his cave.

I love “cantankerous cootie”; Ralph is so vivid I wonder if he’s supposed to be some sort of University of Chicago reference (not Atari Centipede, which wasn’t out yet). Moving on to the castle interior…

…as a reminder I had found a tapestry (treasure) and a black bird statue (not) as well as a door with colored tiles. I did not disclose the answer to the tile puzzle, and Voltgloss managed to work it out in the comments.

The key is the word FNORD, being spelled by the initial words of the colors. As Aula observes in the comments, the color names are decidedly odd, which might suggest thinking of initial letters.

You are inside a large steel vault.
Nearby is an intricately-wrought bronze shield bearing the escutcheon of Duke Aldor.

The other two places of note are the Secret Garden and the kitchen with the dumbwaiter. I already suspected what to do with the dumbwaiter as the puzzle is more or less wholesale stolen from Zork (I’ll get into that later) but let me get into the Secret Garden. You don’t enter it here at all, but rather an exit at the third helicopter stop I missed last time.

(Also, the knapsack with the silk sheets lets you refer to it as a PARACHUTE, which made me much more confident the following sequence would work before I tried it.)

You’re on the south end of a high narrow ridge, which is bounded on its east side by a high mountain. Dug into the mountainside is a ramshackle old mine entrance. The ridge drops off to the west in a rocky cliff. You might be able to climb down the cliff, but you probably won’t be able to get back up.
A helicopter is waiting nearby.

GO NORTH

You are on a narrow N/S ridge high above a stone wall and wide moat.

GO NORTH

You are at the northwest end of a narrow ridge high above the castle’s inner courtyard.

WEAR PARACHUTE

Ok

JUMP

After a few seconds in freefall your parachute opens with a sudden “Pop!” Several moments later you land unhurt. The magic ‘chute then folds itself back into the knapsack.
You are in an idyllic garden hidden in an inner courtyard of, and surrounded on three sides by, the Castle Keep. The far end of the garden is bounded by a high cliff.
A wooden door leads into the castle.
Lying in one corner of the garden is a golden apple!

From a game design angle, what I’m frustrated by here is how this is the only place the parachute works; jump in any other high place and you won’t get a description at all. I know that “magic” can technically hand-wave away anything, but inconsistency in magic use is one of my main teeth-grinders, especially in that it’d be fun to jump off in other high places.

Note as far as I know this loses the helicopter (remember we left at the ledge) so I ended up shuffling my sequence around to do the golden apple part last. So let’s warp back a little and go inside the mine instead.

You are in a gloomy tunnel, the entrance to a long-abandoned mine. All around is fallen rock and rotted timbers. To your left, a small room adjoins the main tunnel.

Arthur O’Dwyer mentioned I had missed an exit here, but at least this time I had fair reason. Going DOWN goes into the mine, and none of the other compass directions work. You’re supposed to go LEFT, which is counter to everything else in the entirety of the game.

You are in the engineering room. On a control panel on the wall are four buttons, colored green, brown, red and yellow; and a digital gauge.

Going down into the mine reveals it is flooded by water. The gauge currently reads 5, which tells you the flood level; pressing the “red button” and waiting will cause the water to go down. The frustrating aspect is that reading the gauge does not pass time.

PUSH RED BUTTON

From somewhere in the distance comes the deep throbbing of a heavy engine.

READ GAUGE

The meter reads “5”.

READ GAUGE

The meter reads “5”.

READ GAUGE

The meter reads “5”.

READ GAUGE

The meter reads “5”.

I was deeply confused for a while, because I knew I had at one point seen the meter go down, and had even had the engine explode because I didn’t turn it off. However, you need to do some command other than READ, like LOOK, and then READ GAUGE afterwards.

You are in the engineering room. On a control panel on the wall are four buttons, colored green, brown, red and yellow; and a digital gauge.
The deep hum of heavy machinery fills the control room.

READ GAUGE

The meter reads “1”.

LOOK

You are in the engineering room. On a control panel on the wall are four buttons, colored green, brown, red and yellow; and a digital gauge.
The deep hum of heavy machinery fills the control room.

READ GAUGE

The meter reads zero.

With this taken care of you can go to the bottom of the mine. There’s a passage there that’s too narrow to go through while holding items (like the one at the emerald / dark room).

You are at the bottom of the mine’s main shaft. Several passages, now all blocked by cave-ins, used to lead off in all directions.
To the north, the one remaining tunnel is partially blocked.

GO NORTH

The tunnel is a real squeaker. You’ll be lucky to get through with your clothes on, let alone anything else.
You’re at bottom of mine.

If you drop everything and go through, the room is too dark to see. I already suspected taking the puzzle from Zork when I saw the dumbwaiter back at the castle; you’re supposed to put a light source in there (lighting the candle back from the cathedral works, the one that I had previously used to burn the thicket except burning it was wrong) and then lower the dumbwaiter.

You are in a dead-end shaft formerly used for temporary storage.
The dumbwaiter is at this level.
It contains:
wax candle
There is a pile of silver ingots here!

You can put the ingots in the dumbwaiter, leave, go back to the castle, and then pull up the dumbwaiter to find the ingots waiting for you.

The water didn’t just disappear! It filled up the ravine.

You’re in an open field on the south side of a flooded ravine. South and west the land merges into nearly impassible swamp. In the muck is a fresh footprint! Incredibly, it looks very much like that of a Giant Devonian Rat, long thought extinct.

This ravine had a statue. The setup was that you could go in or out of the ravine while not holding anything, but you couldn’t take that valuable statue at the bottom with you. By filling up the ravine with water, you have softlocked the game.

I was incredibly stumped because I was looking for alternate exits, when instead I should have been thinking about getting the statue to rise with the water. I was imagining the statue as extremely heavy, so that this wouldn’t work:

You are at the east end of a steep ravine, near where a drainage pipe emerges from a rock wall.
There is an ancient marble statue lying here!

PUT STATUE IN BOX

Ok

DROP BOX

Dropped.

You’ll find the box with the statue sitting at the muddy ravine when it fills. This isn’t the puzzle I consider outrageously unfair, as at least conceptually this was neat, and we are down to not too many items to fiddle with.

Speaking of fiddling with items, remember that “briar pipe” and “suede pouch” from the start of the post? The pouch has tobacco, and you can use a match from the matchbox to light tobacco in the pipe. It wasn’t obvious what it was for, but I remembered (barely) there were some mosquitos out in the salt flats (just a bit south of the ravine) that I had never been able to bypass.

The air ahead is filled with huge mosquitos, with stingers the size of icepicks! The mosquitos haven’t yet caught your scent.
Do you really want to proceed?

YES

Your pipe fumes have effectively fumigated your flying foes. The bothersome bugs beat it as you approach.

You are enveloped in a cloud of noxious-smelling tobacco fumes.
You are on a small dry patch of earth, surrounded by dank swamp.
There is an old cracked shaving mug here.
There is a large cloth bag lying nearby.
There is a smooth, white pebble lying nearby.
An old shiny button is lying here.
An ancient mystic amulet, somewhat tarnished by the dampness, is lying here!

I never used the amulet for anything; it counts as a treasure. (Briefly searching through the walkthrough, it looks like it could be used to teleport, but that’s optional.)

Donovan fit almost everything into the art, but I’m not seeing which spot in the swamp would be the rat nest.

From here this was nearly done! If you’re wondering about the rope that was frustrating me before, you can drop it at the bottom of the well and play the flute to cause it to rise, giving another way to get into the castle (again optional). However, there was one item I had done nothing with and did not count as a treasure and here is the part that went off the charts:

There is a clay statue of a black bird here.

I kept trying to invoke it for some kind of magic? Maybe it would turn into a real bird and do something? Unfortunately I already “used” essentially everything so backwards thinking from my object list was no help.

The bird is dirty, you’re just supposed to clean it.

POUR WATER ON BIRD

The liquid reacts oddly with the black substance covering the statue of the bird. After a few moments, the black coating dissolves completely, revealing a statue of solid gold encrusted with priceless gems of every description!

INVENTORY

You are currently holding the following:
brass lantern
official document
knapsack
maltese falcon
glass bottle

At least I didn’t have to go through a complicated endgame. The way Crowther/Woods works is that once you’ve placed all the treasures, you hang out in the underground enough and there will be an announcement that the cave is closing; wait longer and you’ll get tossed into the endgame. There’s no surprises here other than the item catalog is different than original Crowther/Woods:

The sepulchral voice entones, “The cave is now closed.” As the echoes fade, there is a blinding flash of light (and a small puff of orange smoke). . . . As your eyes refocus, you look around and find… You are at the northeast end of an immense room, even larger than the Giant Room. It appears to be a repository for the “ADVENTURE” program. Massive torches far overhead bathe the room with smokey yellow light. Scattered about you can be seen a pile of bottles (all of them empty), a nursery of young beanstalks murmuring quietly, a bed of oysters, a bundle of black rods with rusty stars on their ends, and a collection of brass lanterns. Off to one side a great many dwarves are sleeping on the floor, snoring loudly. A sign nearby reads: “Do not disturb the dwarves!” An immense mirror is hanging against one wall, and stretches to the other end of the room, where various other sundry objects can be glimpsed dimly in the distance. An unoccupied telephone booth stands against the north wall.

GO SOUTHWEST

You are at the southwest end of the repository. To one side is a pit full of fierce green snakes. On the other side is a row of small wicker cages, each of which contains a little sulking bird. In one corner is a bundle of black rods with rusty marks on their ends. A large number of velvet pillows are scattered about on the floor. Beside one of the pillows is a large, dusty, leather-bound volume with the title “History of Adventure” embossed in pure gold. A vast mirror stretches off to the northeast, almost reaching the phone booth. At your feet is a large steel grate, next to which is a sign which reads, “Treasure Vault. Keys in Main Office.”
The grate is locked.

Mind you, figuring out what to do was hard in Crowther/Woods, but here it’s an identical solution, so I was able to claim victory.

GET ROD

Taken.

GO NORTHEAST

You’re at NE end.

DROP ROD

Dropped.

GO SOUTHWEST

You’re at SW end.
The grate is locked.

BLAST

There is a loud explosion, and a twenty-foot hole appears in the far wall, burying the dwarves in the rubble. You march through the hole and find yourself in the Main Office, where a cheering band of friendly elves carry the conquering adventurer off into the sunset.

You scored 667 out of a possible 751, using 1726 turns.

Your score puts you in Master Adventurer Class B.

I have no idea where the missing points are. Maybe this is a game like the “2.0” version Woods wrote which accounts for your turn count? I absolutely did not optimize. (Optimize light, sure, but there’s a fair amount of aboveground parts to this game, and I never tried to be efficient when it came to sorting inventory at the building/safe.)

That’s still enough to close out the game for good. I’ve known about this one for ages and I can’t describe how gratifying it was to finally play. Some of the mainframes are finally getting tape dumps and there’s more lost content likely that will be unearthed (I’m sure Rob is about to show up and announce another 30-hour game suddenly landing), but because I’ve been able to look at the picture (even using it to annotate other variants of Adventure!) Long’s Adventure 751 had a sense of absence that other games did not.

As far as game quality goes, it was mixed; I think it started to get to the point where it was too big. The new sections were intrinsically clever but they felt like they were part of another realm entirely, even when, say, the rat was using similar mechanics as the pirate. I would have loved to see what Long would have done with an entirely different game.

It is faintly possible there’s a little bit more. In Arthur O’Dwyer’s writeup he discusses a version of the history text file in the game where “more than double” is instead “more than triple”.

But does this indicate any actual expansion of the cave? The unearthed game already includes all of the features mentioned here. Was Long just massaging his messaging?

It is possible Long was able to noodle with the program more while it was on CompuServe, and while I don’t know the details yet, Rob has mentioned in the comments here that the commercial version will be forthcoming so we’ll get a chance to take a look.

11 days ago

Renga in Blue - Jan 09

Adventure 751: A Section of the Castle In Which You Have No Business

(Continued from my previous posts.) The good news is I’m fully clear of the 501 content (1978) and now tangling directly with the 751 section (1980). The bad news is the author clearly thought going to the ’80 version that it was an opportune time to up the difficulty. At the very least, the sheer […] 13 days ago

(Continued from my previous posts.)

The good news is I’m fully clear of the 501 content (1978) and now tangling directly with the 751 section (1980). The bad news is the author clearly thought going to the ’80 version that it was an opportune time to up the difficulty.

At the very least, the sheer combinatorial explosion of the number of items the game now has makes each step much rougher than it needs to be.

TODAY, March 1983. The poster artist is Gray Morrow who is most famous for the Tarzan comic strips (post 1983) but also did work for both Marvel and DC.

Starting simple, I was running over my map trying to figure out the best spot for my shovel when I decided on the beach (even Pillage Village had us randomly dig at the beach, with no shovel at all!)

You’re on sandy beach.

DIG

You’ve dug yourself into a three foot hole in the sand.

DIG

You’re up to your waist in sand.

DIG

You’re in a deep pit in the sand.
You have unearthed a delicate, multi-hued conch.

That doesn’t mean I’m necessarily done with the shovel! None of the other candidates I’ve tried have panned out, though.

While out at the beach, I should mention the flute. Or rather, specifically the rat it summons: the rat has been roaming around aboveground the whole time, essentially the outdoors version of the pirate. I realize it was swapping useless items for useful items, so that “pebble” I found really was an item swap; I’ve also gotten an old shiny button where a pirate chest used to be (I had dropped the chest thinking it would be heavy and “protected” but it isn’t). The occasional bad odor also is from the rat.

The upshot here is rather than the rat being useful (as I was first thinking) is that I needed to get rid of the rat. The flute’s reference to the “pied piper” is the key here.

You’re at blackened shoals.

GO UP

You’re at Ocean Vista.

LOOK

You are on a high cliff overlooking the sea. Far below the rolling breakers smash into a jumble of blackened shoals.
The thunder of the surf is deafening.

PLAY FLUTE

After playing the flute for a few moments, you become aware of stealthy footsteps behind you.
The big rat, entranced by the music, blindly lurches over the edge of the cliff, only to be pounded to smithereens on the rocks below.

With this done, it is safe to put items on the ground in the building now. I used the opportunity to mop up a lot of the items I needed, like the vase (which is highly breakable and goes on a cushion). I also finally ran across the Wumpus corpse I had been looking for back at the Lost River section.

You are standing on a large flat rock table at the western end of Lost River Canyon. Beneath your feet, the river disappears amidst foam and spray into a large sinkhole. A gentle path leads east along the river’s south shore. Another leads sharply upward along the river’s north side.
Nearby is the smashed body of a defunct Wumpus.
On the Wumpus’ finger is a small gold ring.

It was, of course, one of the last sections I checked, but I should have been suspicious sooner, just in a structural-solving sense: there was otherwise a decent chunk of map that wouldn’t be used.

Six rooms otherwise not used. Crowther would be fine with a section like this, but not Long (who was the one who made this part).

One other item from the area I’ll mention now, although in practice it came much later than my other finds:

You are in the Conservatory, whence the gnomes often repair to relax with a little music. On one side of the room is an old upright piano.

OPEN PIANO

Ok

LOOK

You are in the Conservatory, whence the gnomes often repair to relax with a little music. On one side of the room is an old upright piano.
It contains:
official document

Oof. I was mentally sorting it as some kind of already-open grand piano even though it explicitly says in the text it is an upright. (I wasn’t trying to visualize it, though. I know there’s the aphantasia condition where people aren’t able to visualize and so they keep things in their head more conceptually; I don’t have it, but just because I’m good at visualizing doesn’t means I store everything visually. This is a case where my brain abstractly stored a “piano”.)

More on the official document shortly.

With all that I was still stuck on the “sham rock”, the centipede, and the statue in the ravine. I’m still stuck on all of them, more or less, although I got a little past the rock. Let me do an aside on the rose in the thorns right before the sham rock, first…

A NE passage is blocked by an impenetrable thicket of sharp thorny brambles.
Deep within the brambles is growing a perfect, blood-red rose!

…I had been burning them to get them away but this destroys the rose. You’re supposed to use the sword (pulled from the stone while wearing the crown) instead.

Your elfin sword makes short work of the brambles. After a few minutes work, you hack a large hole through the tangle.

If you just try to take the rose now, it will shrivel. That vase that was previously used for the break-if-you-don’t-drop-on-a-pillow puzzle is now repurposed:

PUT ROSE IN VASE

As you place the rose into the vase, the rose opens in full bloom, revealing a sachet of rare perfume inside.

(This is one of those puzzles where I was starting to feel the burn of having so many items.)

Past the thicket, the leprechaun was wanting me to vanquish “one much larger than I”. Oddly, I knew that I had tried going by with the bear, dragon, and Wumpus all killed, but no luck. Arthur O’Dwyer hinted I was on the right track but I needed “proof”. That would be either the rug at the dragon or the gold ring at the Wumpus; the latter sounded more elegant.

As you approach the rock, the leprechaun (for indeed that is what he is) notices your shamrock *and* your ring, and with a muttered curse, disappears.
You’re in a large chamber. All around are massive skeletons of long-dead members of the order proboscidea ungulata, who evidently used this room as their final resting place. Passages exit north and south.
There is a huge ivory tusk here!

You have to be wearing the ring too — first time I didn’t do that and had to make another full circle to test with the ring on. Grr.

The elephant resting place just serves to dish out a treasure (the tusk) and just past that is a passage blocked by a boulder.

PUSH BOULDER

Although the boulder moves a fraction of an inch, it is too heavy for you to roll away.

So you may wonder if I barely made progress on those three things I named, how I did get farther in? Well, back to that official document:

READ OFFICIAL DOCUMENT

The document is written in an undecipherable script. However, it bears the official seal of the Orcan government.

I hadn’t talked about the helicopter strangely at the start because I knew what they were looking for (a letter of transit) so it didn’t seem like an “open puzzle” really until I found the right item.

You’re at end of road again.

GO EAST

You’re in a flat circular clearing surrounded by dense forest.
Not far away is a helicopter. Its engine is idling slowly. Several jac-booted Orcs are standing guard around the aircraft.

IN

After inspecting your letter of transit, the Orcs sullenly stand aside to let you board the aircraft.
You are in the helicopter’s cramped passenger cabin. The only visible feature is a silver button on the wall.

PUSH BUTTON

The door slams shut as soon as you hit the button, followed by the sound of the engine revving up. After many minutes of noise and vibration, the engine falls silent and the door slides open.

OUT

You are in the West Courtyard, a wide flat area bounded on the north by a high cliff and on the south and west by the curve of the castle wall.
A helicopter is waiting nearby.

Huzzah, the castle! (I could have made it here a lot earlier, the Conservatory isn’t gated by any puzzle, it’s just a matter of opening the piano and finding the document.)

At least it feels appropriate for now to be the time to arrive in a dramatic sense.

Just to the east of the landing place is a winch. I have been unable to turn the winch; it presumably connects to the drawbridge.

You are at the base of the central portion of the courtyard near what appears to be some sort of large wooden door in the stone wall.
Attached to the wall is a heavy winch.

Neither wooden pole nor rope have been helpful, and generally the winch has been resistant to verbs in general. The game feels like it is pounding against the edge of what’s possible in a standard Crowther/Woods world model (yes, the containers are fancier and you can use more than two words, but it still doesn’t work as smoothly as, say, Infocom).

Farther along is a door with a slot; that’s where the card from nearby the phone booth goes.

You are at the entrance to Lords’ Keep.
A massive door of solid oak guards the castle entrance. In the center of the door is a small slot.

PUT CARD IN SLOT

From behind the door there is a whirring sound and the card is sucked from your hand. A moment later, the great oaken door swings open.

GO NORTH

You are inside Lords’ Keep, at the south end of the Great Hall. The room is lit by smokey torches hung high overhead. Several passages lead off to connecting rooms.
A priceless tapestry is hanging on the wall!

Side passages have an “aviary” with a “clay statue of a black bird”, and a room overlooking a “secret garden” where there’s a “knapsack” with “silk sheets”. I assume the latter is a parachute (I tried jumping at the ravine with it on but just died). The same room has a barred wooden door.

You are in a small room off the east hallway. Through a heavily barred window you can look out on a lovely secret garden.
A wooden door leads out to the garden.
There is a bulging knapsack here.

Near here is the Kitchen which includes a dumbwaiter. You can put items inside and send them down; to where I don’t know. I also don’t know why you’d need to (I assume I’ll find out soon).

Finally, there’s a puzzle I managed to actually solve:

The short hallway ends at a heavy steel door inlaid with enamelled tiles, each of which is a different color. The tiles, nine in all, are arranged in a 3×3 grid, thusly:

Above the door, a green light is shining.
The stainless steel door is locked.

I am not going to give the solution here, because I’m curious if it’s possible to solve it normally. (Try in the comments!) I did it by getting most of the way through via brute force before realizing the pattern. You need to push tiles in a particular sequence, and you have enough information (assuming you’ve read my previous posts) to solve it with what you know. Brute force requires a lot of reloading save files:

PUSH WHITE TILE

You are obviously attempting to intrude into a section of the castle in which you have no business. Faster than you can spit, a trapdoor springs open beneath you, catapulting you into a deep pit at the bottom of which a number of sharp, upright spikes have been affixed.

I’m not quite done yet with new stuff, because hopping back in the helicopter takes you to a third area.

You’re on the south end of a high narrow ridge, which is bounded on its east side by a high mountain. Dug into the mountainside is a ramshackle old mine entrance. The ridge drops off to the west in a rocky cliff. You might be able to climb down the cliff, but you probably won’t be able to get back up.
A helicopter is waiting nearby.

However, the mine just leads to a flooded tunnel; I’m not sure what’s going on here. Going west down the cliff leads to the caterpillar area. (I guess you could softlock if you hadn’t cleared the quicksand by the time you got here?)

I have to be hovering near the end because I’ve now seen the entire poster map. Other than the obstacles at the castle I’m still dealing with the same three as before (just the boulder past the sham rock rather than the cursed little man saying “fnord”).

13 days ago

Renga in Blue - Jan 08

Adventure 751: Ersatz Materials

(Continued from my previous posts.) Noble warriors of a distant age! Participate in the first-ever Nationwide Adventure Tournament on the CompuServe Information Service. Beginning at 6 p.m. local time on Friday, September 4 through 5 a.m. on Tuesday, September 8, slay evil dragons, carry off precious treasures and be proclaimed “Grand Master” of Adventure! Throughout […] 14 days ago

(Continued from my previous posts.)

Noble warriors of a distant age! Participate in the first-ever Nationwide Adventure Tournament on the CompuServe Information Service.

Beginning at 6 p.m. local time on Friday, September 4 through 5 a.m. on Tuesday, September 8, slay evil dragons, carry off precious treasures and be proclaimed “Grand Master” of Adventure!

Throughout the Labor Day Weekend, all entrants scoring the point total worthy of “Grand Master” status will be awarded two hours of free time and a CompuServe “Adventure” T-shirt. Runners-up will receive a T-shirt only, but still a prize worthy of the challenge!

Additionally, all entrants can receive on request a full size color version of the poster shown here. We’ll charge your account $1 for postage and handling. Check the “What’s New” section of Information Service prior to the contest for details and point total requirements.

Many will win the title “Grand Master.” Will your name be counted within their ranks?

— From TODAY magazine July 1981; the poster being referred to is the “sword and sandals” one I showed off previously

I don’t have a chunk of map to share this time; my progress has been filling in small holes of progress, enough to an extent that I can say I nearly have the 501 content wrapped up, just I’m having trouble making progress on the 751 content.

Ad from the first issue of CompuServe’s TODAY magazine, July 1981, offering the maps of both Adventure 350 and Adventure 751 for sale.

One bit of progress came just from idly checking the Adventure 751 map. I noticed there was an item that normally isn’t there on Adventure 350.

That box on the ground at the window is what I’m referring to. It connects to the Bedquilt room; I had tried earlier to go north at Bedquilt to get to there (as it specifies on my original Adv350 map) but I kept getting sent to the “Low room” instead so hadn’t really tested further. I already knew there was a “randomizing” effect with getting sent in a loop, but there’s some extra randomizing on top of that.

You are in Bedquilt, a long east/west passage with holes everywhere. To explore at random select north, south, up, or down.

GO NORTH

You have crawled around in some little holes and wound up back in the main passage.
You are in Bedquilt, a long east/west passage with holes everywhere. To explore at random select north, south, up, or down.

GO NORTH

You are in a large low room. Crawls lead north, NE, and SW.

The “large low room” isn’t the only possible destination (although it is the most frequent one). Raw persistence is the key, and I mean persistent: it took me about 50 tries to get to the right place.

You are in Bedquilt, a long east/west passage with holes everywhere. To explore at random select north, south, up, or down.

GO NORTH

You are in a secret canyon at a junction of three canyons, bearing north, south, and SE. The north one is as tall as the other two combined.

GO NORTH

You’re at a low window overlooking a huge pit, which extends up out of sight. A floor is indistinctly visible over 50 feet below. Traces of white mist cover the floor of the pit, becoming thicker to the left. Marks in the dust around the window would seem to indicate that someone has been here recently. Directly across the pit from you and 25 feet away there is a similar window looking into a lighted room. A shadowy figure can be seen there peering back at you.
There is a heavy, grey, metal cannister here.
The shadowy figure seems to be trying to attract your attention.

(The shadowy figure is just you in a mirror. I never understood this as a kid playing the game.)

I immediately recognized the canister, er, cannister, as the one I could put the radioactive rock into for safety.

You are at a high rock on the NE side of a watery chamber at the mouth of a small brook. An unknown gas bubbles up through the water from the chamber floor. A bluish light can be seen to the southwest.
Nearby, a strange, greenish stone is glowing brightly.

PUT STONE IN CANNISTER

Ok

CLOSE CANNISTER

Ok

Another puzzle I resolved is near here, so let’s get to that one next. Hop off the boat and head east and you’ll be at the Fairy Grotto.

You’re in Bubble Chamber.
There is a small wooden boat here.

GO EAST

It is now pitch dark. If you proceed you will likely fall into a pit.

LIGHT LAMP

Your lamp is now on.
You are in a sloping muddy defile, next to a tumbling brook.

GO EAST

You are in the Fairy Grotto. All around you innumerable stalactites, arranged in immense colonnades, form elegant arches. On every side you hear the dripping of water, like the footsteps of a thousand fairies. A small stream runs from the SW corner. A bright glow emanates from the south side of the grotto, and a steep passage descends to the east.

GO SOUTH

You go a short way down the bright passage, but the light grows to blinding intensity. You can’t continue.
You’re in the Fairy Grotto.

The game has the dark room in the middle because otherwise it would be easy to accidentally run into the solution: turn off the lamp. (The bright glow is already there, so we don’t need any other light!)

TURN OFF LAMP

Your lamp is now off.

GO SOUTH

You are in the Crystal Palace. An overhead vein of phosphorescent quartz casts a luminous glow which is reflected by countless chips of mica embedded in both walls, which consist of some sort of highly reflective glass, apparently of volcanic origin. A winding path of yellow sandstone leads west and rises steeply to the east.
There is a polished sphere of pure opal here!

The Crystal Palace connects the fairy room to the rainbow / lost river area…

…but before heading over there, I should return to the Fairy Grotto and mention I have the “cold corridor” problem resolved as well, and it was indeed how I guessed mid-post: the cloak is sufficient to protect you.

GO EAST

You’re in a steeply sloping passage. It is very cold here.

GO EAST

You are in the Hall of Ice, in the deepest part of the caverns. During winter, frigid outside air settles here, making this room extremely cold all year round. The walls and ceilings are covered with a thick coating of ice. An upward passage exits to the west.
There are diamonds here!

Now, about that Crystal Palace connection! It makes it easy to transport the cask down to the wine fountain and fill it up.

You are in the Winery, a cool dark room which extends some distance off to the east.
There is a fountain of sparkling vintage wine here!

FILL CASK WITH WINE

The cask is now full of wine.

(East from here are some “limestone pinnacles” and going up is where the cask is; you can take the cask straight back down over to the fountain, but there’s a chance that the cask will break. I spent longer than I needed to here as I assumed there was an extra gimmick, as it’s a “puzzle” that only has a certain percent chance of triggering and it gets bypassed merely by using a different route.)

Trudging past the “tongue of rock” back into the area with the phone booth…

The Conservatory is marked green because it’s in 751 only. It has the flute which is new for this game.

…I have the phone booth worked out, and the flute half-worked out. The phone booth had a gnome come in and use it; if you leave and come back, you can enter, and then get the item I believe was the whole intent of the scene.

You are standing in a telephone booth at the side of a large chamber. Hung on the wall is a banged-up pay telephone of ancient design.
The phone is ringing.

ANSWER PHONE

No one replies. The line goes dead with a faint “CLICK”.

HIT PHONE

A couple of lead slugs drop from the coinbox. (Gnomes are notoriously cheap….) But you’ve broken the phone beyond all hope.

The slugs can serve as a substitute for the coins in the machine that dispenses batteries for the lantern. The various remixes of Crowther/Woods have tended to be uncomfortable with the fact that the Maze of Twisty Passages, All Different doesn’t need to be entered at all because the only reward is the machine for extending battery life (and doing that burns one of your treasures, so you can’t get full points). Usually the resolution has been adding something extra (like hiding a passage behind the battery machine) but here the game slips in a way to use the machine as intended, just with something that isn’t a treasure.

(I still do not know what the plastic card outside the phone booth which says “Merkin Express” is for. It isn’t present in the 501 version.)

For the flute, trying PLAY FLUTE somewhere random gets you the message:

Sounds good. Are you in training to be the pied piper, or what?

If you instead use it at the salt flats (where we made concrete and fell into a bunch of quicksand):

PLAY FLUTE

After playing the flute for a few moments, you become aware of stealthy footsteps behind you.

PLAY FLUTE

You are being followed by a strangely docile giant Devonian rat!

Somehow this resulted in me getting a “smooth, white pebble” in the room just past the construction zone (I guess the rat brought it with them). I haven’t gotten any more use out of the rat; it doesn’t help with the mosquitoes (I thought maybe the bloodsuckers would focus on the critter and I’d be able to get through, no luck) and it doesn’t help with the centipede (ditto trying to make a distraction).

You are in the lair of Ralph the Giant Centipede. The air reeks with the stench of rotting bits of flesh. Giant centipedes, in general, are not partial to visitors.
A golden fleece is lying nearby!
A giant centipede is eyeing you with a none-too-friendly look.

PLAY FLUTE

After playing the flute for a few moments, you become aware of stealthy footsteps behind you.

PLAY FLUTE

You are being followed by a strangely docile giant Devonian rat!

One other quick puzzle, tracing to me still being confused as to what’s a treasure: the honey that you got from giving the flowers to the bees does not count as a treasure, but rather as food for the bear.

You are inside a barren room. The center of the room is completely empty except for some dust. Marks in the dust lead away toward the far end of the room. The only exit is the way you came in.
The bear is locked to the wall with a golden chain!
There is a ferocious cave bear eying you from the far end of the room!

THROW HONEYCOMB

The bear eagerly licks up the honeycomb, after which he seems to calm down considerably and even becomes rather friendly.

The bear not liking the lunch from the start building is the only change in this area.

From a totally different version of Adventure, Platt’s Adventure 551, which includes a new area past the Breathtaking View, the extra long volcano description that is there in Crowther/Woods just for scenery … and also in Adventure 751 just for scenery.

Finally, that leprechaun that was teleporting me with “fnord”: I made a little progress.

ENEMY NUMBER ONE.

I had found the four-leaf clover after the leprechaun and it seemed logical they’d go together, so I did item-juggling and made my way back. Unfortunately, it still doesn’t help:

You are in a dull N/S passage beside a tall black rock. On the rock is chisled the outline of a four-leafed clover, under which is the inscription: “Notice: This rock fabricated from ersatz materials.”

A sudden draft has extinguished your match.
Smoke rings curl upward from the rock.

INVENTORY

You are currently holding the following:
brass lantern
silver horn
ruby slippers
Holy Grail
shamrock
matchbox
wax candle

GO NORTH

As you approach the rock, the little man suddenly notices your shamrock. “Well, well,” says he, “you may be able to see me now, but you’ll never get by this place until you have vanquished one much larger than I! Fnord!”
You’re on grassy knoll.

I’ve tried defeating the dragon and bear but neither seem to satisfy. It could be the centipede?

Apologies about being so randomly scattered! That’s often how progress happens in one of these types of games. I’m left with, at least…

  • a shovel which I haven’t used yet
  • the centipede which chases the player up to a ravine
  • the statue stuck in the ravine (I think I know what to do here, I just need to setup the items to test)
  • still getting by the “ersatz rock”

…and one thing I remember from 501 that I haven’t done yet: finding the corpse of the Wumpus and getting a gold ring. I imagine this is just an exploration error, or rather, the fact I have a bunch of save games where progress hasn’t been consolidated (that is, the save file I explored on is not the same one I killed the Wumpus). I’m still under the feeling the final move count is going to be very tight, so when I realize a sequence could be better, I get the urge to redo it. It means I don’t even know how many points I could get maximum at this moment.

I’m stumped enough on the centipede and the rock I’m happy to get gentle rot13 hints. I suspect I’m about two posts away from a conclusion, although if the endgame is tough this might go out to three.

14 days ago

Zarf Updates - Jan 05

The Visible Zorker 2

Hey, remember the Visible Zorker last year? Meet the Visible Zorker 2: The Visible Wizard of Frobozz! It doesn't have a subtitle really. I just like saying "Visible Wizard of Frobozz". If you don't remember last year (Zog knows I have trouble ... 17 days ago

Hey, remember the Visible Zorker last year? Meet the Visible Zorker 2: The Visible Wizard of Frobozz!

A screenshot titled "The Visible Zorker 2". The left side of the window shows the opening of Zork 2, up to the command TURN ON LAMP. The right side shows a list of ZIL function calls and the message "The lamp is now on." It doesn't have a subtitle really. I just like saying "Visible Wizard of Frobozz".

If you don't remember last year (Zog knows I have trouble too), here's the idea: You play Zork 2 in the left pane. The right pane shows everything that happens under the hood as you play. The functions that were executed to carry out your command, the object tree, the variables, the timers... everything. Click on anything to highlight its source code.

See last year's post for the baroque details. Since then, I've added a few more views, including a map that displays your location live. (Zork 1 has been similarly updated.)

Part of the map of Zork 2, north of the Carousel Room.

Once again, I've written up commentary on bits of the source code that struck my interest. Click any green eyeball button to show its commentary note.

The VZ2 source code is available. Of course, there's a great deal of overlap with the VZ1 source code. I've broken the common parts out into their own repository, which is now a submodule of VZ1 and VZ2.

Obviously -- I don't even know why I mention it -- this project is massive all-over SPOILERS for Zork.


Why now?

A year ago, as you recall, I wasn't very excited about doing Zork 2. The first one was fun; it was a nice resume boost; I was happy to stop there. So what changed?

Most obviously, Microsoft released all three original Zork games as open source. I figured I should respond to that. You gotta reward good behavior, right?

Of course, I did the original Visible Zorker before the games were open source. I scoff at copyright law! Well, no: I think copyright law is generally a good thing. But like I said in 2019, history matters. I did the work, in part, to demonstrate why the Infocom legacy should be treated as a community resource. And now it is -- at least this part of it.

Any Easter eggs?

Hit the commentary button for the I-WIZARD routine (see the "Timers" tab). You'll find an option to force the Wizard to cast any of his spells on you. This is handy for exploring rare special effects.

Anything cool turn up?

Oh, the usual wacky details. I was reminded that the Wizard's FANTASIZE spell doesn't work at all in this version of Zork 2. (Release 48, the Masterpieces CD version.) We've known that for a while though.

If you get the wand and cast FLUORESCE on an object, not only is the spell permanent (same as when the Wizard does it) but the fluorescing object magically gains a power switch!

>wave wand at rose The wand grows warm, the perfect rose seems to glow dimly with magical essences, and you feel suffused with power.

>say "fluoresce" The wand glows very brightly for a moment. The perfect rose begins to glow.

>turn off rose The perfect rose is now off.

>turn on rose The perfect rose is now on.

There's a couple of places where the compiler skips over a <TELL> line, omitting the string from the compiled game. This seems to be a size optimization for routines that are never called. (See <BLAST>.) But (a) why not skip the entire function and save even more space? And (b) in <V-ODYSSEUS> it skips some code that is called, resulting in a bug: typing ODYSSEUS just prints a blank line. This might be evidence of a ZIL compiler bug in the %<COND> compile-time directive.

So, on to Zork 3?

...Let's say the chances are high. But I'll save that announcement for a bit. Watch this space, honorable readers!

17 days ago

Zarf Updates - Jan 04

NarraScope is open for submissions

Happy New Year! NarraScope is once again calling for talks, games, and -- new this year -- experiences. NarraScope will be in Albany, NY this year (June 12-14), thanks to support from the University at Albany. As always, we will have a full ... 18 days ago

Happy New Year! NarraScope is once again calling for talks, games, and -- new this year -- experiences.

NarraScope will be in Albany, NY this year (June 12-14), thanks to support from the University at Albany.

As always, we will have a full weekend of talks and presentations. Last year in Philadelphia, we added the NarraScope Showcase, where people could demo games in a dedicated room and time slot. We'll be doing that again in 2026. And now also adding:

"The Experience": Bridging the Physical and Digital Worlds through Narrative

For Narrascope 2026, we are thrilled to announce a new track dedicated to narratives with the intention to blur the lines between the physical and digital worlds.

We invite you to help us explore and celebrate the future of embodied narrative. If your work tells a story by transformation between physical and digital spaces, we want to hear from you.

We are seeking projects that tell a story through a participatory experience, and are looking for creators who use technology as a way to weave narratives into the fabric of our surroundings.

What does that mean? Check out the web site. Could be AR, mixed-reality, projection mapping, interactive installations... we don't know what else. We shall find out!

Submissions for all of the above are now open. Deadline for proposals is January 31st. Go wild.

18 days ago

The People's Republic of Interactive Fiction - Jan 22

November 2025 Post Mortem

The People’s Republic of Interactive Fiction convened on Thursday, November 20, 2025 over Zoom. Stephen Eric Jablonski, Hugh,, Josh Grams, Michael Stage,   Matt Griffin, zarf,, Cidney Hamilton, Doug Orleans, David J Hall, and anjchang, welcomed newcomers and Monica Storss. Warning: What follows is probably not proper English, but just a log of notes from the meeting to […] 8 hours ago

The People’s Republic of Interactive Fiction convened on Thursday, November 20, 2025 over Zoom. Stephen Eric Jablonski, Hugh,, Josh Grams, Michael Stage,   Matt Griffin, zarf,, Cidney Hamilton, Doug Orleans, David J Hall, and anjchang, welcomed newcomers and Monica StorssWarning: What follows is probably not proper English, but just a log of notes from the meeting to jog people’s memories.

In general, topics covered IF preservation news (Zork!), new tools/experiments (Ink + Godot, Bitsy exercises), community jams (EctoComp), and ongoing debates about IP openness vs. protection in interactive fiction/narrative games.

Major News & Announcements

Games & IFDB Entries Mentioned

People & Social/Media

  • Monica aka@digitalpoetics on Instagram, Discord, and other “agitprop” outlets (likely for experimental/digital poetics/narrative work).

Industry/IP Discussion

  • Many treat old games/code as effectively open source in practice, but companies vary wildly in handling legacy IP.

Narrative Engines & Tools Discussion

  • Why so many engines? People love experimenting and building their own (e.g., Twine, Ren’Py inspire lots of creators).
  • Mentioned projects/tools:
    • Domino Club / Domino Gallery: Loose collective for anonymous game jams, low-tech/digital art, narrative-heavy work, ditherpunk, etc. (focus on DIY, remix, glitches, queer themes, etc.).
      Link: https://domino.gallery/
    • Related piece: “good writers are perverts” manifesto/essay by DOMINO CLUB (interactive “tape window” format arguing for embracing “sicko” creative impulses).
      Link: https://dominoclub.itch.io/good-writers-are-perverts
  • Yack script example (Ink-based dialogue system, from Grumpy Gamer’s DeloresDev repo—likely Thimbleweed Park-related dev work).
    Link: https://github.com/grumpygamer/DeloresDev/blob/master/Scripts/Yacks/Sheriff.yack
  • Bitsy for game poems/tiny narratives: Limited text UI space; Pico-8 also noted for similar constraints.
    • Anna Anthropy’s Itsy Bitsy Exercises (Bitsy teaching exercises for narrative design—spatial movement, dialogue, etc.; full details in devlog posts).
      Link: https://w.itch.io/itsy-bitsy-exercises
  • Other platforms: Playdate handheld (crank + charger features).
    Links: https://play.date/games/blippo/ and https://play.date/

Design/Systems Discussion Highlights

  • Praise for a diagram-based approach (circuit-like, state-showing; “systems thinking”).
  • Idea: Can you build a game directly from a diagram? Potential for hybrid narrative modes (pause navigation for decisions).
  • Question raised: Handling state/history across geographical spaces (Metroidvania-style logic?).

8 hours ago

Renga in Blue - Jan 20

The Colonel’s House: Interview with the Author

(Continued from a post from a year ago. You should probably read that post before this one.) While I occasionally reach a videogame in the All the Adventures project which is famous enough to have existing interviews and memoirs to pull from (like The Hobbit and The Dark Crystal) oftentimes I have very little to […] 2 days ago

(Continued from a post from a year ago. You should probably read that post before this one.)

While I occasionally reach a videogame in the All the Adventures project which is famous enough to have existing interviews and memoirs to pull from (like The Hobbit and The Dark Crystal) oftentimes I have very little to start with. Even when an author gets some attention from later work they may never talk about their adventure game output (like with Stuart Marks’s biography pretending that Pillage Village didn’t exist).

Hence I was gratified when the author of The Colonel’s House (Rob Davis, 14 when he wrote the game) contacted me and not only was he willing to do an interview, he remembered this era well.

The first computer I experienced was a ZX-81 that my Maths teacher showed in the school staff room. I was immediately massively inspired by seeing it, and requested one for my birthday. I learnt to program BASIC on the ZX-81, and very quickly outgrew it and bought a VIC-20 where I continued to program BASIC and learnt Assembler.

Rob Davis first had contact with adventure games via a visit to a friend’s house; they had an Apple II and were playing Mission: Asteroid, “a really early graphic adventure that I remember involving a spaceship, and you had to work out which buttons to press on a very simple spaceship control panel, and it was a text adventure, but it was graphics, and I found that really exciting.”

He also had exposure to Mystery House (more on that in a moment) but otherwise this brief visit was his only exposure to adventure games (he played lots of games, “especially Jeff Minter ones”, but not adventures); that was enough to make him want to write his own.

I was just doing it in my own from my own inspiration it was just really that one game and really just one hour with that game that was the starting point for me.

He had no exposure to Crowther/Woods Adventure, or Scott Adams, or any of the VIC-20 adventure games coming out at this time.

I did it from scratch. I had read books about coding, but no, I had no guide to making adventure games or anything. I just started and I worked out how to build the engine for the adventure game, which was an engine that was able to kind of store room state, store player state, parse language, render rooms and react to your movements across the rooms and react to the objects changing state and all those kinds of things. So I wrote the engine for that from scratch from my own understanding of coding.

His VIC-20 had memory expansion; he wrote one game as a proof of concept (“a small map and was set on a desert island”) before writing The Colonel’s House.

More than games, I was inspired by the Omen movies on TV at that time, which had a set of seven daggers forged to kill the Antichrist.

He’s referring to The Seven Daggers of Megiddo. They are named after the seven churches from Revelation, and each one needs to be placed at a different point of the body to kill the Antichrist.

The Colonel’s House was a “private game” to just share with friends. Sometime after this, he had gone to a computer game show in London, where he found Rabbit Software, and the topic of his game came up:

I got talking to them, and they asked me to send them a tape of my game. I wasn’t going to send it, but a school friend persuaded me that I should, and Rabbit immediately offered to publish it.

They were “chaotic” and actually released the game without telling Davis; a school friend had said they’d seen it at a game store. Rob didn’t believe him but his friend offered to buy a copy.

That was also the first time I saw the cover art, which I didn’t approve at the time, though in hindsight it was OK.

I was able to discuss the content of the game a bit; he had a scene (which I didn’t hit while playing) where you can fall out a window; you’ll be alive, get picked up by an ambulance, but then the ambulance will get in a wreck on the way to the hospital and you’ll die. This comes directly from a death in Mystery House (when you leave the attic). Regarding the amount of the death the game has in general:

I mean, I’m casting myself back now to when I was 14, but I’m not sure that I would know mechanically how I wanted to treat players who had done something unwanted and kind of you know failed in one of the puzzles; like probably death was the only way to handle that. How do you cover the cases of the different failures of the puzzle? That might have been a complexity that I wasn’t sure what to do with … therefore game over seems like quite a kind of neat way to wrap up whatever kind of sequences of actions that haven’t got them (the player) to the right solution.

He did indeed have a grand plan for seven games total:

I had planned to make 7 adventure games, each to recover a different one of the 7 Knives of Eternity. The lore was that the knives were extremely powerful and when joined together, gave the holder ultimate powers. They had been hidden distributed throughout time and space for safety, but their locations had been compromised and others were seeking them. You were an agent who had to recover them and destroy them for good. I did complete the 2nd game, Escape from Detra Five, which had a knife hidden in an alien space station. Unfortunately it was never released because Rabbit went out of business.

He remembers Detra Five being at a computer show once so it is still faintly possible a copy escaped to the wild; he doesn’t have one he can find.

Rob Davis did eventually go on to be a full-time game developer, and there’s even an interview in The Guardian with him back when he was in charge of Solaris Media (“worked with Macromedia Flash for five years to build websites, online games and digital art installations”).

His more recent work includes Star Wars: Hunters, a free-to-play game which was only shut down in October of 2025; his current ongoing project is a game intended to fight climate change with planting trees.

Again, deep thanks to Rob Davis for his time, and of course (if he is the one reading these very words) feel free to drop any additional thoughts in the comments.

2 days ago

Renga in Blue - Jan 19

Sword of Raschkil: Supermoon Logic

I’ve finished the game; this continues directly from my previous post. I received warning on the puzzle I was stuck on from gschmidl that: “I have no idea how you’re supposed to figure it out.” The puzzle is so baffling I am coining a new term, supermoon logic. The term moon logic has not come […] 3 days ago

I’ve finished the game; this continues directly from my previous post.

Covers of the last three issues of the magazine (ending in August 1983).

I received warning on the puzzle I was stuck on from gschmidl that: “I have no idea how you’re supposed to figure it out.” The puzzle is so baffling I am coining a new term, supermoon logic.

The term moon logic has not come up as often on this blog as you might think; as I’ve mentioned before, I think the term gets applied far too widely to any kind of puzzle difficulty without any kind of care taken to if a puzzle is illogical or just difficult. Quoting myself on the game Katakombs:

I still think the term is useful, but I tend to narrow down to circumstances were cause and effect seem to be nearly at random; perhaps you understand from the animation why the bubble gum made the goat move, but the connection is one that could almost never have been predicted. There is a disjoint between action and result. Oddly, in text adventures, this shows up less than you might think, just because the requirement of a verb adds specificity to an action; you can’t just USE BUBBLEGUM ON GOAT and have the animation happen, but rather need to specify to (for sake of example) FEED BUBBLEGUM TO GOAT. The puzzle is still perhaps a bad one, but there’s at least a suspicion that something interesting might happen.

This puzzle is worse than that. Not only do cause and effect seem to be random, but even after seeing the result the sequence makes no sense. Put another way, if a game asks me to “guess what the author is thinking”, usually afterwards I can see how the author made the decision they did (even if it went spectacularly awry). Here, even knowing the particulars and combing the source code I can’t even begin to reconstruct what was going on. Perhaps you, the reader, can help demystify this, but for now I’m slotting this as the rare supermoon logic, where moon logic doesn’t even make sense after the fact.

Last time I was stuck with water in a jar (from a pond), a key (extracted from the bottom of the pond), a gold leaf, and a staff. I had dead-ended at a castle with a pit that you could use a staff to fly over and a wizard in a room with a cryptic sign.

The pit turned out to be a complete red herring; I am unclear why the flying scene was in the game. Only the wizard room is important:

? E
YOU ARE IN THE CASTLE ENTRY.
VISIBLE ITEMS:
NOTHING
? E
YOU ARE IN THE WIZARD’S ROOM.
THE WIZARD IS IN THIS ROOM.
A SIGN IS NEARBY.
VISIBLE ITEMS:
WIZARD
SIGN
? READ SIGN
IT SAYS, ‘I AM CLUTON. THROW A PIE AND YOU WILL DIE.’
? TAKE SIGN
THE WIZARD SAYS, ”LEAVE MY SHINGLE ALONE.”’

The hint that I needed to do an action I had already done was enough to get by, but only because I looked at my previous screenshots and saw an action that could be done in any room.

? DRINK WATER
O.K.
EVERYTHING BEGINS TO SPIN AROUND AND…
YOU ARE ON THE HEATH OF ORIONE’S MANOR.
TO THE NORTH IS A HOUSE, TO THE EAST, A DUMP.
VISIBLE ITEMS:
NOTHING

Anyone with an idea? I tried doing anagrams of “I AM CLUTON”; I tried poking the word (and the “throw a pie” phrase) into search engines to see if I had missed some obscure cultural reference. I tried checking the source code to see if I had missed a way of getting a hint. Drinking the water elsewhere gets the message “BOY THAT REALLY HIT THE SPOT!!!” which suggests nothing magical.

The other lesson from this is that magic is very dangerous for a game designer; it can be done to make arbitrary effects, but if a part of the game is based on that effect, it is almost certainly going to be frustrating for the player.

Moving on, as we aren’t too far from the end:

You can go south to loop back to the forest with the oak tree if for some reason you missed something; if you go east you end up at a DUMP with a RAT. This room serves only to kill you if you try to mess about with the rat.

Heading north instead into the house, there’s a series of locations that are room-name-only (YOU ARE IN THE ENTRY HALL, YOU ARE IN THE BACK ROOM, YOU ARE IN THE BACK PORCH). One side room is a kitchen with a pie, and at the end of the sequence is a ghost.

Given the sign earlier, it was impossible not to resist trying to THROW PIE while at the ghost.

YOU HIT THE GHOST WITH A PIE.
HE GETS MAD AND PUNCHES YOU, THE FORCE OF THE BLOW
IS SO GREAT THAT IT KILLS YOU.

I know people are still sore about the pie/yeti combo from one of the King’s Quest games; finally, the ghost gets revenge.

Thinking outside the box, I looped back around to the wizard Cluton and tried throwing the pie at him instead…

…the end result being that THROW PIE still somehow throws it at the ghost, even when you are nowhere nearby. OK, yes, the source code is a bit fragile. (I checked the late issues — see top of this post — for corrections, but couldn’t find any, but maybe the magazine ended too quickly for that.)

I tried EAT PIE instead and found a diamond. Knowing GIVE was on my verb list, I tried GIVE DIAMOND while at the ghost and it worked.

This isn’t supermoon level logic since “enemy accepts something valuable” makes retrospective sense (sort of), but I certainly didn’t use regular logic to solve; it’s just the game limits so heavily what options are available I didn’t have many choices to go through.

The ending had no puzzle at all because I had already found the key (if you didn’t find it earlier, you can go back and get it; you can even refill your water and do the DRINK WATER trick again).

My apologies to the author if he’s here Googling himself. I did indeed hit a puzzle so baffling I had to coin a new word to describe it. I did at least appreciate the “pure” feel of the game even with the bugs and puzzle illogic, and even with minimal description I did get the scent of another world.

It was also useful to see what sort of game H & E Computronics printed (and the fact they likely did not test the game for bugs at all); as I mentioned in my last post, we’ll visit them again sometime at least once more (I have not skimmed the complete catalog to be sure nothing else is missing).

Coming up: an interview with an author giving a snapshot of the chaotic UK game publishing scene, followed by an Apple II “contest game” with buried treasure.

3 days ago

My So Called Interactive Fiction Life - Jan 17

Capability Dispatch: A Pattern for Extensible Action Resolution

White Paper on Sharpee Interactive Fiction Engine January 2026

Abstract

Sharpee's Capability Dispatch system solves a fundamental problem in extensible software: how do you allow third-party code to modify the behavior of standard operations without sub-classing, monkey-patching, or invasive hooks?

This paper describes a pattern combining&

5 days ago

White Paper on Sharpee Interactive Fiction Engine January 2026

Abstract

Sharpee's Capability Dispatch system solves a fundamental problem in extensible software: how do you allow third-party code to modify the behavior of standard operations without sub-classing, monkey-patching, or invasive hooks?

This paper describes a pattern combining double dispatchcomposition over inheritance, and a behavior registry to create a system where:

  • Standard actions have default semantics
  • Entities can override or block actions via traits
  • Behaviors are registered externally and resolved at runtime
  • The system is extensible at three levels: platform, extensions, and applications

While developed for interactive fiction, this pattern applies broadly to any domain with entities, operations, and extensibility requirements.


Table of Contents

  1. The Problem
  2. Traditional Solutions and Their Limitations
  3. Capability Dispatch Architecture
  4. Design Patterns Employed
  5. Implementation
  6. Real-World Analogies
  7. Benefits and Trade-offs
  8. Conclusion

The Problem

Consider a system where:

  • Entities exist with varying compositions (a door, a troll, an axe)
  • Actions can be performed on entities (take, open, attack)
  • Behaviors vary based on both the action AND the entity's characteristics

The naive approach leads to a combinatorial explosion:

M entity types × N actions = M×N behavior implementations

With 50 entity types and 40 actions, you'd need 2,000 specialized handlers. Worse, adding a new action requires touching every entity type, and adding a new entity type requires implementing every action.

The Interactive Fiction Example

In a text adventure game:

  • Player types TAKE AXE
  • Standard behavior: move axe to player's inventory
  • But THIS axe belongs to a living troll
  • Desired behavior: block with "The troll's axe seems white-hot. You can't hold on to it."

How do we let the axe (or more precisely, something about the axe) override the standard taking behavior?

The General Form

This problem appears whenever you have:

Entity (with attributes) × Operation → Behavior

And you want the behavior to be:

  1. Determined at runtime based on entity state
  2. Extensible without modifying core code
  3. Composable from multiple sources (platform, extensions, application)

Traditional Solutions and Their Limitations

Sub-classing (Inheritance)

class TrollAxe extends Axe {
  take(actor: Actor): Result {
    if (this.troll.isAlive) {
      return blocked("white_hot_message");
    }
    return super.take(actor);
  }
}

Problems:

  • Rigid hierarchy; an item can't be both a TrollAxe and a MagicWeapon
  • New actions require adding methods to base classes
  • Diamond inheritance problems
  • Can't add behaviors from external packages

Event Hooks (Observer Pattern)

world.on('before:take', (event) => {
  if (event.target.id === 'axe' && troll.isAlive) {
    event.cancel("white_hot_message");
  }
});

Problems:

  • Global handlers; hard to trace which handler affects which entity
  • Order-dependent; handlers fight for priority
  • Weak typing; handlers receive generic events
  • No structured way to register/un-register

Visitor Pattern

class TakeVisitor {
  visitAxe(axe: Axe): Result { /* standard */ }
  visitTrollAxe(axe: TrollAxe): Result { /* blocked */ }
  visitDoor(door: Door): Result { /* can't take */ }
}

Problems:

  • Visitor must know all entity types upfront
  • Adding new entity types requires modifying visitor
  • Entity types leak into action code

Strategy via Callbacks

axe.onTake = (actor) => {
  if (troll.isAlive) return blocked();
  return defaultTake(actor);
};

Problems:

  • Ad-hoc; no structure or discoverability
  • Can only have one handler per action
  • No composition or layering

Capability Dispatch Architecture

Capability Dispatch separates the problem into four concerns:

1. Traits (Capabilities Declaration)

Traits are composable units of data and capability claims attached to entities:

class TrollAxeTrait implements ITrait {
  static readonly type = 'dungeo.trait.troll_axe';
  static readonly capabilities = ['if.action.taking'] as const;

  guardianId: EntityId;  // Reference to the troll
}

Key properties:

  • Traits declare which actions they can handle via capabilities
  • Traits contain data, not behavior
  • Entities can have multiple traits
  • Traits are added/removed at runtime

2. Behaviors (Capability Implementation)

Behaviors implement the four-phase action pattern for a specific trait+action combination:

const TrollAxeTakingBehavior: CapabilityBehavior = {
  validate(entity, world, actorId, sharedData) {
    const trait = entity.get<TrollAxeTrait>('dungeo.trait.troll_axe');
    const guardian = world.getEntity(trait.guardianId);
    if (guardian && CombatBehavior.isAlive(guardian)) {
      return { valid: false, error: 'dungeo.axe.white_hot' };
    }
    return { valid: true };
  },

  execute(entity, world, actorId, sharedData) {
    // Not needed - standard taking handles it
  },

  report(entity, world, actorId, sharedData) {
    return [];
  },

  blocked(entity, world, actorId, error, sharedData) {
    return [{ type: 'action.blocked', payload: { messageId: error } }];
  }
};

3. Registry (Binding)

The registry connects trait types to behaviors for specific actions:

registerCapabilityBehavior(
  TrollAxeTrait.type,        // 'dungeo.trait.troll_axe'
  'if.action.taking',        // Action ID
  TrollAxeTakingBehavior     // Behavior implementation
);

The registry is a simple map:

Key: "{traitType}:{actionId}"
Value: CapabilityBehavior

4. Dispatch (Resolution)

At runtime, when an action executes:

// 1. Find trait on entity that claims this capability
const trait = findTraitWithCapability(entity, actionId);

// 2. If found, get the registered behavior
if (trait) {
  const behavior = getBehaviorForCapability(trait, actionId);

  // 3. Let behavior validate first (can block)
  const result = behavior.validate(entity, world, actorId, {});
  if (!result.valid) {
    return blocked(result.error);
  }
}

// 4. Proceed with standard action logic
return standardAction.validate(context);

The Flow

┌─────────────┐     ┌──────────────┐     ┌────────────────┐
│   Action    │────▶│   Entity     │────▶│    Trait       │
│  (taking)   │     │   (axe)      │     │ (TrollAxeTrait)│
└─────────────┘     └──────────────┘     └────────────────┘
                                                  │
                                                  │ claims 'if.action.taking'
                                                  ▼
                    ┌──────────────┐     ┌────────────────┐
                    │   Registry   │── ─▶│   Behavior     │
                    │              │     │ (validate/exec)│
                    └──────────────┘     └────────────────┘

Design Patterns Employed

Capability Dispatch combines several established patterns:

Double Dispatch

Traditional single dispatch selects a method based on one type (the receiver):

entity.take()  // Dispatch based on entity's class

Double dispatch selects based on TWO types:

Action Type × Trait Type → Behavior

This avoids the need for entity classes to know about all possible actions, and for actions to know about all possible entity types.

Strategy Pattern

Behaviors are interchangeable strategies implementing a common interface:

interface CapabilityBehavior {
  validate(entity, world, actorId, sharedData): ValidationResult;
  execute(entity, world, actorId, sharedData): void;
  report(entity, world, actorId, sharedData): Effect[];
  blocked(entity, world, actorId, error, sharedData): Effect[];
}

Different behaviors can be swapped in for the same trait+action combination (useful for testing or difficulty modes).

Registry Pattern

A central registry holds bindings and provides lookup:

const behaviorRegistry = new Map<string, TraitBehaviorBinding>();

function registerCapabilityBehavior(traitType, capability, behavior) {
  behaviorRegistry.set(`${traitType}:${capability}`, { ... });
}

function getBehaviorForCapability(trait, capability) {
  return behaviorRegistry.get(`${trait.type}:${capability}`)?.behavior;
}

Composition Over Inheritance

Entities don't inherit from specialized classes. Instead, they're composed of traits:

const axe = world.createEntity('axe', EntityType.ITEM);
axe.add(new IdentityTrait({ name: 'bloody axe', ... }));
axe.add(new TrollAxeTrait({ guardianId: troll.id }));
// axe.add(new MagicWeaponTrait({ ... }));  // Can add more!

An entity's behavior emerges from its trait composition, not its position in a class hierarchy.

Extension Object Pattern

Traits act as extension objects - they extend an entity's capabilities without modifying its core class. The entity doesn't need to know what traits might be attached to it.


Implementation

Trait Definition

// packages/world-model/src/traits/trait.ts
export interface ITrait {
  readonly type: string;
}

export interface ITraitConstructor {
  readonly type: string;
  readonly capabilities?: readonly string[];
  new(...args: any[]): ITrait;
}

Capability Discovery

// packages/world-model/src/capabilities/capability-discovery.ts
export function findTraitWithCapability(
  entity: IFEntity,
  capability: string
): ITrait | undefined {
  for (const trait of entity.traits) {
    const constructor = trait.constructor as ITraitConstructor;
    if (constructor.capabilities?.includes(capability)) {
      return trait;
    }
  }
  return undefined;
}

Behavior Registration

// packages/world-model/src/capabilities/capability-registry.ts
const behaviorRegistry = new Map<string, TraitBehaviorBinding>();

export function registerCapabilityBehavior(
  traitType: string,
  capability: string,
  behavior: CapabilityBehavior
): void {
  const key = `${traitType}:${capability}`;
  if (behaviorRegistry.has(key)) {
    throw new Error(`Behavior already registered for ${key}`);
  }
  behaviorRegistry.set(key, { traitType, capability, behavior });
}

Engine Integration

// packages/engine/src/action-executor.ts
private executeAction(action: Action, context: ActionContext): ActionResult {
  // Check for capability-based blocking BEFORE standard validation
  const blockResult = this.checkCapabilityBlocking(action, context);
  if (blockResult) {
    return this.handleBlocked(action, context, blockResult);
  }

  // Proceed with standard action flow
  const validationResult = action.validate(context);
  // ... rest of action execution
}

private checkCapabilityBlocking(
  action: Action,
  context: ActionContext
): ValidationResult | null {
  const target = context.command.directObject?.entity;
  if (!target) return null;

  const trait = findTraitWithCapability(target, action.id);
  if (!trait) return null;

  const behavior = getBehaviorForCapability(trait, action.id);
  if (!behavior) return null;

  const result = behavior.validate(target, context.world, context.player.id, {});
  return result.valid ? null : result;
}

Real-World Analogies

This pattern appears in many domains beyond interactive fiction:

Authorization / Policy Engines (ABAC)

Resource (attributes) × Action (operation) → Policy Decision

Examples: Open Policy Agent (OPA), AWS IAM, Azure RBAC

A request to DELETE a resource with SensitiveData=true attribute triggers a different policy than the same operation on a regular resource. The policy engine performs double dispatch based on resource attributes and requested operation.

Mapping:

SharpeeABAC
EntityResource
TraitResource Attribute
ActionOperation (read/write/delete)
BehaviorPolicy Rule
RegistryPolicy Store

HTTP Content Negotiation

Request (headers) × Route (endpoint) → Handler

Examples: Express.js middleware, ASP.NET Core, JAX-RS

POST /users request with Content-Type: application/json routes to a different handler than the same endpoint with Content-Type: application/xml. The framework dispatches based on route AND request attributes.

Mapping:

SharpeeHTTP
EntityRequest
TraitHeader (Content-Type, Accept-Language)
ActionRoute/Method
BehaviorHandler
RegistryRoute Table + Content Handlers

Business Rule Engines

Facts (entity state) × Event (trigger) → Rule Firing

Examples: Drools, IBM ODM, Azure Logic Apps

An insurance claim with ClaimType=Medical and Amount>10000 triggers different processing rules than a small auto claim. The rule engine matches facts against conditions and fires appropriate rules.

Mapping:

SharpeeRule Engine
EntityFact/Working Memory Object
TraitFact Attributes
ActionEvent/Trigger
BehaviorRule Consequence
RegistryRule Base

Plugin/Extension Systems

Context (host state) × Extension Point (hook) → Plugin Handler

Examples: VSCode extensions, WordPress hooks, Webpack plugins

A file with .md extension triggers the Markdown formatter plugin when the "format" command is invoked. The host dispatches based on context (file type) AND extension point (command).

Mapping:

SharpeePlugin System
EntityContext/Document
TraitContext Attributes (file type, mode)
ActionExtension Point/Hook
BehaviorPlugin Handler
RegistryExtension Registry

Medical Clinical Decision Support

Patient (conditions) × Order (medication) → CDS Alert

Examples: Epic CDS, Cerner Alerts, HL7 FHIR CDS Hooks

A patient with Condition=Diabetes receiving a prescription for a contraindicated medication triggers a clinical alert. The CDS system dispatches based on patient attributes AND the clinical action.

Mapping:

SharpeeMedical CDS
EntityPatient
TraitCondition/Allergy/Lab Result
ActionOrder/Prescription
BehaviorCDS Rule/Alert
RegistryKnowledge Base

The Common Thread

All these systems share the fundamental challenge:

How do you determine behavior based on BOTH what you're operating on AND what operation you're performing, in an extensible way?

The solutions converge on similar architectures:

  1. Entities/resources with composable attributes
  2. Operations/actions as first-class concepts
  3. External registration of handlers
  4. Runtime dispatch based on attribute+operation matching

Benefits and Trade-offs

Benefits

Extensibility Without Modification

  • Add new entity behaviors without changing entity classes
  • Add new actions without changing trait definitions
  • Three-tier extension: platform → extensions → application

Composition Over Inheritance

  • Entities combine multiple traits freely
  • No diamond inheritance problems
  • Behaviors compose naturally

Separation of Concerns

  • Traits define data and capability claims
  • Behaviors implement logic
  • Registry manages bindings
  • Actions orchestrate flow

Testability

  • Behaviors are pure functions (entity, world, actor → result)
  • Registry can be cleared/mocked for testing
  • No hidden global state in entities

Discoverability

  • getAllCapabilityBindings() shows all registered behaviors
  • Traits explicitly declare their capabilities
  • Clear audit trail of what handles what

Trade-offs

Indirection

  • Behavior isn't on the entity; must trace through registry
  • Debugging requires understanding the dispatch flow
  • IDE "go to definition" doesn't work naturally

Registration Timing

  • Behaviors must be registered before use
  • Order of registration matters for initialization
  • Missing registrations fail at runtime, not compile time

Single Behavior Per Trait+Action

  • Can't have multiple behaviors for same combination
  • Must compose within a single behavior if needed
  • No built-in priority/ordering for multiple handlers

Runtime Cost

  • Trait iteration and map lookup on every action
  • Negligible for IF (tens of entities) but consider for high-frequency systems

Mitigations

For Indirection:

  • Consistent naming: {Entity}{Action}Behavior
  • Logging/tracing in dispatch path
  • Documentation of capability chains

For Registration:

  • Fail-fast validation on startup
  • Type-safe registration helpers
  • Clear initialization order in stories

For Single Behavior:

  • Behaviors can delegate to sub-behaviors
  • Chain of responsibility within a behavior
  • Explicit composition patterns

Conclusion

Capability Dispatch provides a principled solution to the entity×operation combinatorial problem. By combining double dispatch, composition, and a behavior registry, it enables:

  • Platform code to define standard action semantics
  • Extension packages to add reusable mechanics
  • Application code to customize per-entity behavior

The pattern appears across diverse domains—authorization systems, HTTP frameworks, rule engines, plugin architectures, and clinical decision support—suggesting it addresses a fundamental need in extensible software design.

For Sharpee, Capability Dispatch means a text adventure's troll can have a "white-hot axe" that blocks taking with a custom message, without modifying the taking action, without sub-classing the axe, and without global event handlers. The troll story adds a trait, registers a behavior, and the engine handles the rest.

The axe doesn't know it's special. The taking action doesn't know about trolls. The magic happens in the space between them.


References

  • ADR-090: Entity-Centric Action Dispatch (Sharpee Architecture Decision Record)
  • Gamma et al.: Design Patterns (Visitor, Strategy, Registry patterns)
  • Fowler: Patterns of Enterprise Application Architecture (Plugin, Registry)
  • OASIS XACML: Attribute-Based Access Control specification
  • HL7 FHIR CDS Hooks: Clinical Decision Support specification

Sharpee is an open-source interactive fiction engine. For more information, see the project repository.

5 days ago

Renga in Blue - Jan 15

Haunted House: Pray Harder

(Continued from my previous post.) Just to recap from last time, here was the state of my map, with special rooms marked. I also had access to a candle, a box of matches, a bottle of spirits, some food, a map (all used) as well as a book of ghost stories, a tray of drinks, […] 7 days ago

(Continued from my previous post.)

Just to recap from last time, here was the state of my map, with special rooms marked.

I also had access to a candle, a box of matches, a bottle of spirits, some food, a map (all used) as well as a book of ghost stories, a tray of drinks, a packet of crisps, a bar of soap, a knife, a uniform, a rope with hook, pots, a painting, some electrodes, and some tomatoes (all unused). I was facing a wolf by a coffin, a monster in a secret passage, a room getting locked with a princess, a lift that wasn’t moving, and a room blocked by a ghost (supposedly afraid of uniforms, but nothing I could do with uniform was triggering it!)

I went through my usual verb list with the catch this is generally a two-letter parser.

CL(IMB)
SW(IM)
RE(AD)
LI(GHT)
RU(B)
PR(AY)
PU(LL)
US(E)
EX(AMINE)
IN(SERT)
LE(AVE)
HI(T)
SH(OOT)
KI(LL)

HIT, SHOOT, and KILL all have a response about not being so violent, which suggests they don’t work at all. (It also explains when I tried KISS PRINCESS — it was required in Pillage Village, remember — that the response was “you’re not cruel.” It wasn’t trying to be progressive about kissing consent, the game thought that I was typing KILL PRINCESS.)

After multiple fruitless attempts and managing the uniform/ghost combo I started working on the monster instead. GIVE isn’t a verb but DROP is (drop is how I gave the spirits to the drunk) so I went through a variety of items just to test things out.

“But they’re Monster Munch! You don’t like them?”

I tried HELP out just in case this was the sort of game help is a required verb and the game informed me:

I suppose you could try praying!!

So I tried PRAY:

That didn’t seem to help!!
Maybe you didn’t try hard enough!!

Alas, PRAY HARDER gets no different reaction (I doubt the parser even looked at the second word, to be honest). I eventually hit upon dropping the electodes…

…which sort of makes sense if you squint, but not really.

Past the monster are two rooms.

With the antique my score was now safely 2 out of 7, and I thought it would become 3 out of 7 shortly with the keys. They do work in the princess room (USE KEYS)…

…but the princess refuses to move. This was the moment in Pillage Village where KISS was required. Princess, are you sure you want to hang out in the dungeon…?

The princess refuses.

With me befuddled, I tried more attempts at the ghost.

Maybe you’d prefer some Crispy Bacon Frazzles? I can’t eat them myself, there’s no EAT command.

The rest of my time was spent frustrated. I tried USE KEYS at the man the stocks and the tomatoes, no dice. I tried every verb on my list on the lift, again no dice. (“USE LIFT”: “You’re trying to confuse me!”) I am nearly guaranteed now to check either the walkthrough or at least the source code, but I wanted to report in on my progress here first. The main issue isn’t it doesn’t feel like I’m “stuck on a puzzle” as much as fighting against the system; I’m guessing at least once I’ve done the right thing, just expressed in the wrong way.

The wolf really doesn’t like crisps.

(Also, people picked up on last time there’s a certain other game from 1981 Lucas is “borrowing” from that is not by him, but I want to save getting into that for my final post.)

7 days ago

My So Called Interactive Fiction Life - Jan 13

Sharpee - The Final Design Conversation with Claude

Note: I did agree not to post AI material, but this is an important conversation I had with Claude. It's not Claude's ramblings about Sharpee. It's a Q&A design session that I believe merits sharing in full.

Design Session: Text Service & 9 days ago
Sharpee - The Final Design Conversation with Claude

Note: I did agree not to post AI material, but this is an important conversation I had with Claude. It's not Claude's ramblings about Sharpee. It's a Q&A design session that I believe merits sharing in full.

Design Session: Text Service & Client Architecture

Date: 2026-01-13
Branch: chaining
Subject: The final design of how the text service and varying types of clients work together.
Participants: Dave Cornelson, Claude (Opus 4.5)
Status: Architecture finalized, ready for implementation


Overview

This session designed Sharpee's text output architecture from first principles, covering template syntax, TextBlock contracts, and client rendering. The design is inspired by FyreVM channel I/O (2009).


The Challenge

"We're going to test your ability to juggle complexity"

The goal: think through the entire text output system holistically:

  • lang-en-us: Templates, formatters, prose
  • text service: Middleware orchestration
  • client: How we display the story

Scoping the Problem

CLI

"I think we can say CLI is simple and we've more or less already proven how it works"

CLI is solved - just concatenate TextBlocks with whitespace.

GLK

"I would say glk is an interesting IF thing, but it's worth an ADR with identified as the status"

GLK is a known future concern - park it as ADR-099 with status "identified".

Screen Reader / Accessibility

"There are a lot of blind IF players so I really love the idea of making Sharpee an easy path for authors to make games accessible"

Accessibility is a priority, not an afterthought. ADR-100 for screen reader support.

React / Electron

"the big one is react/electron and I think we have to consider them side by side"

React is the main focus. Works in both browser and Electron contexts.


Unified Template Syntax

The Problem

ADR-091 (Text Decorations) and ADR-095 (Message Templates) had overlapping concerns:

  • ADR-095: {modifier:placeholder} for formatters
  • ADR-091: Needed decorations on both placeholders AND literal text

The Solution

Dave: "yes let's figure out a unified syntax"

Three distinct syntaxes for distinct purposes:

{formatter:placeholder}     - Transformations (a, the, list, cap)
[type:content]              - Semantic decorations (item, room, npc)
*emphasis* / **strong**     - Inline prose decoration

Can be combined:

[item:{a:item}]             - Resolve placeholder, then mark as item-type
*{adverb}*                  - Resolve placeholder, then emphasize

Key insight: Formatters transform, decorations annotate. Different operations, different syntax.


Single TextService + Multiple Renderers

DRY Principle Applied

Dave: "let's add some basic developer principles (DRY) into the mix"

With multiple text services, you'd repeat:

  • Template resolution logic
  • Formatter logic (articles, lists)
  • Decoration parsing
  • Language layer integration

What actually differs per client: only rendering.

Architecture

┌─────────────────────────────────────────────────────────┐
│                    lang-en-us                           │
│  Templates, formatters, noun types, prose               │
└─────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────┐
│                    TextService                          │
│  Resolves templates → parses decorations → TextBlocks   │
│  (ONE implementation, shared)                           │
└─────────────────────────────────────────────────────────┘
                          │
                          ▼
                     TextBlocks
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
   ┌─────────┐       ┌─────────┐       ┌─────────┐
   │  React  │       │   CLI   │       │  JAWS   │
   │ Renderer│       │ Renderer│       │ Renderer│
   └─────────┘       └─────────┘       └─────────┘

Each renderer is small - just maps decoration types to platform output.


Formalized TextBlock Contract

Dave: "do we formalize the text blocks?"

Yes - TextBlocks become a concrete, typed contract.

Package Location

@sharpee/text-blocks - pure interfaces, no implementation

Interface Design

type TextContent = string | IDecoration;

interface IDecoration {
  type: string; // Open - 'em', 'item', 'photopia.red'
  content: TextContent[]; // Can nest
}

interface ITextBlock {
  key: string; // Channel - 'room.description', 'status.score'
  content: TextContent[];
}

Language Agnostic

Dave: "do text blocks need to be language specific: textblocks-en-us"

No. TextBlocks are a universal container format. The prose inside is localized, but the structure is the same.

// Same ITextBlock shape, different language content

// English
{ key: 'action.result', content: ['You take the sword.'] }

// German
{ key: 'action.result', content: ['Du nimmst das Schwert.'] }

FyreVM Channel I/O Inspiration

Dave: "you just reinvented fyrevm channel IO Mr. Claude (though I actually invented it in 2009 with help from Tara McGrew and inspired by Jeff Panici)"

Credit where due! The architecture draws from proven design.

Channel = Block Key

{ key: 'room.description', content: [...] }  // Channel: room
{ key: 'action.result', content: [...] }     // Channel: action
{ key: 'status.score', content: [...] }      // Channel: status

Key Conventions

Prefix Purpose Client Routing
room.* Room info Main transcript
action.* Action results Main transcript
status.* Status bar elements Fixed header slots
error System errors Main transcript (styled)
prompt Command prompt Input area
{story}.* Story-defined Configurable

Extensibility

Dave: "they start pre-defined, but I created a way for authors to make their own and use them in storytelling"

Same pattern in Sharpee:

  • Core keys defined by platform
  • Stories can define custom keys
  • Clients render unknown keys with sensible defaults

Browser Architecture

Dave: "the engine bundles game and sharpee to {game}.js and runs in the browser (we've already done this and it's fast)"

No server. No API layer. Everything runs client-side.

┌─────────────────────────────────────────────────────────┐
│  {game}.js (bundled)                                    │
│  Engine + WorldModel + Story + TextService + lang-en-us │
└─────────────────────────────────────────────────────────┘
                          │
                          │ on('turn-complete') → ITextBlock[]
                          ▼
┌─────────────────────────────────────────────────────────┐
│  React Client                                           │
│  Receives ITextBlock[], renders to DOM                  │
└─────────────────────────────────────────────────────────┘

Event-Based Client Communication

The IF Model

Dave: "in IF we have one stream of text blocks including any daemons and npcs - the client would never handle anything but one set of text blocks"

One stream. Everything mixed. Client just renders.

engine.on('turn-complete', (blocks: ITextBlock[]) => {
  // One array - command results, daemons, NPCs, everything
  setTranscript((prev) => [...prev, ...blocks]);
});

No routing logic. No "handling" different event types. Just:

  1. Receive blocks
  2. Append to transcript
  3. Render

Status Line Design

Not Special

Dave: "I see the status line as no different than any other rendered text block"

Status elements are just more blocks with status.* keys:

{ key: 'status.room', content: [{ type: 'room', content: ['West of House'] }] }
{ key: 'status.score', content: ['0'] }
{ key: 'status.turns', content: ['1'] }

Multiple Blocks, Not One Object

Dave: "B is the way I think" (choosing Option B: multiple sub-keyed blocks)

React routes by key to slots:

<StatusBar>
  {blocks.filter(b => b.key.startsWith('status.')).map(renderToSlot)}
</StatusBar>
<Transcript>
  {blocks.filter(b => !b.key.startsWith('status.')).map(renderBlock)}
</Transcript>

Story-Defined Colors (Photopia Pattern)

Dave: "think about how Sharpee would handle Adam Cadre's Photopia colors"

Photopia uses color as narrative. Authors need full creative control.

Solution

Authors define semantic color names in story config:

// stories/photopia/src/config.ts
export const storyColors = {
  'photopia.red': '#cc0000', // Alley's scenes
  'photopia.blue': '#0066cc', // Fantasy scenes
};

Templates use semantic names:

'[photopia.red:The light was red, like always.]'

Client looks up mapping, renders appropriately:

  • Web: actual CSS color
  • CLI: ANSI approximation
  • Screen reader: announces "red text" or ignores

IDecoration Type is Open

interface IDecoration {
  type: string; // Open - 'em', 'item', 'photopia.red'
  content: TextContent[];
}

Type is open string, not enum. Core types are conventions, not constraints.


Decoration Types

Semantic vs Presentational

Semantic Presentational
item em (italic)
room strong (bold)
npc underline
command strikethrough
direction super / sub
(story-defined) (story colors)

Decisions Summary

Topic Decision
Template syntax Unified: {formatter:placeholder}, [type:content], *emphasis*
TextService Single service, multiple renderers (DRY)
TextBlocks Formalized ITextBlock contract, language-agnostic
Decoration type Open string (not enum) for extensibility
Channel keys Core prefixes + story-extensible
Client communication Event-based: on('turn-complete')
Status line Multiple status.* blocks, not special
Colors Story-defined semantic names
Priority/role fields Dropped (YAGNI)

ADR Map

ADR Topic Action
091 Text Decorations Finalize - hybrid syntax decision
095 Message Templates Update - align with 091
096 Text Service New - architecture, ITextBlock, channels
097 React Client New - event-based, components
099 GLK Client New - status: identified
100 Screen Reader New - status: identified

Package Structure

New Packages

  • @sharpee/text-blocks - Interfaces (ITextBlock, IDecoration)
  • @sharpee/text-service - Single service implementation
  • @sharpee/client-react - React client (greenfield)

Archived

  • text-services → archive
  • text-service-browser → archive
  • text-service-template → archive

Key Quotes

"the Sharpee Way would be event based" - Dave

"you just reinvented fyrevm channel IO" - Dave (on the architecture)

"I'd toss the current implementation and design for what we're designing now" - Dave (clean slate)

"everything is greenfield Mr. Claude" - Dave


Next Steps

  1. Write/update ADRs (091, 095, 096, 097, 099, 100)
  2. Create @sharpee/text-blocks package
  3. Create @sharpee/text-service package
  4. Archive existing text-service packages
  5. Implement React client

This document preserves the design thinking and decisions from a pivotal architecture session.

9 days ago

My So Called Interactive Fiction Life - Jan 11

Another Parser Refactor(ial) and Scope

In the process of porting Dungeo to Sharpee, we got to a completed implementation, but some unit tests missed important steps. When I started a "walkthrough" test in phases, we discovered a glaring gap in my grammar and parser implementation. I should say fundamental misunderstanding of what the

11 days ago

In the process of porting Dungeo to Sharpee, we got to a completed implementation, but some unit tests missed important steps. When I started a "walkthrough" test in phases, we discovered a glaring gap in my grammar and parser implementation. I should say fundamental misunderstanding of what the grammar definitions are responsible for, what the parser does, and what happens in actions in the standard library.

The grammar builder was trying to do some of the validation ahead of time. It took a few iterations to convince Claude this was incorrect (the stubbornness comes from all of the history of docs in the project, not Claude hallucinating).

We updated the Grammar Builder to be very simple. It connects patterns to actions and defines required Traits. Here's examples of the old builder and the new one.

OLD: Scope + boolean property matching in grammar

  grammar
    .define('put :item in :container')
    .where('item', (scope) => scope.carried())
    .where('container', (scope) => scope
                    .touchable()
                    .matching({ container: true }))
    .mapsTo('if.action.inserting')
    .build();

  grammar
    .define('board :vehicle')
    .where('vehicle', (scope) => scope
                    .visible()
                    .matching({ enterable: true }))
    .mapsTo('if.action.entering')
    .build();

  NEW: Traits only - scope moved to action validation

  grammar
    .define('put :item in :container')
    .hasTrait('container', TraitType.CONTAINER)
    .mapsTo('if.action.inserting')
    .build();

  grammar
    .define('board :vehicle')
    .hasTrait('vehicle', TraitType.ENTERABLE)
    .mapsTo('if.action.entering')
    .build();

  Key changes:
  - Removed .visible(), .touchable(), .carried()
        - scope now handled by action validate()
  - Replaced .matching({ container: true })
        with .hasTrait('slot', TraitType.CONTAINER)
  - Grammar declares only semantic constraints (what kind of entity),
    not scope (visibility/reachability)

And this leads to handling scope and validation more efficiently:

 Action Scope Validation (NEW)

  Scope is now handled in action validate() with a 4-tier system:

  /**
   * 4-tier scope hierarchy (ordered - higher implies lower)
   */
  enum ScopeLevel {
    UNAWARE = 0,    // Entity not known to player
    AWARE = 1,      // Player knows it exists (think about, ask about)
    VISIBLE = 2,    // Can see it (examine, look at, read)
    REACHABLE = 3,  // Can physically touch (take, push, open)
    CARRIED = 4     // In inventory (drop, eat, wear, insert)
  }

  Example: Opening Action

  export const openingAction: Action = {
    id: 'if.action.opening',

    // Document default scope for this action
    defaultScope: {
      target: ScopeLevel.REACHABLE
    },

    validate(context: ActionContext): ValidationResult {
      const target = context.command.directObject?.entity;

      if (!target) {
        return { valid: false, error: 'NO_TARGET' };
      }

      // Check scope - must be able to reach the target
      const scopeCheck = context.requireScope(target, ScopeLevel.REACHABLE);
      if (!scopeCheck.ok) {
        return scopeCheck.error!;  // Returns "You can't reach that" etc.
      }

      // Check trait - must be openable
      if (!target.has(TraitType.OPENABLE)) {
          return { valid: false, error: 'NOT_OPENABLE',
                params: { item: target.name } };
      }

      // Check state - must be closed
      if (!OpenableBehavior.canOpen(target)) {
        return { valid: false, error: 'ALREADY_OPEN',
                params: { item: target.name } };
      }

      return { valid: true };
    },
    // ...
  };

  Example: Examining Action (VISIBLE scope)

  export const examiningAction: Action = {
    id: 'if.action.examining',

    defaultScope: {
      target: ScopeLevel.VISIBLE  // Only need to see it, not touch
    },

    validate(context: ActionContext): ValidationResult {
      const target = context.command.directObject?.entity;

      if (!target) {
        return { valid: false, error: 'NO_TARGET' };
      }

      // Examining yourself always works
      if (target.id !== context.player.id) {
        const scopeCheck = context.requireScope(target, ScopeLevel.VISIBLE);
        if (!scopeCheck.ok) {
          return scopeCheck.error!;  // "You can't see any such thing"
        }
      }

      return { valid: true };
    },
    // ...
  };

The most important thing these changes enabled was composable traits. The previous implementation was unable to handle that and now we have working composition.

11 days ago

Zarf Updates - Jan 10

2026 IGF nominees

Oh gosh! The IGF finalists are up. I played a bunch in the first judging round. Many of these are already in my review list, including The Drifter, Öoo, Strange Jigsaws, Type Help, The Roottrees Are Dead, and Mini Mini Golf Golf. I am amused ... 12 days ago

Oh gosh! The IGF finalists are up.

I played a bunch in the first judging round. Many of these are already in my review list, including The Drifter, Öoo, Strange Jigsaws, Type Help, The Roottrees Are Dead, and Mini Mini Golf Golf.

I am amused that four games in that IGF post wound up in my review post titled "Weird little games, summer edition". I didn't know they were IGF entries when I wrote that; I just knew they were little and weird. It's great to see the appreciation of weird little games is shared among the discerning game-playing community.

Of course I am happy to see that Roottrees and Type Help continue to get recognition. I can't wait for Incident at Galley House, the Type Help remake.

Games which I have not yet played but I clearly need to: Perfect Tides: Station to Station, Blippo+, Angelina Era, and all the other titles that I haven't mentioned but in no way mean to slight.

Extra shoutout to Titanium Court. I have not played this and I do not know a damn thing about it, but as soon as the IGF post dropped, my social circles were flooded by awesome game-design folks saying "Titanium Court! I can talk about it now! Titanium Court! You gotta play it!" (As soon as it's out -- no release date yet.) So, I guess I gotta play it.

Anyway, here's what you want: games that I have played but not yet discussed. This includes both IGF finalists and entries that didn't get an official mention but they're worth a word anyhow.

  • Arctic Awakening
  • Promise Mascot Agency
  • The Haunting of Joni Evers
  • Carceri
  • Prší
  • Kid Cosmo
  • and Roger
  • Jane

Arctic Awakening

A narrative exploration game in five episodes. You're stuck in Alaska with only the wreckage of your airplane and your court-assigned therapy bot for company. What's going on, and why do you keep discovering abandoned weird science labs?

I am mixed on this one. The dialogue and the voice acting are great. Grumpy Guy and Perky Bot are a solid double act, and I enjoyed spending time with them. But, to be clear, you spend a lot of time with them. Most of the game is walk-and-talking through the wilderness. To be fair, the wilderness has grandeur. Think Firewatch with snow -- not hyper-realistic, but great mountain vistas and charismatic megastructures.

There's light puzzling, mostly of the "find this object, it's around here somewhere" variety. This can get annoying if you happen to miss the object for a while. Just keep poking. Beyond that, the game tracks a lot of story state -- again, Firewatch-style. Minor story state, though; it's not a seriously branching plot.

I feel like the overall structure doesn't quite hang together. It's supposed to be a dual plot: discovering the secrets of the world, and working through your emotional issues. Thread #1 has a lot of meat on it, but doesn't exactly resolve; the last-act reveals are rushed, and manage to be both obvious and incomplete. As for thread #2, it mostly consists of your annoying bot friend trying to get you to open up about your life, while you tell him (correctly) that this is less important than getting home. It just doesn't really fit the ending they want you to arrive at.

I had a good time, but the game doesn't exceed the sum of its parts.

Promise Mascot Agency

Disgraced yakuza enforcer is sent to the town of out-of-work live mascots. Hijinks ensue.

This is very pleasant. (Once I got past the initial money crunch, which is a bit scary even in easy mode.) It's GTA with all the hostile cops and high-pressure race scenes stripped out, which is honestly a brilliant idea and exactly what I need in my life right now.

The setting is self-consciously ridiculous. Not as completely ridiculous as Paradise Killer, which was lofted entirely on its absurdist beach-town-of-Elder-God-Things vibe. But dead-serious yakuza mob war cheered on by a walking thumb and a block of sentient tofu are almost as good. All the characters are a joy to hang with, each in their own over-the-top way.

PK's plot was almost entirely backstory. I can see the designers are pushing to have a more active story this time, but the pacing isn't great. If you are assiduous about side missions (and why would you play a package-hunting game without lawnmowering the side missions?), then the plot hangs and hangs and then slams down on you at the end. It's good stuff, but the last half of the last act turns into a sequence of cut scenes. Sigh.

I guess my real complaint is that the setting is amusing, in its over-the-top Japanese mob-and-mascot schtick. (The entire voice track is subtitled Japanese -- remember that the developers are British!) But I didn't spend the game repeatedly shouting "They did what?!" Which was the Paradise Killer vibe, and I miss it.

Not enough weird cosmic horror in the mix, is what I'm saying. Not none! Karoushi kicks ass. Needs more though.

The Haunting of Joni Evers

Walking sim about a woman's hangups about her family.

This is well-presented, but it drags out a fairly simple idea rather too long. It's three hours of the narrator talking about her family memories. She does her damnedest but the characters never really came alive for me (pun half-intended) (they're ghosts or something, see). Without that, the whole thing felt stilted and overstuffed.

(With an evil spirit for punctuation, but he never becomes more than a spooky cartoon. Weakest part of the game, really; they could have left him out.)

This is notionally part of a horror anthology series, "Worlds Across the Causeway". I didn't get a sense of the larger world beyond the phrase, though. I'd play another one -- three hours isn't much time to invest! But I'm not yet convinced by the concept.

Carceri

A cheerful, talky platformer. You run around a candy-colored low-poly virtual world tagging little fox dudes. Sorry, I mean: infecting daemon processes with a sentient virus, which rewards you by levelling up your reality-warping powers. To wit: jump and then double-jump. (There's a third powerup but I won't spill the beans.)

At the end, you can listen to an hour-long philosophy discussion between the author and himself. It's like The Witness without any of those tedious puzzles!

...Okay, I'm being snarky. This is really very pleasant. The world is full of little corners to explore: libraries, art museums, a beach resort. Yes, a Piranesi-inspired prison labyrinth as well. All floating in a grand cyberspatial void. It reminded me of Fract: OSC, except that the only "puzzle" is not getting lost. The jumping isn't that hard either, and that's the whole game.

A complete run-through took me two hours. (I ignored all the in-game photo stuff and just explored.) The author says "virtual vacation" and honestly I was happy to take it.

Prší

One of the regulars in your favorite Czech dive bar has disappeared. What are you going to do about it? Play cards, ask questions, and drink a truly catastrophic volume of beer.

This is delightful. The dialogue UI is built on playing cards -- and drinking beer -- in a way that I haven't seen before. The bar is built in a warped claymation style, which entirely suits both the story and the cultural setting. (Švankmajer fan game!) Really, everything about this is perfect.

(Now I want someone to adapt Fritz Leiber's "Gonna Roll the Bones" in a similar way.)

Kid Cosmo

A narrative puzzle game about playing narrative puzzle games with your annoying sister in the alt-1980s.

This is well-built, but it felt a little unmotivated. There's some kind of alt-history leading to the Robot Uprising, which would be interesting if I knew anything about the tie-in movie or even the Simon Stålenhag book it's based on. But I don't. So it's two kids playing a videogame, plus the world has janitor robots and gas-pumping robots. The kids are cute but I don't see the theme.

I put this down after a few chapters. Maybe you'll be more into it.

(Also: I love a lot of break-the-fourth-wall game elements, but for some reason "use the physical tilt sensor" annoys me. Going back to the original release of The Room. I don't know why.)

(Outside-the-car lightning reflecting off the console case was jazz though.)

and Roger

I have seen several games on this theme. (Not spoiling, as the reveal is part of the narrative.) This one works.

The one-button control scheme is master-level. I can't imagine how hard it was to make it feel this easy and natural. And yet expressive, and a surprise each time. You could play the game in another language and get everything important from the button mechanics.

Really, that's all I have to say about it. Top-notch.

Jane

A very short mood piece. You wake up in the middle of the night and wander around the house in your underwear. There's exactly one thing to do.

This is nice! You can argue whether it's substantial enough to be an IGF entry, but IGF judging is done for the year so never mind that. One character, one moment, sweetly presented.

12 days ago

Choice of Games LLC - Jan 08

Throne of Blood—Heaven’s blood, Hell’s throne, your destiny.

Hosted Games has a new game for you to play! The throne of the demon realm calls for blood, and you’re next in line. As a half-angel heir scorned by your kin, you’re thrust into a brutal succession where only one of the Emperor’s children can survive. Outsmart your rivals, wield an ancient celestial power, and decide the fate of a realm that despises you. Throne of Blood is 30% off until January 15 14 days ago
Throne of Blood

Hosted Games has a new game for you to play!

The throne of the demon realm calls for blood, and you’re next in line. As a half-angel heir scorned by your kin, you’re thrust into a brutal succession where only one of the Emperor’s children can survive. Outsmart your rivals, wield an ancient celestial power, and decide the fate of a realm that despises you.

Throne of Blood is 30% off until January 15th!

Throne of Blood is a 295,000-word interactive novel by Kezia S. It’s entirely text-based, without graphics or sound effects, and fueled by the vast, unstoppable power of your imagination.

  • Forge your legacy as male, female, or nonbinary; gay, straight, bi, asexual, or poly.
  • Tap into your celestial heritage to unleash powerful, dangerous magic.
  • Shape the demon realm through reform, fear, or ruthless conquest.
  • Recruit and rule alongside three loyal retainers: a fiery dragonkin knight, a doting childhood friend, and a charming but mysterious knight-mage.
  • Pursue romance with one, two, or all three of your companions in a polyamorous court.
  • Navigate political intrigue and ancient prejudice as demons, angels, and monsters close in.

Kezia developed this game using ChoiceScript, a simple programming language for writing multiple-choice interactive novels like these. Writing games with ChoiceScript is easy and fun, even for authors with no programming experience. Write your own game and Hosted Games will publish it for you, giving you a share of the revenue your game produces.

14 days ago

My So Called Interactive Fiction Life - Jan 05

Sharpee - Grammar, Identity, and Scoring Updates

The port of mainframe Zork is nearly complete, but I keep running into things that impact the platform so I get sidetracked into improving Sharpee over finishing Dungeo.

Scoring

The most recent refactor from the port of Zork was how we enable scoring in the platform and how the author

17 days ago

The port of mainframe Zork is nearly complete, but I keep running into things that impact the platform so I get sidetracked into improving Sharpee over finishing Dungeo.

Scoring

The most recent refactor from the port of Zork was how we enable scoring in the platform and how the author defines things or removes scoring completely. So we created a scoring capability and service that manage scoring events. This is now completely integrated into Sharpee and the Zork port. Anytime there is a scoring event, the game event source receives 'if.event.score' and the details of why. The Text Service will pick up these events and report as needed. The capability also has the standard ranking system that can be modified or replaced.

Grammar

I'd already made some sweeping changes to the parser/grammar system, but found one refactor and a major improvement. The refactor was just in how we're processing grammar. That file had gotten to 1400 lines of code and it was easy enough to create a factory pattern to break up slot logic. The second one was realizing the implementation was verbose. You had to define "N" and "NORTH" separately or "pattern-specific" and we need "action-specific" definitions to allow for synonyms. Both of these are documented in adr-087 and adr-088.

Identity and Story Form

And the work I'm doing now is to enable 1st, 2nd, and 3rd person as well as a wide range of gender identity configurations for PCs and NPC's.

Pronoun Sets

Available via PRONOUNS constant from @sharpee/world-model:

Key Subj Obj Poss Adj Refl Verb
HE_HIM he him his his himself sing
SHE_HER she her hers her herself sing
THEY_THEM they them theirs their themselves plur
XE_XEM xe xem xyrs xyr xemself sing
ZE_ZIR ze zir zirs zir zirself sing
ZE_HIR ze hir hirs hir hirself sing
EY_EM ey em eirs eir emself sing
FAE_FAER fae faer faers faer faerself sing

Legend: Subj=Subject, Obj=Object, Poss=Possessive, Adj=Possessive Adjective, Refl=Reflexive, Verb=Verb Form (sing=singular, plur=plural)

Note: Singular "they" uses plural verb forms ("they are", not "they is").

Honorifics

Available via HONORIFICS constant:

Key Value Usage
MR Mr. Mr. Smith
MRS Mrs. Mrs. Smith
MS Ms. Ms. Smith
MX Mx. Mx. Smith (gender-neutral)
MISS Miss Miss Smith
DR Dr. Dr. Smith
PROF Prof. Prof. Smith

Grammatical Gender

For localization in gendered languages. Separate from pronouns!

Value Use Case Languages
masculine Male grammatical agreement French "il", German "er", Spanish "él"
feminine Female grammatical agreement French "elle", German "sie", Spanish "ella"
neuter Neuter grammatical agreement German "es", Swedish default
common Common gender Swedish "hen", Dutch common gender

Grammatical Number (Inanimate Objects)

For entities without ActorTrait:

Value Pronoun Example
singular (default) it "Take it" (the lamp)
plural them "Take them" (the coins)
17 days ago

Renga in Blue - Jan 05

Adventure 751: The Footsteps of a Thousand Fairies

(Continued from my previous posts.) I’ve taken off enough of a chunk of the game to give a report, including a brand-new-for-751 section, but I’m still not yet past the “fnord” rock. (Incidentally, I’m not sure on the naming of LONG0500 above. There’s text in the November ’78 game which claims the max score is […] 17 days ago

(Continued from my previous posts.)

I’ve taken off enough of a chunk of the game to give a report, including a brand-new-for-751 section, but I’m still not yet past the “fnord” rock.

From Arthur O’Dwyer’s family tree of variations of Adventure.

(Incidentally, I’m not sure on the naming of LONG0500 above. There’s text in the November ’78 game which claims the max score is 500 yet typing SCORE says outright the max score is 501. Also, the commercial version of the game has been rescued off old CompuServe drives and likely should be added as another node off of LONG0751.)

I’ve picked up a few new readers recently, so now is a good time to re-explain my verb list. Verbs marked in green are understood by the game, unmarked verbs are not understood at all.

I don’t do this with every old game I play, but it helps with the particularly ornery ones. I typed every single verb in my standard list (see above) and checked if the verb was understood by the parser or not. (SWIM is understood only to say you aren’t able to swim, so I gave it a different color.)

The process looks like this:

STAB

Mumble? STAB?

HOLD

I don’t understand the word HOLD.

PLAY

Play what?

COOK

I don’t understand the word COOK.

Fortunately, there are two and only two well-defined “I don’t understand that word” prompts so there’s no ambiguity (I’ve played games where I’ve had to either outfox the parser or just give up).

For games with a low vocabulary count, this can help fish out the one unusual phrase a game might need early; even when the density is higher (like here) making the list can help suss out potential issues. For example, RUB is in even though it tends not to be used in Adventure variants (Scott Adams Adventureland, yes) so I need to remember to test it if an object seems like a magical candidate. BUILD is particularly worrisome because it means there’s likely some object that is not previously named that the player will be able to make out of parts (usually it’s a ladder or a bridge). FOLLOW is also fairly rare and not normally one I use; I can think of at least one game where the verb was required to solve a puzzle. CRAWL, KICK, and PUNCH are also worth noting.

The list can help in a “negative space” sense as well; I can tell we are not making much conversation, and SAY only serves to speak a particular word out-loud in the sense of a “magic word”.

While I was busy doing this I also realized something about the safe in the starting building.

GET POSTER

Hidden behind the poster is a steel safe, embedded in the wall.

OPEN SAFE

How?

TURN COMBINATION

I don’t understand the word COMBINATI.

TURN DIAL

I can’t make any sense out of that.

(Only the first nine letters are being used, hence COMBINATI.) I realized the way the safe operated was likely going to be by entering individual numbers on their own lines (like typing “42” just on its own). Because of this, I wondered: would it be possible to brute force the puzzle?

4

I don’t understand the word 4.

5

I don’t understand the word 5.

6

Mumble? 6?

7

“Click.”

With this method I was able to get that 7-22-34 causes the safe to open. This is not randomized. (I did find out how to find the combination properly, but only later; I’ll save it for the end of my post.)

The safe door smoothly swings open.

The safe includes a “rare book” which has a “HISTORY OF ADVENTURE (ABRIDGED)” which is long-ish and I have the entire thing as a text file here. This is the document in Adventure 501 that says the max score is 500; in this version, it adds:

Most recent additions include the great Castle of Aldor, the Elephants’ Burial Ground, Leprechaun Rock and more.

You’ll get to see the outside of the Castle in this post. In addition, I wanted to highlight:

Thanks are owed to Roger Matus and David Feldman, both of U. of C., for several suggestions, including the Rainbow Room, the telephone booth and the fearsome Wumpus.

This means the Wumpus puzzle I mentioned admiring in my last post was actually thought of by one of the people playing the game! Mainframe games were not produced in voids and often had multiple contributors; this includes Woods (of classic 350-point Adventure). In the interview with Woods made for Jason Scott’s documentary GET LAMP, he talks about this process, citing (for example) the passage that was too narrow to carry your lamp as something that was suggested by a player.

Back to the safe, it turns out to be useful to access because just like the thief in Zork (I assume he was the inspiration for this) you can have any objects you drop in the building noodled with. I don’t know if there’s a limit or a specific algorithm but the game is hard enough as it is without having to worry about items wandering from where you expect them. I blame the “tiny little green man” that kicks you while outside at the grassy knoll.

A tiny little man dressed all in green runs straight at you, shouts “Phuce!”, aims a kick squarely at your kneecap, misses, and disappears into the forest.

Speaking of “phuce”–

You’re at top of steps in back of Thunder Hole.
The only way past the wall is through a tiny locked door.

UNLOCK DOOR WITH KEY

The tiny door is now unlocked.

PHUCE

You feel dizzy…Everything around you is spinning, expanding, growing larger…. Dear me! Is the cave bigger or are you smaller?
You are on a wide ledge, bounded on one side by a rock wall, and on the other by a sheer cliff. The only way past is through a large wrought-iron door.
The door is open.

GO EAST

You are on the western shore of an underground sea. The way west is through a wrought-iron door.
A high wooden structure of vast proportions extends into the water.
The door is open.

PHUCE

You are again overcome by a sickening vertigo, but this time everything is shrinking… I mean, you are growing. This is terribly confusing!
You are at the western tip of the Blue Grotto. A large lake almost covers the cavern floor, except for where you are standing. Small holes high in the rock wall to the east admit a dim light. The reflection of the light from the water suffuses the cavern with a hazy bluish glow.
There is a small wooden boat here.
The only way past the wall is through a tiny open door.

This is back at the door where you start by growing with mushrooms, shrinking with cake, but then finding a small door to still deal with. No real logic: I was just trying all the magic words everywhere. This breaks into the grotto I dropped a picture of last time.

Manifested!

To move the boat around you need to be holding the wooden pole; I solved this puzzle “passively” by having the pole in my inventory by accident when I tried to move around in the boat. There is a hint — the wooden pole has the text “_ R O _ _ O” suggesting the word GROTTO.

ENTER BOAT

You are now sitting in a small boat.

GO EAST

You have poled your boat across the calm water.
You are on the eastern shore of the Blue Grotto. An ascending tunnel disappears into the darkness to the SE.
There is a jewel-encrusted trident here!

As I was remembering, this links together two distinct parts of the map, the outside section to the area with the “rainbow” room and the Lost River and the “too bright” corridor and the “tongue of rock” with the whiskbroom sitting there and the bat cave with the shovel. I’ve done my best to show a merging of the two sections:

In one case I simply missed an exit (near where the passage got too bright, you can go north to a ledge and find a wooden casket). The grotto connects with the shore with the trident, as already shown, plus you can go:

a.) South to a “gravel beach” where there is an “apiary” with bees; I was able to bring the flowers I found outside and distract them, revealing a treasure (a honeycomb).

You are in the Apiary. The walls are covered with colorful, intricate, flower-like patterns of crystallized gypsum.
There is an active beehive nearby. The bees hum protectively around the hive.

THROW FLOWERS

The bees swarm over the fresh flowers, leaving the hive unguarded and revealing a sweet honeycomb.

The flowers have a “!” mark but that apparently isn’t good enough to determine if something is a treasure. If you GET TREASURE and it picks the thing up then you know it counts for points.

b.) North to a “dark cove” where you can walk up a “basin” to eventually find a fountain of wine. You can climb up at the fountain to get to the place where you can find the cask. I haven’t experimented with this section and if you need to do some fancy shenanigans to safely get the cask to the wine yet.

c.) North from the trident to a “Bubble Chamber” that has a green stone. Hang out at the green stone long enough and you’ll start to feel unhealthy.

You are at a high rock on the NE side of a watery chamber at the mouth of a small brook. An unknown gas bubbles up through the water from the chamber floor. A bluish light can be seen to the southwest.
Nearby, a strange, greenish stone is glowing brightly.

I remember (from 501) this is because the stone is radioactive and needed to be stored in a special container. I’m not sure if I’ve seen the container yet.

d.) Past the radioactive stone is a “Fairy Grotto”…

You are in the Fairy Grotto. All around you innumerable stalactites, arranged in immense colonnades, form elegant arches. On every side you hear the dripping of water, like the footsteps of a thousand fairies. A small stream runs from the SW corner. A bright glow emanates from the south side of the grotto, and a steep passage descends to the east.

…and if you try to keep going, you end up down a corridor that’s too cold to walk through. I think I have seen the right item for this elsewhere but I haven’t tested it yet (you’ll see later).

Going south from the Fairy Grotto you get stopped because it is “too bright”; a similar message happens elsewhere, so this is clearly the same place being linked two ways.

That’s enough of that section. Let’s hop up to the swamp. It relates to the cloth bag that was part of the “Witt Construction Company”.

You are at the edge of an open area of wet sand. The dense foliage appears to grow thinner towards the northeast. A small sign stuck in the muck reads: “Site of Proposed Municipal Parking Lot — D.M. Witt, Contractor.”
Foul smelling gasses bubble up through the wet sand.

I decided to put construction together with the construction site to see what would happen.

As the grey powder mixes with the bubbling quicksand, the whole mixture gradually thickens to a rocklike hardness.

This opens a brand new section; going north no longer sinks you in quicksand.

First comes a ravine:

You’re in an open field on the south side of a deep ravine. South and west the land is an almost impassible swamp. To the west the ravine merges with the swamp; some distance to the east it ends abruptly at the foot of a sheer granite cliff. A dry drainage pipe six inches in diameter emerges from the base of the cliff just above the floor of the ravine.

You can go in the ravine but you can’t get out again with anything being held. This is unfortunate since the ravine has a statue (a treasure).

You are at the east end of a steep ravine, near where a drainage pipe emerges from a rock wall.
There is an ancient marble statue lying here!

Following the ravine further leads to death; I don’t know if exit is about climbing up or about surviving the “wet and treacherous” area to the west.

Ignoring the ravine, you can also go east to find a “cliff” with vines; climbing the vines reveals a rope, and for a while I thought that was that. (Incidentally note: no TIE or UNTIE on the verb list. I tried playing the flute and that didn’t cause the rope to levitate, so I don’t know how to get it to work. I assume THROW makes it happen somewhere?)

I admit my next piece of insight came from the map, but given you could buy it from CompuServe to accompany your gameplay I just consider it a “supplement”. Notice there seems to be a hole/entrance next to the vines. It isn’t there in the regular description!

You are at the foot of a towering cliff. The sheer rock face is partially obscured by thick vines growing up the cliff.

MOVE VINES

Parting the vines reveals a narrow crack in the face of the cliff.

This allows winding around the ravine, getting a “four-leaf clover” on the other side. You can also walk farther and find a lair.

You are in the lair of Ralph the Giant Centipede. The air reeks with the stench of rotting bits of flesh. Giant centipedes, in general, are not partial to visitors.
A golden fleece is lying nearby!
A giant centipede is eyeing you with a none-too-friendly look.

You can take the fleece and it is rather like taking the cloak from the Wumpus. (Incidentally, I suspect either the cloak or fleece or both protect from cold — I just haven’t had a chance to test it yet.) The centipede starts to chase:

The incensed insect is in full gear now. If you don’t move quickly, his monstrous mandibles may masticate you into murky mush!

JUMP

You are at the bottom of the ravine with a broken head.

I’ll have to play around with this later. The game is large enough that it takes a while to get items together to test a theory. Since I had the boat access I grabbed the whiskbroom and shovel and tried using them in various places, getting a hit with the broom at the “dusty room” above the Complex Junction. (This is one of the standard Crowther/Woods rooms, just it has been repurposed. Adventure 448 had a similar puzzle.)

You are in a large room full of dusty rocks. There is a big hole in the floor. There are cracks everywhere, and a passage leading east.

BRUSH

Brushing the dust from one of the larger rocks reveals some carved characters.
In the rock is carved the inscription:

In Memoriam:
John Dillinger, Liberator of the Little Man.
Died: 7-22-34.

…and that’s how you figure out the safe code if you aren’t brute forcing it. Either that, or you take a wild jump based on the Dillinger Society poster and try the death date. I wonder if anyone did that to solve the puzzle!

I’m not really “stuck”, but I have a lot of moving parts to coordinate now and I’m trying to get through without burning too much lamp power. I have five theories about the area past the chapel (“fnord”) but I need to juggle objects to get them in the right spot in order to test any of them.

17 days ago

Renga in Blue - Jan 03

Adventure 751: All Hope Abandon Ye Who Enter Here

(Continued from my previous post.) I’ve taken a fair chunk of the “501 content” down, although there’s a part that’s either different or I’m not remembering correctly. I’ve made a step into the 751-only-content but have only managed so far a step. To continue from last time, I had explored the outside and found the […] 18 days ago

(Continued from my previous post.)

I’ve taken a fair chunk of the “501 content” down, although there’s a part that’s either different or I’m not remembering correctly. I’ve made a step into the 751-only-content but have only managed so far a step.

From Personal Computing, November 1979. CompuServe was still using the MicroNET name in 1980, but eventually they were just known as CompuServe.

To continue from last time, I had explored the outside and found the usual lamp, food, keys, bottle, and keys, but also a yellow tablet, matchbox, leather sack (empty), cloth sack (with grey powder), large wooden box (empty), mushrooms, flowers, and a wooden pole. The treasures in the building go in a safe (which I don’t have the combination for) and I was stopped by a three-headed perfectly ordinary dog (which we’ll get by later), and a salt marsh/swamp area included one exit I neglected to mention last time guarded by mosquitos:

The air ahead is filled with huge mosquitos, with stingers the size of icepicks! The mosquitos haven’t yet caught your scent. Do you really want to proceed?

YES

Once the mosquitos catch your scent, it’s all over very quickly. Sheesh! You have more holes in you than a pincushion!

Arthur O’Dwyer pointed out in the comments EXAMINE works on some objects, although it doesn’t work on many of them and sometimes it works inconsistently. If you’ve opened the cloth bag at the grate, you at least see the grey powder without spilling it…

It contains:
grey powder

…but you miss out entirely on a helpful message if you don’t examine the bag while it is closed.

The label on the bag reads: “Mix with care. Property of Witt Construction Company”.

This bag is not in Adventure 501 and I have no idea how to mix it yet. Since it is a new item I presume it applies to one of the new puzzles.

At least some of the content is still identical; you can still unlock a grate to find yourself in a long west-east passage, where along the way you can pick up a cage and a rod. (The cage has a “soiled paper” this time around with a “useless” deed for a silver mine.) The bird is along the way who is spooked by the rod and you need to have dropped the rod in order to capture the bird.

The Donovan map includes the fact you can drop from the “all alike” maze which has the pirate treasure down to the bird room.

The bird then can be released to chase off the snake, making the rest of the cave wide open. This seems like a good moment to step back to the big picture.

Above is my current attempt at a “meta-map” where the “new for 501” rooms are marked in blue and the “new for 751” part is marked in green. (Please note directions are approximate, and general areas are compressed into single rooms.) For example, from the snake, there’s one small offshoot to the northeast where you can find a throne room with a crown.

You are in the private chamber of the Mountain King. Hewn into the solid rock of the east wall of the chamber is an intricately-wrought throne of elven design. There is an exit to the west.

GO EAST

You are on the east side of the throne room. On the arm of the throne has been hung a sign which reads “Gone for the day: visiting sick snake. –M.K.”
An ancient crown of elven kings lies here!

While wearing the crown in 501, there’s a sword in a stone you can pull out; you can find it by finding a “whirlpool” (it’s just past the rusty door, if you know Crowther/Woods) and diving in:

You are dragged down, down, into the depths of the whirlpool. Just as you can no longer hold your breath, you are shot out over a waterfall into the shallow end of a large reservoir. Gasping and sputtering, you crawl weakly towards the shore….
You are on a narrow promontory at the foot of a waterfall, which spurts from an overhead hole in the rock wall and splashes into a large reservoir, sending up clouds of mist and spray.
There is a narrow chimney on the east side of the promontory. Through the thick white mist looms a polished marble slab, to which is affixed an enormous rusty iron anvil. In golden letters are written the words: “Whoso Pulleth Out This Sword of This Stone and Anvil, is Rightwise King-Born of All This Mountain.”
A gleaming sword is stuck into the anvil!

Returning back to the Mountain King area:

Two of the treasures have been swapped; the “silver bars” to the north are now a “delicate lyre” and the “diamonds” found near the fissure (the same one you wave the rod to make a bridge) are now a “silver horn”. Both are used to solve puzzles I’ll show later. (I didn’t remember them straight off the bat from 501, but the fact they were treasures changed into tools gave me suspicion.) The magical bridge from Crowther/Woods is technically optional (you can reach the other side via walking a different way) but because of the addition of the Wumpus the bridge is now needed.

You are on the east bank of a fissure slicing clear across the hall.
The mist is quite thick here, and the fissure is too wide to jump.

WAVE ROD

A crystal bridge now spans the fissure.

GO WEST

You are on the west side of the fissure in the Hall of Mists.
There is a silver horn here!
A crystal bridge now spans the fissure.

The Wumpus was my favorite puzzle from 501 and I didn’t even put the solution when I wrote about the game last time.

You’re in the Cloakroom.
A lovely velvet cloak lies partially buried under a pile of loose rocks.
In the corner, a Wumpus is sleeping peacefully.

Specifically, the Wumpus doesn’t wake up until you nab the cloak, at which point it starts chasing you. You can reach a fair number of places on the map in time, but the one you want to aim for is the crystal bridge.

Normal map, not meta-map. Trying to enter the Wumpus area will sometimes randomly drop you in a dead end.

While waving the rod makes the bridge appear, waving the rod again will make the bridge disappear. A formerly “optional” puzzle is repurposed here to now be meaningful.

You’re at west end of Hall of Mists.
The Wumpus is still on your trail! And he’s getting closer!!

GO EAST

You are on the west side of the fissure in the Hall of Mists.
The Wumpus is only a few steps behind you! All this exercise is making him veerrrrry hungry!
There is a silver horn here!
A crystal bridge now spans the fissure.

GO EAST

You’re on east bank of fissure.
The Wumpus is only a few steps behind you! All this exercise is making him veerrrrry hungry!
A crystal bridge now spans the fissure.

WAVE ROD

The crystal bridge has vanished!

As the bridge disappears, the Wumpus scrambles frantically to reach your side of the fissure. He misses by inches, and with a horrible shriek plunges to his death in the depths of the fissure!

(If you aren’t familiar with the Wumpus, I give the history in my Before Adventure series. This is the most notable appearance of the Wumpus in a proper adventure game from this era.)

Some parts are near-identical but still with a change; for example, the long sequence with the troll-chasm-bear normally has the bear appeased with the food in Adventure 350, but this was changed for Adventure 501. This is one puzzle where I forgot what the solution is (I have a suspicion but I haven’t been able to test it yet).

Near the troll bridge entrance is a completely different branch which leads to new rooms starting with “Dante’s Rest”.

You’re at Dante’s Rest, on the north side of a yawning dark chasm. A passage continues west along the chasm’s edge. A decrepit natural bridge spans the chasm. A message scrawled into the rock wall reads: “Bridge out of repair. Maximum load: 35 Foonts.”

GO SOUTH

The bridge shakes as you cross. Large hunks of clay and rock near the edge break off and hurtle far down into the chasm. Several of the cracks on the bridge surface widen perceptibly.
You’re at the Devil’s Chair, a large crystallization shaped like a seat, at the edge of a black abyss. You can’t see the bottom.
An upward path leads away from the abyss.
A decrepit natural bridge spans the chasm. A message scrawled into the rock wall reads: “Bridge out of repair. Maximum load: 35 Foonts.”

I have not tested if there’s a number-of-passes through limit; there certainly is a weight limit. There’s a magic item that allows teleportation so I haven’t needed to pass through more than once.

Just up from the “Devil’s Chair” is a “Rotunda” with a telephone booth; the telephone is ringing. Try to go into the booth and a gnome will jump in before you. (I mentioned this puzzle in my writeup on 501, but I neglected to explain how it gets resolved and I don’t remember. D’oh. I used to do much more skipping around in ye olden days of the blog.) To the east of the rotunda is a brand new room (I think, at least it didn’t make my 501 map) with a Conservatory and a flute.

You’re in the Rotunda. Corridors radiate in all directions. There is a telephone booth standing against the north wall. The telephone booth is empty. The phone is ringing.
Nearby is a small plastic card.

GO EAST

You are in the Conservatory, whence the gnomes often repair to relax with a little music. On one side of the room is an old upright piano.
A delicate silver flute is lying nearby.

The card is a “MERKIN EXPRESS CARD” and does not count as a treasure and is new for 751 along with the flute. I don’t know what either is for yet. Just to compare, here’s the scene from 501:

You’re in Rotunda.

The telephone booth is empty. The phone is ringing.

ENTER BOOTH

You are standing in a telephone booth at the side of a large chamber. Hung on the wall is a banged-up pay telephone of ancient design.

The phone is ringing.

ANSWER PHONE

No one replies. The line goes dead with a faint “Click”.

I don’t know if the change in events suggests a change in how the phone operates (and if there’s a puzzle now that wasn’t here before).

The path leads farther past a “star sapphire” (just a treasure) and into an area I’ll call the Lost River section.

You land from the passage at a “Tongue of Rock” (the whiskbroom was in 501, but again I don’t remember what it was for)…

You are in a level E/W passage partially blocked by an overhanging tongue of rock. A steep scramble would take you up over the tongue, whence continues an upward crawl. There is a small hole in the north wall of the passage.
There is a small whiskbroom here.

….and to the west of here you can pass by a Bat Cave with a shovel, finally ending at a Blue Grotto with a trident; rather, the trident, the one that normally is placed elsewhere and is used to open a clam.

You are on the eastern shore of the Blue Grotto. An ascending tunnel disappears into the darkness to the SE.
There is a jewel-encrusted trident here!

From the Tongue of Rock you can proceed down to a colorfully described Green Lake Room…

You are in a low, wide room below another chamber. A small green pond fills the center of the room. The lake is apparently spring-fed. There is a narrow passage to the north.
A larger passage continues west.

…followed by a Rainbow Room; going any farther west results in it being too bright to make further progress.

You are in a very tall chamber whose walls are comprised of many different rock strata. Layers of red and yellow sandstone intertwine with bright bands of calcareous limestone in a rainbow-like profusion of color. The rainbow effect is so real, you are almost tempted to look for a pot of gold! Poised far over your head, a gigantic slab, wedged tightly between the north and south walls, forms a natural bridge across the roof of the chamber.

GO WEST

You are following a yellow sandstone path. There is a glow to the west.

GO WEST

You go a short way down the bright passage, but the light grows to blinding intensity. You can’t continue.

You can take one more passage north to the side of a river…

You are standing on a large flat rock table at the western end of Lost River Canyon. Beneath your feet, the river disappears amidst foam and spray into a large sinkhole. A gentle path leads east along the river’s south shore. Another leads sharply upward along the river’s north side.

…but let’s leave this area entirely, and jump back upstairs to show off getting by the dog.

You are in a dimly lit passage behind Thunder Hole. Etched into the rock wall are the ominous words:

You are approaching the River Styx.
Lasciate Ogni Speranza Voi Ch’Entrate.

A hideous black dog bares his teeth and growls at your approach.

PLAY LYRE

The air fills with beautiful music. The dog gradually becomes less fierce, and after a short while he lies down by the side of the cavern and falls into a deep sleep.

GO EAST

You are at the River Styx, a narrow little stream cutting directly across the passageway. The edge of the stream is littered with sticks and other debris washed in by a recent rainfall. On the far side of the river, the passage continues east.

I flailed a bit (“GO EAST: How do you propose to cross the river?”) before I realized I could just jump.

JUMP OVER RIVER

You’re on the east side of the river’s sticks.

GO EAST

You are at the top of some arched steps. On one side is a blank wall with a tiny door at the base and a shelf overhead. On the other side a westward passage leads to the sea.
The only way past the wall is through a tiny locked door.

Snrk. From here, thinking of an Alice in Wonderland reference with the tiny door, I tried EAT MUSHROOMS. (Previously, the mushrooms did nothing, but if they were going to work anywhere, here seemed like the place.)

You are growing taller, expanding like a telescope! Just before your head strikes the top of the chamber, the mysterious process stops as suddenly as it began.
You are in a low cramped chamber at the back of a small cave.
There is a shelf in the rock wall at about the height of your shoulder.
There is a tiny brass key on the shelf.
There are some tiny cakes on the shelf.

The tiny key unlocks the door, and the tiny cakes cause you to return to normal size, but the issue is the door remains tiny! So I’m not sure if I’m supposed to be adding another step to my sequence somehow so I can be not just super-grown and normal but also shrunk. (I’m pretty sure this puzzle is in 501 as-is, and I’m annoyed at my past self that I didn’t just explain the solution.)

That’s one instrument used! Let’s take care of the horn next. We’re going back to a scene that’s pretty familiar in Crowther/Woods, where you find a clam and then open it with the trident.

Rather than bothering with the clam at all, though, we’re going up:

You’re in a large room carved out of sedimentary rock. The floor and walls are littered with bits of shells imbedded in the stone. A shallow passage proceeds downward, and a somewhat steeper one leads up. A low hands and knees passage enters from the south.
There is an enormous clam here with its shell tightly closed.

GO UP

You are in an arched hall. A coral passage once continued up and east from here, but is now blocked by debris. The air smells of sea water. Your footsteps echo hollowly throughout the chamber.

BLOW HORN

As the blast of the horn reverberates through the chamber, the seemingly solid rock wall crumbles away, revealing another room just beyond. The wall was most likely worn thin by an ancient watercourse which dried up just before completely wearing away the rock.
You are in an arched hall. The remnants of a now-plugged coral passage lie to the east. The north wall has partially crumbled, exposing a large connecting hole to another room.

This is all still in 501 territory; it leads to a path down to a chapel which is a dead end.

There’s some “ruby slippers” near the church that can be worn and utilized to teleport between the rainbow room and the bridge above it (which adjoins the chapel).

You are standing on a natural bridge far above the floor of a circular chamber whose walls are a rainbow of multi-colored rock. The bridge was formed eons ago by a huge slab which fell from the ceiling and is now jammed between the north and south walls of the chamber. There is a pair of ruby slippers here.

GET SLIPPERS

Taken.

WEAR SLIPPERS

Ok

CLICK HEELS

You are in a very tall chamber whose walls are comprised of many different rock strata. Layers of red and yellow sandstone intertwine with bright bands of calcareous limestone in a rainbow-like profusion of color. The rainbow effect is so real, you are almost tempted to look for a pot of gold! Poised far over your head, a gigantic slab, wedged tightly between the north and south walls, forms a natural bridge across the roof of the chamber.

The new thing is that there are some “brambles” to the east blocking the area.

You can take a candle from the chapel and the matchbox from the start of the game (not present in 501) in order to make a fire.

You’re at the east portal of the Gothic Cathedral.

A sudden draft has extinguished your match.
A NE passage is blocked by an impenetrable thicket of sharp thorny brambles.
Deep within the brambles is growing a perfect, blood-red rose!

BURN THICKET WITH CANDLE

The dry brambles immediately catch fire and disappear in a roar of flame.

Finally this gets to the main new area of the game! The thing I’ve been waiting years to reach… except….

You are in a dull N/S passage beside a tall black rock. On the rock is chisled the outline of a four-leafed clover, under which is the inscription: “Notice: This rock fabricated from ersatz materials.”
Smoke rings curl upward from the rock.

GO NORTH

As you approach the rock, an indistinct muttering sound arises from the general area of the rock. The only word you can hear clearly is “Fnord!”
You’re on grassy knoll.

Agh! Trying to say FNORD here just gets a “snickering sound”. I don’t know if this is just a matter of repetition or finding a new magic word or blindly throwing the axe and hitting whatever is hiding behind the rock or what, exactly. It seemed like a good place to pause, though.

Just to be clear, my main obstacles going forward are:

a.) the tiny door, where I can grow to grab a key and shrink again to normal but I don’t have a way of shrinking to tiny-door size

b.) the mosquitoes at the swamp

c.) the “fnord” rock

d.) being able to rescue that “perfect, blood-red rose” before lighting the brambles (this may help resolve problem c)

There’s always the possibility of something hidden, though. I’m pretty much giving myself free use of the map and it does seem like almost everything left that’s from 751 is past that rock.

I know all this is past the tiny door and I visited it in 501, I just need to make it here.

18 days ago