How I play TTRPGs in Emacs

Howard Abrams - Website: - Mastodon:,

Format: 15-min talk; Q&A: BigBlueButton conference room
Status: Q&A finished, IRC and pad will be archived on this page


00:00.000 Introduction 01:20.680 Solo RPGs 02:47.440 Demo 04:11.760 Randomization 05:31.960 Moves 06:03.640 Reference 06:34.680 Story arcs 07:48.680 Using different stats 09:02.960 Dice rolls 09:34.800 Dangers 10:19.680 A strong success 11:49.680 Other solo RPGs 13:04.720 Conclusion

Duration: 14:36 minutes


Listen to just the audio:
Duration: 19:20 minutes


As an eternal Dungeon Master, I have a long history of collecting my notes in Emacs. When my son was very young, I would export my Org files to an HTML page that would include some magic JavaScript, so that when displayed on my iPad, I could touch a table to have it randomly return a line, or touch a phrase like 3d6+1, to have the web page return a dice roll.

Lately I’ve been getting into Solo versions of tabletop role playing games (TTRPG), and have had a fun time writing Lisp to support this style of play, and thought I’d share my code and my fun.

I’d like to begin by showing my game play in action: I’m currently playing Ironsworn with the Mythic GM Emulator and various other tables and procedures to stike a balance between playing a game and writing a book. Next I would like to show the code that supports the interface, and perhaps dive a bit deeper into some of the underlying mechanisms and functions, especially that function that randomly chooses entries from Org tables. I’ll end with a plan for turning my code into a community project, if people are interested.

Format (10 minutes, 20 minutes, description of other format) and outline: 20 minutes, but I could do less if you have too many submissions.

About the speaker:

Howard often gives technical, work-related talks at EmacsConf, but here he is talking about playing games in Emacs.


