What is Interactive Storytelling?

Interactive storytelling is a form of entertainment that uses the computer as a medium to allow players to create and influence a nascent storyline through small, relevant, dramatic actions.

The primary focus of a storyworld should be on character interactions and social reasoning.

Teen Talk

Instead of the four tropes that dominate a majority of today’s games—spatial navigation, resource management, hand/eye coordination, and puzzle solutions.

The Four Tropes—Doom, SimCity, LodeRunner, Tetris (clockwise from upper left)

While social reasoning takes precedence in a storyworld, an entertaining storyworld will probably include some of the other four tropes, though they would not take precedence.

Chris Crawford’s Excalibur (1983)

Chris Crawford’s Balance of Power (1985)

Note: Cross-posted to Medium here.

Posted in Side Projects | Tagged , , | 1 Comment

Who is Chris Crawford?

I’ve realized that many people who’ve read StoryCalc: A New Hope might not know who Chris Crawford is or what he’s accomplished.

Chris is a game designer and if it were not for his passion, hard work, and insights over the past thirty nine years I would not be here today attempting StoryCalc.

Building off his early interest in board wargaming, Chris released his first game, Tanktics, through Avalon Hill. Moving to Atari, he programmed Eastern Front (1941), Excalibur, and Gossip for their Atari 400/800 computers.

After the video game crash of 1983 he left Atari and became an independent game developer before there was such a thing. Programming for Apple’s Macintosh platform because of its consistent and powerful user interface he released Balance of Power in 1985. In 1987 he released his seminal work, Trust & Betrayal: The Legacy of Siboot, the first glimpse of what he would later call interactive storytelling.

But Chris wanted more.

I dreamed of the day when computer games would be a viable medium of artistic expression an art form. I dreamed of computer games expressing the full breadth of human experience and emotion. I dreamed of computer games that were tragedies, games about duty and honor, self-sacrifice and patriotism. I dreamed of satirical games and political games; games about the passionate love between a boy and girl, and the serene and mature love of a husband and wife of decades; games about a boy becoming a man, and a man realizing that he is no longer young. I dreamed of games about a man facing truth on a dusty main street at high noon, and a boy and his dog, and a prostitute with a heart of gold.

This dream lead him to take the road less traveled.

Chris continued to release games like Patton Vs. Rommel, The Global Dilemma: Guns or Butter, Balance of the Planet, and Patton Strikes Back for the Macintosh but he also self-published The Journal of Computer Game Design and kickstarted what would became the Game Developers Conference by inviting twenty-six computer game developers to his living room to discuss their craft.

In a nutshell, Chris took upon himself the sisyphean task to try and drag the entire game industry into an artistic future that he imagined was just out of reach. But the industry wouldn’t listen so in 1992 he left, delivering one of the most passionate and inspirational call to arms that is known simply as The Dragon Speech (you should watch it). After that he “lit out for the territories,” leaving steadiness and security behind to search for the holy grail of interactive storytelling.

The trail becomes a bit harder to follow then. There was his annual interactive storytelling Phrontisterion conferences hosted at his home in Oregon where enthusiasts would gather and discuss how to advance the state of the art. He wrote books and lectured to audiences around the world about his theories of interactive storytelling. He worked on his next game, Le Morte D’Arthur which morphed into various versions of the Erasmatron, his interactive storytelling engine. Work on the Erasmatron morphed into Storytronics/Storytron, an attempt at commercialization. Sadly, this attempt failed in 2010.

Since then, in true startup fashion, Chris has remained focused on his dream, pivoting with projects like Gossip 2.0, Siboot 2.0, and Le Morte D’Arthur 2.0 to show the world what he sees so clearly.

Patrick Dugan in Understanding Crawford, says this:

It was clear, during Crawford’s period as a game developer, that he was an auteur operating at the top of his form, not always creating commercially successful products, but always pressing at the edges of the possible, always advancing the state of the art. He was an inspiration.

I agree 100% with Patrick’s assessment.

