Headline:Implementing the Classics: Colossal Cave Adventure
Date:Friday, December 20, 2019
Posted By:Plaid Hatter Games

With the holidays coming up, I'll be taking a few weeks off. My work on Clay-Pidgin: A TCP based message queuing for Tcl/Tk, while interesting, has been overtaken by events at work. Long story short: we found a way to solve the problems that I thought Clay Pidgin was required to address, without Clay Pidgin. While on one hand I'm slightly disappointed, on the other this actually frees me up somewhat to take Pidgin technology in any direction that better fits my personal projects.

The content for Iliad-07 is slowly coming together on index cards. But before I really start to commit to converting those concepts into computer code, I need to have a better sense of what that computer code is going to look like. I'm stuck in a Catch-22 where to write the content, I need an engine. And to write the engine, I need to know the content.

Iliad-07 is going to be a terribly complicated game. So trying to tackle both the engine and the content at once is... well... just look at how many playable demos I have so far. So my thinking is start simpler. In fact, take a classic game where everyone knows how it's supposed to be played, and then implement that in the style (and rough technology) of what I want to implement Iliad-07 in.

The game I have chosen is one of the classics of the text-adventure world Colossal Cave Adventure. Fortunately for me, the game's engine itself was quite simple. The game also had an external database.

...Several Hours of Research Later...

Ok, this was not nearly as simple as I thought it was going to be. Colossal Cave, while it has an optimal strategy, has random elements. This makes a regression test impossible to write. Also, while the external database is an arms-length abstraction of the game, the engine does the lion's share of the work. And the engines are almost as long as the database.

This exercise has proven that for most games there is a dichotomy between the engine and the content, with the content being tailored for the engine and the engine being tailored for the content. Emulating a primitive engine developed originally for Fortran running on machines that had less ram than the text editor I'm using to compose this is probably consuming would be a great academic exercise. And indeed people do it in everything from C to Python. But it's not simple, and it's not going to be a logical stepping stone to kick off my project.

It hasn't been a complete waste of time. One thing that has occurred to me is that with Cuneiform, I can express behavior directly in my content.

uuid: 13038a20-5466-46a5-ad5b-8c46115cf149
Title: {Room with a view}
Connections: {
  port {to  5b6d1021-f8ee-48eb-9556-f1135f926842 locked 1}
  stbd {to 1d8745e2-3944-4610-8c77-5707b4fb085f}
  fore {to 4553d949-8237-4a6c-9cbb-a7eace596dfe}
  aft  {to 670d4466-9846-4b02-b87b-8c4e4d5a8d59 hidden 1}
}
---BEGIN CONTENT---
# Intercept player interactions
if {[player action] eq "open shutters"} {
  # Logic Test to see if players have solved a puzzle
  if {[player has widget xyz]} {
    # Content on success
    para {You use the xyz to open the shutters}
    my state shutters open
    para {Opening the shutters bathes the room in a blinding light.}
  } else {
    # Hints to unluck the puzze
    para {You need some sort of key to open the shutters.}
  }
}
# Room state check
if {[my state shutters] eq "open"} {
  # Content in one state
  para {You are in brightly lit room. If you had ever been on Earth, you would say that
it was bright as daylight. Having been born and bred on this starship however, you know
this bright as agriculture areas.}
} else {
  # Content in the other state
  para {You are in a room with massive plate windows that seem to be opened into the back
of giant steel shutters. You can see a slot where you can use an xyz to open the shutters.}
}
# Macro to generate navigation links
my connections