Skip to content

A hypertext interactive fiction (IF) engine with a focus panel and a scrollback. (Incomplete.)


Notifications You must be signed in to change notification settings


Folders and files

Last commit message
Last commit date

Latest commit



55 Commits

Repository files navigation


This is yet another IF engine. It’s based on the idea that the player is watching the current descriptions of things, and they can also scroll up to see the series of events that have happened recently. The player may watch more than one thing at a time, but only two panels appear on the screen at a time: One describes the immediate surroundings of the viewpoint character, and one describes the currently selected thing.

I’m likely to abandon this project before it gets very far, but the design is taking shape surprisingly well, so I’m starting this repo to host the design notes.

Background and motivation

Interactive fiction (IF) is a medium under constant reinvention, but as the name suggests, it tends to revolve around prose stories (fiction) that have interactivity. Two of the most popular interactive fiction systems have quite different approaches:

Inform (one of many similar parser-based IF systems) gives the player a prompt where they can type simple commands like "PUT BOOK ON TABLE. READ BOOK." To support this kind of interaction, there’s an underlying world model that remembers the location and state of each item in the world. An author who goes with the grain of the medium will tend to take advantage of this to set player goals related to item acquisition, exploration, and application of items outside their original context. Multiplayer systems (MUDs, MOOs, etc.) based on the same interaction style exist.

Twine uses a minimalistic hypertext interface. (Again, Twine isn’t the only system of its kind.) The default structure of a Twine work is a collection of pages with links to each other, like a website or wiki. An author who goes with the grain of the medium will…​ Well, it’s hard to say anything for sure, but they’re likely to focus on just the state they need to keep for the story outline they have in mind. Player choices in hypertext fiction can be particularly fantastical thanks to the fact that the player doesn’t need to guess them. The lack of extraneous interaction choices makes it so that if the player is railroaded, they can move along and not waste their energy looking for alternatives.

One project sitting between these alternatives is Seltani. Like MUDs, Seltani is an online multiplayer environment that lets players walk around between rooms. Like wikis, Seltani’s content is largely user-supplied hypertext.

I’ve tinkered around in Seltani a bit, and I find it pretty inspiring. However, most of the story ideas I can come up with require more detailed world models and more detailed interfaces. I’ve found it difficult to use Seltani’s scripting code fields to architect a framework to support new world model concepts, and even before my additions, Seltani’s player-facing interface is already cluttered enough to elicit usability complaints. So what I might want is to improve the generality of Seltani to encompass my use cases, while subtracting assumptions I don’t need.

Since then, for unrelated reasons, I’ve mused on category theory a while. Roughly, category theory focuses on things that can be lined up end-to-end to make bigger things of the same kind. This is often used to study programming languages. If a programming language could discard most of its unnecessary complexity to focus on only a few useful categories, I think we’d care about these:

  • Space: The methods by which coexisting people and things interact with each other.

  • Time: The narratives connecting past to future.

Wouldn’t you know it, interactivity and storytelling. So although this project is just another IF engine with a modest scope, it’s intertwined with my broader thoughts on programming languages and my political perspective on what "we’d care about." I look forward to taking concepts from those places to inspire this project and vice versa.

Design: User interface

The interface is divided into two scrollable panels: The ambient panel and the focus panel. Each panel has a past, present, and future section. The past is a scrollback of events. The present contains a reactively updating description. The future contains significant actions that can be taken. The present and future update as the panel is scrolled so as to show what they were like back in a previous moment.

The ambient panel represents the current ambient surroundings of the player’s viewpoint system (e.g. a player character, a god game cursor, etc.). It may remember certain toggle settings related to what the player currently wants to pay attention to and what tools the player is currently brandishing. For instance, the player may stop paying attention to the landscaping, they may start paying closer attention to the behavior of a particular machine, and they may start holding a hammer and looking for nails.

The focus panel represents something specific the player is currently focusing on, like an object their player character sees now or an object they remember from the past. The focus panel saves a list of tabs, much like browser tabs. The present and future of this panel display only the description and choices for the currently selected tab. The past displays the history of all the tabs at once, but it emphasizes the history of the currently selected tab.

Interactive UI elements in the past and present, such as hyperlinks, practically never have an effect besides opening tabs, focusing tabs, gaining access to toggles, and configuring toggles. Any interactive UI element that can do more belongs in the future.

Design: Deeper topics

Some more design thoughts are on a dedicated page.


There’s barely anything implemented in this repo at this point, only a little Hello World tinkering in Idris, but here’s how to run it.

First, you’ll need to install some dependencies. I’ll list the versions I’m using, but you don’t necessarily need to hunt those down.

Installing Idris can be a somewhat frustrating process, particularly on Windows. After I failed to get it to work under Cygwin on Windows, I resorted to a Linux Mint VirtualBox VM, and that’s how I’m developing this project right now. I set up my VM with access to 1.5GB of RAM (more than I would usually give it) so it wouldn’t page to disk so much during Idris’s lengthy build process.

Okay, once you’re set up with those dependencies, you can build and run the project. Build it like so:

$ make

This will create a few files which you can run by opening fin/local-web/contrivertext.html in a browser.

Here’s a more detailed view of the build options available:

$ make

Run the browser version on Node.js:
$ nodejs fin/local-web/contrivertext.js

Build and run the browser version on Node.js
(assumes nodejs is on your path):
$ make run

Build and run the unit tests (assumes nodejs is on your path):
$ make check

Build documentation of ContriverText's internals to fin/doc/html/:
$ make html

In case Node.js is too slow, here’s a set of targets for building native code instead:

Build the native executable:
$ make nonjs

Run the native executable:
$ fin/contrivertext

Build and run the native executable:
$ make run-nonjs

Build and run the native unit tests:
$ make check-nonjs


A hypertext interactive fiction (IF) engine with a focus panel and a scrollback. (Incomplete.)