Chris and his work inspired me to spend two years working part time with his Storytron technology, to spend months porting Gossip 2.0 to iOS, to spend hours curating the Phrontisterion Online website, and to briefly join the team working on Siboot 2.0.

Chris is an auteur in the truest sense of the word, interactive storytellings version of D.W. Griffith, the American writer, director, and producer who pioneered modern filmmaking techniques. While other directors in Griffith’s day were content to churn out 10-15 minute shorts for nickelodeons, Griffith worked to refine this nascent technology, creating a new language of film that culminated in 1915 in the twelve reel, three hour epic, The Birth of a Nation.

“Nanos gigantum humeris insidentes”—I am a dwarf standing on the shoulders of a giant.

Note: Cross-posted to Medium here.

Posted in Side Projects | Tagged , , | 2 Comments

StoryCalc: A New Hope

For the past twenty-six years Chris Crawford has been fighting the good fight, trying to jumpstart an interactive storytelling revolution. He says he’s failed and that his age, his perfectionist nature, and the complexity of the problem were the perfect storm that defeated him. He retires from the field, promising to put his software in public domain and work on other projects, but interactive storytelling will no longer be his primary focus.

StoryCalc is an experiment to see if it is possible to develop an open source, workable, extensible platform for interactive storytelling based on the principles Chris has outlined using his blog posts, books, and videos (here, here, and here) as primary sources. StoryCalc is not affiliated in any way with Storytron or Chris Crawford.

This experiment will be evolutionary, not revolutionary. I make no grandiose, earth-shaking promises. I am not asking for anyone’s help right now though I welcome feedback and discussion on the StoryCalc Slack group (click here to email me for an invite).

Note: Cross-posted to Medium here.

Posted in Other, Side Projects | Tagged , , | 3 Comments

A Thanksgiving Prayer

Posted in Other | Tagged | Leave a comment

Siboot in 2017?

I’m thinking of finishing the version of Siboot that I was creating with Chris Crawford’s Storytron technology back in 2009-2010. Part of me thinks it’s a crazy idea and part of me thinks it’s a totally cool thing to do.

I’ve always been interested in Crawford’s work and his iconoclastic approach to game design and development. I’ve owned and played all of his Mac games and read all of his books. The verb-centric, process-intensive, parser-based approach to interactive storytelling that he’s championed has always appealed to me and seemed like a viable approach that no one else was considering. I admired his bravery and willingness to tilt at windmills.

After Crawford abandoned Storytron in 2011 I wanted to keep working on my storyworld but without a server to handle the backend dramatic calculations it was not possible to continue. I mothballed my development efforts and, though disappointed, kept an eye on Crawford’s website to see where he would go next. I figured that I wouldn’t be able to continue pursuing my interest in this approach to interactive storytelling until Crawford released a set of tools that he deemed acceptable. The only alternatives were to write my own code from scratch or repurpose a tool like Inform to the task, something I briefly considered.

In 2013 I ported some Java code Crawford wrote to iOS and released it as Teen Talk, a simple experiment in high school gossip. In 2014 I joined the Siboot 2.0 team to help out in any way I could even though there weren’t any programming or storyworld design tasks to do. I did write the first draft of the Encounter Creation Guide with Chris Conley but eventually I decided to leave the team because I came to the conclusion that even though I wanted to work with Crawford’s ideas, I really didn’t want to work with him directly.

Perhaps my frustration at watching Crawford flounder around over the next two years to try and deliver his updated version of Siboot put the idea in my head to complete my 2010 storyworld.

If I do try and finish my version of Siboot there’s no guarantee that I’ll succeed. I’ll be using six year old software that’s buggy and has no support. Even if I could decipher the source code to fix bugs, none of the versions I’ve got will load or run my 2010 storyworld. It’s been years since I wrapped my head around Storytronics and I’ve got several other side projects that I need to complete before I could focus on my Siboot 100%.