Questions and answers

  • Q: Where can I get this?
  • Q: How well would this suppliment freefoxm writing. short novels or novels?
    • A: I think it would be a good start. It is just an org file, so you can go as far as you\'d like with the writing.
  • Q: Does the current version also have some utilities for doing multiplayer? (either physically or digitally) (since you mentioned, you previously did multiplayer sessions as well..)
    • A: Nope, it is just Solo, but that does sound like a fun idea.
  • Q: This game + CRDT (collabrative editing should be great for non-solo playing?
    • A: Perhaps, I\'d like to try it out.
  • Q: How does one become super awesome like Howard Abrams??
    • A: \"There\'s no secrets! Just follow your passions!\"
      • Seriously inspiring.
  • Q: Please talk a little about how you produced such a slick presentation video!  Everything looked completely professional!
  • Q: Does table data allow for recursion?  I have a table that when I roll on it, a result comes up that references another table (e.g. result that returns \"There are [random monster] haunting the cavern entrance\" and we\'d roll on [random monster] and inject them into the result.)
    • A: Yes.
  • Q: With your toolkit a list of good books would be nice to be included. example d&d, space, steampunk, cyberpunk settings
  • Q:  Hi Howard and Thanks for an outstanding presentation!!! What did you use to create the graphics in your presentation?
    • A: I don\'t really know. I will have to ask my son, as he did the editing and directing.
  • Q: Any plans to borrow tables from Dungeon World, or Ironsworn:Starforged and publish in the toolkit repository?  (
    • A: That does sound like fun.
  • Q: How has this impacted your imagination on the scenes?  (e.g. constraints by algorithms)
    • A: Yes, writing creatively can be very helpful in many other aspects of your life.
  • Q: Your essay/video \"Literate DevOps\" I consider a classic, and it\'s really opened my eyes on org-babel and what you could do. Do you still use those techniques at work? Have you come up with any improvements or changes to your workflow?
    • Yup. Still do.


  • Ironsworn Emacs project code:
  • Note that this code depends on my earlier project:
  • The alpha version of a RPG Toolkit code:
  • Really cool project! - Also the enthusiasm for the topic is really contagious!
  • \"Every time Howard publishes a talk, I end up doing one more thing in a new radical or literate way inside Emacs - currently looking into how to go about literate snow shoveling for the winter ahead.\"
  • I can see this one is going to be a classic
  • the camera and lighting already has me sold
  • Such a vibe!
  • can I just (require 'howardism) and be done with it all?
  • i love this so hard
  • "Howard's talk is published on the site now" "I'll be in my bunk"
  • Holy CRAP Howardism WINNING EmacsConf2023
  • Could we add this to emacs beside dunnet?
  • Howard's stuff is always great. this particular thing is totally unchained. :D
  • "Howard approaches your table in the tavern. Do you (1) buy him a tanker of mead (2) kill him and eat his brain"
  • "Not showing-off," he said.
  • That was epic
  • Happy Hacking!
  • What's the emoji for a crowd picking Howard up on our shoulders and carrying him around
  • there's a peaceful aspect of having non web based stuff to play
    • Non-web, and not-networked!
  • the web is horrible. lisp machines are the future.
  • Imagine playing D&D with colab (from the previous talk)!


[00:00:00.000] Introduction

Hi there, I'm Howard Abrams. You may remember me from past conference talks as "Literate DevOps and the Temple of Doom" and "Using Eshell for Fun and Profit". I'm here to talk to you about my latest Emacs project: playing games, solo role-playing games. I started playing RPGs when I got my first copy of Dungeons & Dragons when I was 12. Yes, my original copy burned in the Great Satanic Panic of the 1980s, but that's another story. I started playing other RPGs like GURPS. These are some of my notes. Back then, I was typing them in Emacs, but I formatted them with LaTeX. Later, when I was introducing my kids to role-playing games, I actually typed them up still in Emacs, but now formatted them for a tablet. I wrote a little JavaScript code that allowed me to click on it, and it would roll dice, generate random events, keep track of turn order, you know, everything, so I didn't have to slow down the action of the game. Well, when my kids got older, I still managed to sneak in a game of D&D once a week at lunch. This pastime came to a screeching halt with the pandemic.

[00:01:20.680] Solo RPGs

I turned to playing role-playing games by myself to get my fix. Playing these silly elf games in solo mode has been part of the game for many years, but with so many of us stuck at home, solo role-playing games really expanded, creative people releasing some amazing ideas. What's a solo RPG like? Well, it's somewhere in the middle of writing your own story, where anything's possible, but you've got to do all the imaginative work; or reading a choose-your-own-adventure book, where the text is given to you, and you have free, a few predetermined paths; and tactical battle games, where dice determines everything. It kind of fits in the sweet spot between those. While I started removing the Game Master using the Mythic GM Emulator, Ironsworn really captivated me. I began with dice, pencils, notebooks, you know, just like when I was a kid. But taking notes on paper? Yeah, you know me. That's not my jam. Org mode is. And, you know, notes have to be in Org, well, why not write a little dice roller in Lisp? Well, when Shawn Tomkin released his Ironsworn under the Creative Commons, well, I could just download the entire text. I figured I could just render the entire game in Emacs.

[00:02:47.440] Demo

All right, enough talk. Let's get some Emacs action here, while I show you a bit of my game. When playing a solo RPG, I jot down the story notes in an Org file. I mean, did you expect anything less from me? I alternate between lengthy prose and short notes. As I'm both the writer and the audience, the goal is just enjoyment. So, this document is both a record log of my game sessions, as well as my character's character sheet. In most RPGs, a player's focus is a character sheet that lists all the attributes, the stats, equipment, powers, you know, that sort of thing. For my game, I wanted the focus to be the prose, or at least the notes. So, I put down all the stats as Org mode properties. Now, I can collapse a property drawer and have functions that just grab values from these properties. All right, let's play. While not important to my talk, I'm in the middle of a game. My character, Tegan, promised to help a village by tracking down the son of a village chief. A less-than-stellar roll meant I didn't catch him before he entered the mysterious underground structure of a relic of an ancient people. I just finished playing out the journey, and he's about to enter into the Catacombs of Svala's Blood.

[00:04:11.760] Randomization

Why that name? Well, that was actually what came up from an extensive random number generator that I wrote. As I wrote more and more functions to help me play this game, and since I don't play all the time, I created hydra. I can roll dice, I can roll dice challenges against the character stats, I can adjust stats. Lots of random generators come from this oracle section. For instance, are footprints going through the door? I press c, and I'm prompted with how likely. Since the villagers gave Tegan vague directions, and he didn't see any signs the contrary, I chose "likely". And, well, it originally said yes, and that's why I jotted this information down. Now, this is different than my character's ability to notice the prints. This is about generating the story, something that the game master would do in a typical role-playing game. Now, if I wanted to name something, or even the current weather, I have random tables with the C keystroke. Hmm, weather. Oh, it's summer, so hey, it's nice and clear. All right, let's play.

[00:05:31.960] Moves

The action in Ironsworn, like other Powered by the Apocalypse games, is driven by moves. So, I hit the m key, and all the moves show up. Now, I don't think I need to espouse the virtues of completing-read enhancements like Ivy. Here, I'm using orderless with vertico to help me find my choices. Since I've discovered a site, let's play that move.

[00:06:03.640] Reference

I seldom remember the details for the moves, so I figured, why not put the text of the book in an Org file and show it in a side window? The prompt at the bottom, asking for a name, is driven by the content in the displayed Org file. This allows me to enhance my game without changing the original code. So, let's call this story arc, Exploring the Catacombs of Svala's Blood. Ooh, sounds epic.

[00:06:34.680] Story arcs

Ironsworn tracks the beats of a narrative, so major plot points take up more room in the fiction than minor plot points. Similar games like Blades in the Dark use numbers to track these, so you can say something like, we're three quarters of the way through this story arc. Ironsworn just uses labels, and while I want this particular story arc to be significant, I really just want to get in, find this person, and get out. So, I'm going to call this "short". Next, it's asking about an Org mode header placement. While I originally wanted my Org files to be completely flexible, one thing I noticed in playing is that a pattern always emerged. The story became a tree. You see, story arcs were just a series of montages or scenes, and each of those were made of a series of events and challenges to overcome. So, each Org mode header has a track, which often becomes the number of subheadings. At any point, I can see how much track is being made. So, for instance, this one seems to be about a third of the way through.

[00:07:48.680] Using different stats

So, let's dive into this ancient place. Since I've been walking through a misty forest, I can imagine vines hiding an immense door and a humid, earthy smell as I peer inside. But I don't have to write that stuff down, or if I want to practice my writing, I can. I can imagine the place is dark, so Tegan lights a torch before peering into this obscure world. As this move mentions, the next move to make is called Delve the Depths. As soon as I select this move, it shows up on the side window, and explains that, depending on how you're moving through this ancient catacombs, is what kind of stat I roll against, and those stats show up at the bottom. You know, if I'm sneaking around, you roll against "shadow". If you're trying to go as fast as you can, it's "edge". But I kind of imagine that he's thinking through, being very careful about it. So, I'm going to select "wits". And I don't have any modifiers. Just about every one of my stats prompts me if I want to add or subtract any values.

[00:09:02.960] Dice rolls

A miss. I should explain how the dice roll in this game. The downside to Ironsworn is that the dice mechanics are more cumbersome than other games. You roll a 6-sided die, add to it your relevant stat, plus any modifiers. Next, you roll two 10-sided die and see how it compares. Of course, I programmed this in Lisp, but when I displayed it, I wanted to see all the dice. And I also just wanted to see the end results.

[00:09:34.800] Dangers

So I colored it. I rolled a miss, which means I need to reveal a danger. Sure, I could imagine all sorts of dangers, but this is a game. I've already made a random generator for dangers. In fact, I've made a random generator for dangers in an ancient underkeep. Discovery undermines or complicates the quest. Hmm, a complication for finding the chief's son? What about a labyrinth full of hallways and levels with lots of choices and almost no way of finding them? Yeah, that sounds like it fits pretty well.

[00:10:19.680] A strong success

Time for another move. This time, we're going to gather information, see if we can figure out which way to go. A strong hit. Excellent. I imagine Tegan noticing footprints in the dust and knowing where to go. The game suggests that when you get a strong success, you can increase your momentum. These game mechanics come into play later, but this function here allows me to adjust that stat +2. I don't even have to scroll to the top of the buffer and edit that value in my properties. At any point, I can take a look at those stats and see how they measure up. Again, I don't have to scroll up and take a look at my properties at the top of the Org mode file. That's how I play the game. It's just a recursive loop of playing a move, rolling some dice to see how it works, trying to answer the question based on your own imagination or random tables, which the game calls oracles, and play creatively until you decide to take a break and pick it up another time. I think you get the gist of how I play this dice and pencil game in Org Mode.

[00:11:49.680] Other solo RPGs

However, I found more solo RPGs to play. And of course, I want to render them in Emacs too. This code for Ironsworn was a bit too specific, so I decided to create a role-playing game toolkit. This project is still in the early stages, but I've created some functions for mimicking rolling dice, including a mini-DSL for making dice mechanics typical of many role-playing game systems. I've also ported over the random table system. A text file can just list entries to be displayed at random. I love that I can put dice expression and word choices in the entries. One type of random table allows you to essentially copy and paste a table from a published game into a text file. A frequency table is what I'm calling a list of random entries where some entries show up more often than others. I'm working on generalizing the character sheet attributes as Org properties, so if you're interested, check out the project at Codeberg.

[00:13:04.720] Conclusion

The point of my presentation is not to show off Ironsworn, how I programmed it, or even this new toolkit. You see, most engineers, when they get an idea for a game like mine, would make a web app. Nothing wrong with it. More people can play it, but web apps suffer from text entry. And don't tell me you prefer the keyboard interface to Google Docs. Oh, and the JavaScript framework du jour? Oh, I mean, that's a huge barrier of entry when all you want to do is have a bit of fun prototyping a game. What I'd like to impress upon you is that hacking Emacs to make personal games is a trip. Learning Lisp is, it's easy. And more, Emacs Lisp has some, well sure, it has some cruft. But really, some of those features that I would hate at a distributed system at work, like global variables, makes hacking easier when you just want to have some fun in your own system. So, grab your laptop, sink into your comfy chair, pour yourself a glass of scotch, and craft yourself an enjoyable evening. Happy hacking, my friends.

Captioner: sachac

Questions or comments? Please e-mail