Data × Puzzles & Games

Category: Data Science

Introducing the IF Recommender

I’m excited to announce something I’ve been working on for the past few months: a recommendation app for Interactive Fiction!

I’ve wanted to build a recommendation system from scratch on a real-world dataset with current models and techniques, and I’ve also wanted to get back into playing Interactive Fiction after being away from the scene for a few years. It’s cool to see this app out in the world now as something that I’ll personally use and that will also hopefully be useful to others in the community.

How it works

You search by game, author, reviewer, or vibe to get a list of games ranked according to semantic relevance from machine learning models. You can then filter the results by metadata (system, tags, years, user ratings, etc.) and you’re set to discover the next great IF game tailored to your interests.

  • game: pick an IF game and get back games with a similar feel
  • author: pick an IF author and get back games in their spirit (excluding their own)
  • reviewer: pick an IFDB username and get back games that suit their taste based on their ratings (excluding ones they’ve played/rated)
  • vibe: pick a set of systems/genres/tags and get back games that vibe with that set

Each search mode’s input becomes a query of systems/genres/tags, and two models rank against it: a fast two-tower encoder embeds the query and every game into a common space to pull a longlist of candidate games by similarity, then a slower but more accurate cross-encoder scores each candidate game against the query directly.

The game, author and reviewer rankings are pre-computed ahead of time and served as a lookup, whereas vibe is scored live and takes a few seconds to compute (queries may get queued based on traffic).

The source code is available on Github, and the data comes from IFDB via quarterly database dumps published to the IF Archive (around 15K games, 80K ratings, and 20K users as of June 2026). After filtering to games with enough signal to learn from, the app ultimately lets you search around 10K games, 6K authors and 3K reviewers.

Go play something

I’m excited to start playing some of the top games I discovered when passing my IFDB username into reviewer mode, with Les lettres du Docteur Jeangille and The Absence of Miriam Lane up next for me. What’s next for you?

if-recommender.datalexic.com

Twine Story Clustering

In Twine-authored interactive fiction, one can find a wide range of structural approaches to storytelling through hyperlinked passages.

As explored in posts by Emily Short on small-scale structures and Twine gardening or by Sam Kabo Ashwell on standard patterns in choice-based games, as well as the work in Porpentine’s Twine Garden blog and the DotGraph project, full or partial story graphs can be useful both as a writing tool for authors, and as a way to reason about patterns of narrative structure in general.

Using twine-graph, a Python package developed to automate the creation of structured representations and visualized graphs for published Twine stories, I ran a meta-analysis of Twine stories based both on structure and on textual content.

I pulled all Twine stories published as part of the IFComp and Spring Thing competitions dating from 2012 onward (159 total stories) from the Interactive Fiction Archive, under the competitions’ terms that make all stories freely available upon entry. These were then processed into a dataset of structured representations and visualized graphs, and finally run through clustering analyses based on both structural and textual features.

Story Clustering with Structural Features

For structure, I used NetworkX to produce a number of features from each story’s graph structure: number of nodes, link degree (mean, median, and max), graph radius, and graph diameter. Given these features, the stories were passed into an algorithm for hierarchical clustering with SciPy to generate a dendrogram showing how stories group together according to similarities in their structure.

Looking at some of the stories clustered together according to structure, some interesting patterns arise. The visual representations of the stories Will Not Let Me Go (2017) [visual] and Who Among Us (2013) [visual], for instance, show clear similarities: both are fairly linear narratives with light branching and occasional denser interactive moments.

Story Clustering with Textual Features

Given that each story’s passage text was available, I also ran a clustering analysis based on textual representation, to get at content and subject matter. This involved using spaCy to preprocess each passage, removing stop words and transforming each story into a word embedding space (using GloVe vectors) to facilitate hierarchical clustering.

The clustering changes substantially when using this semantic space, leading to nice results. For instance, the three stories authored by Porpentine—howling dogs (2012), their angelic understanding (2013), and With Those We Love Alive (2014)—are clustered together, which makes sense given that the author has a uniquely poetic and enigmatic writing style with content matter focused on the surreal and monstrous. Another interesting cluster appears to cover dark fantasy, magic and the macabre, and includes, among other stories, Day of the Djinn (2017), Grimnoir (2018), and Arcane Intern Unpaid (2015).

The full dataset, including graph visuals and structured representations of each story in the corpus, is available on GitHub, for any who are interested in browsing through specific visualizations or running other types of experiments. The analysis notebook used to produce the above plots is also available, and was written using Jupyter.

Introducing TwineGraph

Twine Graph is a Python package and command line tool for parsing passage and link structure from published .html Twine stories and outputting the resulting graphs in visual (.pdf) or structured (.json) formats. The goal of Twine Graph is to allow for research and analysis of story structure in freely-available Twine games.

The initial release is now available through PyPI under the name twine-graph, and the source code is available on GitHub.

Story Visualization

To demo Twine Graph’s capabilities, let’s look at two recent, highly rated Twine stories from the annual Interactive Fiction Competition (IFComp). Cactus Blue Motel (2016) is a game that involves a large amount of movement between the rooms of the titular motel, while Will Not Let Me Go (2017) is a more linear story that moves from scene to scene with only a few clusters of densely interlinked passages.

The twine-graph command line utility takes a published .html Twine file as input and programmatically derives a directed graph structure of passages and links. It outputs a structured .json file and corresponding graph image file, with the nodes laid out according to heuristics encoded in the graphviz library. The automatic layout appears to work well for many Twine stories, creating a top-to-bottom flow with nodes clustered into visually coherent sections.

In Cactus Blue Motel, the start and end sections are apparent, along with an interesting mid-game containing large clusters of highly-connected nodes indicating distinct explorable areas. [Visualization]

In the case of Will Not Let Me Go, the flow of the story is more linear, with only a few occasional clusters of nodes for scenes that focus on interlinked passages and choices. [Visualization]

Corpus of Twine Stories

In order to unveil insights into Twine story structure on a larger scale, I’m working on putting together a corpus of story files in .json and .pdf formats for all of the freely available Twine games that have been submitted to both IFComp and the Spring Thing festival since the inception of Twine games in those competitions, which goes as far back as 2012. I’m excited about the possibilities that this data will open up for the IF community to research and analyze choice-based game structure.

© 2026 Datalexic

Theme by Anders NorenUp ↑