It’s not all doom and gloom, there is an upside. I have a verb web that I think is every bit as good as the one Crawford’s come up with. I’m not conflicted with this having to be my magnum opus, I just want to learn what I can and apply it to future efforts. I think I’m one of two people aside from Crawford who dug deep enough into the technology to not only realize how complicated it is but also managed to figure out how to get things done. There’s excellent documentation available on the Storytron wiki (which I wrote). And I know back in 2011 I would have been able to deliver something if Crawford hadn’t thrown in the towel.

Windmills, hmm…


Posted in Other, Side Projects | Tagged , | Leave a comment

140 Words Per Day

I’ve always wanted to write more whether it was in my journal, on this blog, or expanding on some of the story ideas I’ve had over the years. I probably have fifteen to twenty books on fiction writing and grammar. Many years ago I was into writing screenplays and I’ve probably started one short story or two that never went anywhere. Last year I even started a 50,000 word novel during National Novel Writing Month but after a couple of days got bogged down in my own stressful inadequacies as a fiction writer and quit.

At heart I don’t think I’m a fiction writer. While the idea appeals to me I don’t seem to have any burning desire to sit my ass in a chair day after day  and put fiction words on a page. I get really stressed out and fight the constant “is it good enough feeling.” I don’t seem to have the same difficulty when writing non-fiction or computer code.

A couple of days ago, just to see what the answer was, I figured out how many words a person would end up with if they wrote 140 words a day for 365 days. The answer surprised me–51,100 words.

So I’ve decided to see if I can write 140 words a day. It can be in my journal, it can be in a blog post, it can be part of a short story, it can be a design document for a game. There are only a couple of rules:

  • They have to be my words. Quotes or pictures (which equal 1000 words) don’t count towards the 140 quota.
  • I can write more than 140 words a day but they don’t “add up,” i.e. I can’t write 980 words one day and be good for the week. I’ve got to write 140 words every day.

Off to a good start, 304 words.

Posted in Other | Tagged | 1 Comment

Gossip Among Sapiens

I started reading Yuval Noah Harari’s Sapiens a couple of days ago and came across this on page 22:

Our language evolved as a way of gossiping. According to this theory Homo Sapiens is primarily a social animal. Social cooperation is our key for survival and reproduction…It’s much more important for them to know who is sleeping with whom, who is honest, and who is a cheat.

The amount of information that one must obtain and store in order to track the ever-changing relationships of even a few dozen individuals is staggering. In a band of fifty individuals, there are 1,225 one-on-one relationships, and countless more complex social combinations.

This made me racall what I read in the Verbs and Events chapter of Chris Crawford on Interactive Storytelling:

Any adequate interactive storytelling system must provide for the transmission of information among characters. I refer to such information transmission systems as gossip systems. This stretches the conventional definition of gossip to include all information related by one character to another, not just the “dirt.”

It was the mention of gossip in both books that caught my eye. Since Crawford thinks ontology recapitulates phylogeny when it comes to interactive storytelling I thought Harari’s statement about Homo Sapien’s earliest application of their augmented language skills a nice supporting argument for how this new medium might evolve.

Posted in Other | Tagged | Leave a comment

Elm – Mapping Anonymous Functions

In my prior post I wrote about creating a recursive function in Elm to iterate through a list of records and update a single record that met the search criteria.

I’ll admit that I was quite pleased with my solution not only because I had wanted to figure it out before looking at the instructor’s answer, but my implementation seemed particularly Elm-like.

So when I looked at the instructor’s solution, wondering how he would implement, I was pleasantly shocked (and a bit humbled) to see an entirely different way to implement iterate through a list an modify a particular record that didn’t use recursion.

Before I show you the instructor’s code I’ll need to talk about two things–how to create anonymous functions in Elm and Elm’s map function.

An anonymous function is a function that isn’t assigned to a particular identifier. They’re usually defined in-line. They’re parenthesized and the content is prefixed with a backslash. Anonymous functions are often used as arguments passed to higher-order functions or as part of a result of a higher-order function that needs to return a function.

The syntax for an anonymous function is:

(\param1 param2 ... -> -- Body)

(\x y -> x * y)
-- 6 : number

List.map (\n -> sayHello n) ["Alice", "Bob"]
-- ["Hello Alice", "Hello Bob"] : List String

By themselves anonymous functions are not much. But when you combine them with other functions they become much more powerful.

The map function can be used to apply a function to every element of a list or an array.

map : (a -> b) -> List a -> List b

map sqrt [1, 4, 9] == [1, 2, 3]
map not [True, False, True] == [False, True, False]

So map appears to have list and array iteration built-in. But there’s no standard Elm function that can examine the elements of a record, compare one element to the criteria, and modify another element based on the results of that evaluation. But with anonymous functions we can create a function to do that.

From the last example you see that it’s possible to create an anonymous function that map can use to modify a list of items. So let’s look at the instructor’s solution.

First, here’s the type alias of the model he’s passing in to his edit function. The model contains a list of players, the playerId of the player whose name we want to change, and the new name.

type alias Model =
    { players : List Player
    , name : String
    , playerId : Maybe Int

type alias Player =
    { id : Int
    , name : String
    , points : Int

Here’s his edit function.

edit : Model -> Int -> Model
edit model id =
        newPlayers =
                (\player ->;
                    if player.id == id then
                        { player | name = model.name }
        { model 
            | players = newPlayers
            , name = ""
            , playerId = Nothing

The edit function takes a Model and an Int as parameters and returns a new Model (I like this much better than my way of passing in a Player record and a List of Player. It seems much cleaner since the Model contains everything you need).

The let/in construct allows you to create local variables in the let section which you can use in expressions in the in section.

A newPlayers list is created in the let section using map with an anonymous function. Each player record is passed into the anonymous function as a parameter. If the player.id matches edit’s id parameter then the player’s name is changed to the new name stored in model.name. If not, the unchanged player record is returned by the anonymous function.

A new model is created in the in section with the following changes and returned.

  • The old players list is replaced with newPlayers
  • name is set to an empty string
  • playerId is set to Nothing

I have to admit that I was both pleased and humbled to see this solution.

I’m pleased because it seemed so much more elegant and Elm-like than my recursive function (which I thought and still think is pretty cool). Also, the way map and anonymous functions are applied here could be used if my model contained other instances of player name in other lists that needed to be updated at the same time.

I’m humbled because looking at the instructor’s solution made me realize how much I don’t know about Elm and functional programming. When learning a new programming language, especially something as radical as Elm, I think I tend to approach it with the constructs and mindset of the old languages I know. It takes a while for me to “unlearn” what I know in order to embrace the new paradigm correctly (I hope).

I’m comforted by the fact that I’m just at the start of the journey, excited about what I’ll see along the way and wondering where I’ll end up. I’m looking forward to finding out what I don’t know.

Posted in Software Development | Tagged , , | Leave a comment

Elm – Recursive Functions

In one of the Elm For Beginners exercises I have to update a player record’s name field with the modified player name and all I have is the playerId to search on.

Here are the Elm type alias for the Model and the Player

type alias Model =
    { players : List Player
    , name : String
    , playerId : Maybe Int

type alias Player =
    { id : Int
    , name : String
    , points : Int

If I were writing this in C# I’d probably have the Player objects stored in a generic List. To modify PlayerId’s name I’d probably use a foreach statement to iterate through the list. When I found the Player object who’s id matched PlayerId, I’d change the player’s name.

public int PlayerId;
public string Name;
public List<Player> Players;

public class Player
    public int Id { get; set; }
    public string Name { get; set; }
    public int Points { get; set; }

// 1. Code to create Players list and populate with Players
// 2. Code to set Name to player's new name
// 3. Code to set PlayerId of player whose name you want to update

foreach (Player p in Players)
    if p.Id = PlayerId {
        p.Name = Name;

But Elm doesn’t have control structures like for, foreach, while, or do-while. So how do I iterate over the record elements in the list below and modify the one player record that meets the criteria?

[ { id = 2, name = "Robin Maya", points = 0 }
  , id = 1, name = "Katie Maya", points = 0 }
  , id = 0, name = "Bill Maya", points = 0 } ] 

From working with Clojure and reading Functional Programming for the Object-Oriented Programmer I knew that is was possible to extract the items in a list. Elm provides you with head function to extract the first element of a list.

head : List a -> Maybe a
head [1, 2, 3] == Just 1
head [] == Nothing

And a tail function to extract the rest of the list.

tail : List a -> Maybe (List a)
tail [1, 2, 3] == Just [2, 3]
tail [] == Nothing

The type annotation before the head and tail examples is an Elm convention that makes is easier at a glance to determine a function’s inputs and outputs and also easier to debug compiler warnings.

Both functions take a list (“List a”) as input and output a single element of that list (“Maybe a” for head) or the remainder of the list (“Maybe (List a) for tail”).

The “Maybe” in this type annotation indicates that in certain situations, like when an empty list is passed as a parameter, nothing might be returned (in fact, Nothing is returned).

Since Elm doesn’t support null values it uses the union types of Maybe, Just, and Nothing to handle situations like this (I’ll probably do a blog post about these types at a later date as I try to understand them better).

So using head and tail I could systematically extract the values of a list for review. If I take the example Elm list with the three Player records in it that I showed previously and applied successive head and tail functions to it I would get this:

head == { id = 2, name = "Robin Maya", points = 0 }
tail == [ { id = 1, name = "Katie Maya", points = 0 }
          , id = 0, name = "Bill Maya", points = 0 } ]

head == { id = 1, name = "Katie Maya", points = 0 }
tail == [ { id = 1, name = "Bill Maya", points = 0 } ]

head == { id = 1, name = "Bill Maya", points = 0 }
tail == []

So I can extract individual list elements but one question remains–what mechanism do I use to leapfrog my way through the list since Elm doesn’t provide foreach or do-while control structures?

Some thinking and googling lead me to this page which explained how to create recursive functions in Elm.

To explain how a recursive function works here’s an example of how to calculate the factorial of a number using recursion. In mathematics, the factorial n! of a non-negative number n is the product of all positive integers less than or equal to n. For example,

5! = 5 x 4 x 3 x 2 x 1 = 120

The Elm function to calculate the factorial of a number would be:

import Html exposing (..)

main = Html.text (toString (factorial 5))

factorial : Int -> Int
factorial int =
    case int of
        0 ->
        _ ->
            int * factorial (int - 1)

The factorial function type annotation (line 5) indicates that this function takes an Int as a parameter and returns an Int. The case statement in the body of the function (lines 6-10) uses pattern matching to determine what to do with the parameter value passed into the function:

  • If the value of int is zero the functions returns a value of one
  • Otherwise, for any other value (“_” acts as a wildcard) the function calls itself again, subtracting one from the current value of int. The value returned from this function call is multiplied by the original value of int.

In the example above, calling the factorial function with the parameter of 5 makes five recursive function calls.

factorial 5
    5 * factorial 4
        4 * factorial 3
            3 * factorial 2
                2 * factorial 1
                    1 * factorial 0

Which yields the value of 120.

Back to my original problem–I have to update one of the records in the list using the player’s id.

[ { id = 2, name = "Robin Maya", points = 0 }
  , id = 1, name = "Katie Maya", points = 0 }
  , id = 0, name = "Bill Maya", points = 0 } ] 

So I wrote a recursive updatePlayer function to do that.

updatePlayer : Player -> List Player -> List Player
updatePlayer player players =
    case players of
        [] ->
        x :: xs ->
            if x.id == player.id then
                { x | name = player.name } :: xs
                updatePlayer player xs

The function takes two parameters–the first is a single player object containing the id of the player to update and their new name. The second is a list of current players. The function returns a list of updated players.

The case statement uses pattern matching to determine what to do with the list that’s passed as a parameter into the function. If the list is empty, it simply returns and empty list (lines 4-5).

The pattern on line 6 splits the list into a head and a tail. The head (a record) is assigned to x and the tail (a list) is assigned to xs. If the id of the head record is equal to the id in the player record a new player record is created with an updated player name (obtained from the player record) using the following format:

newRecordName =
    { oldRecordName | fieldName1 = newFieldValue1
                    , filedName2 = newFieldValue2

Rather than assigning this newly created record (Elm data is immutable) I simply it after using the cons statement (::) to add it to the front of the list stored in xs

If the id of the head record is not equal to the id in the player record then I recursively call the updatePlayer function again, passing in the player object and the tail stored in xs as the list.

This first attempt of updatePlayer has an error in it. When passing in the Before list the function returned the After list. The player’s name was updated from “Katie” to “Kathleen” but I lost one of my records. Rather than retaining a record that didn’t match the player id the function appeared to be throwing it away until if found a match.

[ { id = 2, name = "Robin Maya", points = 0 }
  , id = 1, name = "Katie Maya", points = 0 }
  , id = 0, name = "Bill Maya", points = 0 } ]

[ { id = 1, name = "Kathleen Maya", points = 0 }
  , id = 0, name = "Bill Maya", points = 0 } ]

I spent some time trying to figure out why this was happening but ran up against my limited knowledge of Elm and my unfamiliarity with functional programming. I thought about also passing in an empty list as one of the parameters and using it to store head records as I iterated through the list but that seemed kludgy.

So I did the next best thing–I decided to sleep on it and return to the problem the next day.

Fifteen minutes after sitting down at the keyboard the next morning I discovered my omission.

-- Original
updatePlayer : Player -> List Player -> List Player
updatePlayer player players =
    case players of
        [] ->
        x :: xs ->
            if x.id == player.id then
                { x | name = player.name } :: xs
                updatePlayer player xs

-- Modified
updatePlayer : Player -> List Player -> List Player
updatePlayer player players =
    case players of
        [] ->
        x :: xs ->
            if x.id == player.id then
                { x | name = player.name } :: xs
                x :: updatePlayer player xs

Compare the recursive function call on lines 11 and 23. Line 11 discards the unmatched head record when calling updatePlayer again while line 23 uses the cons (::) function to “stitch” the unmatched head record to the whatever results are returned by subsequent calls to updatePlayer.

I was quite pleased with myself for about fifteen minutes. Not only had I figured out how to iterate through a list using Elm pattern matching but I was also one step closer to grokking the immutable nature of data in Elm.

But then I reviewed the lesson’s answer to see the instructor’s solution and discovered another way to accomplish the same thing using two new Elm functions and no recursion. It was a bit humbling. I’ll write about it in my next post.

Helpful links

Posted in Software Development | Tagged , , | Leave a comment


I’m 78% of the way through Elm For Beginners, a free course about the Elm programming language. I first read about Elm in Seven More Languages in Seven Weeks but did nothing with it until this week.

My reasons for learning Elm are simple:

  • It compiles down to HTML, CSS, and JavaScript, the three languages used to build web applications
  • It’s a functional reactive language with strong types and immutable data structures

Though I’ve had some experience with HTML and CSS, web development isn’t the first thing that bubbles to the top when I consider the software development that I’ve done in the past. I fiddled around with JavaScript because it’s become the lingua franca on the web and I felt I should know it better but there are some things about it that leave me cold.

I’ve read a lot about functional languages in the past, about how their immutable data and lack of side effects help you develop code that is easily maintained, easily testable, and easily refactored. Given that most of my coding has been in C# .NET over the past years I figured I would check out F#, Microsoft’s functional language.

But when I looked at F# I just wasn’t excited about it (I still might use it for cross-platform development with Xamarin down the road) and I had this nagging feeling that I should beef up the web development side of my resume but I didn’t want to start at the HTML/CSS/JavaScript level.

So I took another look at the Elm, checked out the home page and some of the documentation and decided that this is the language that I want to use for creating web front ends. Down the road I can figure out how to make it interop with either  ASP.NET MVC or learn another functional language like Elixir, combined with the Phoenix framework.

I’ll leave you with Richard Feldman’s excellent Introduction to Elm.

Posted in Software Development | Tagged , , | Leave a comment