I am not an expert on solo RPGs, but I have played a quite a
few. These are some I have especially enjoyed.
World-building
Some solo RPGs are focused on building a world, rather than role
playing within one. It's the genre I have most enjoyed. They're
especially easy to put down and come back to, and the results are
useful for other TTRPGs. Like, I made a history for my Blades in the
Dark character's dagger with Artefact. I didn't share that with
anyone really, but it helped my play a bit. And I enjoyed it!
These are especially recommended if you enjoy The Quiet Year and
want something like that to play solo.
In Artefact you create the history of a magical item. From its
origin, to the numerous people its been owned by, to the stretches of
time where it was lost and forgotten. There's also a mini-game where
you can do the history of a group of critters who live among the
object in one of its fallow periods. (Like a colony of mice who use a
shield as the roof to a community center.)
In I, The Land you really do role-play as a piece of land. You got
flora and fauna, there's big and little things that happen upon you,
and you react (or don't). I've been surprised by twists and unexpected
events more in this than any of the others in this section. This is a
really neat game!
It uses playing cards for randomness, and the one complaint I have is
that the deal is weird. First you draw four cards from a fully
shuffled deck, then you need to draw four cards from each suit. It's
awkward to do live. Luckily, I can make websites and I made one to do
the deal for you.
In Lineage you write the history of a royal family. From its bare
beginnings through its rise to a golden age or two, to its inevitable
collapse. This one can go a very very long time. I've never actually
reached the ultimate end of a family. You'll amass quite a collection
of flawed ancestors for a royal character.
Traditional
I only have one entry for a solo RPG that plays like a traditional
TTRPG, but it's so good maybe it's all you need.
Ironsworn and Starforged share a system, which is a bit
unforgiving, but impressively put together for running a traditional
TTRPG game by yourself. There's a bit of set-up before you get to
play, but the play is really, really good.
Two things stand out for me in how well it works:
Not having to roll for enemies during combat or deal with enemy stat
sheets saves a lot of headaches.
You get to role-play a lot. I was worried that it would be too
dice-dependent, but no!
Ironsworn is low-magic, high-peril fantasy. Starforged is in
space. Pick your setting.
IRL
There are some solo RPGs that are less sit at a table with dice and
paper and more you're doing stuff in the world. If you can not feel
weird about it, here are two (or one and a collection, rather).
Made by The Quiet Year's brilliant author, Avery, these are four games that you play in your mind as you go about the world, no paper or pen needed. These are the farthest removed from normal RPGs on this list, and more contemplative than "fun". But if it's your cup of tea, drink deep.
Last year's December Adventure I had one project: a set of scripts to
run GoToSocial bot for a song-listening club I'm in with a dozen
people. That version of the club (for there have been a few) is coming
up on it's one-year anniversary, and I'm proud of it. All its flaws
and peculiarities remind me that of how it was handcrafted for a
finite time for some friends. We'll lose steam at some point, and it
will be an archive of something we shared. I like that.
This year's adventure ended with me working on porting some of that
code to Rust. Because the code is not something I work on a lot, I
find (for me) that Rust makes code easy to come back to. After weeks
or months away from Rust code that I wrote, it's easier for me to see
what I was up to and why. I still get tripped up by some interactions
between async code and ownership, but the confidence I gain from a
happy compiler is worth the stumbling.
But the jewel of this year, the completed project, was the creation of
another GoToSocial bot, @tomes@phantasmal.work. The scripts
that run it take an epub file as input, split it into 5,000–9,000
character posts, and publishes them one by one each day until the
end. I was inspired by DailyLit, a service I used years
ago to read a number of books by email. I've been having trouble
putting aside time for reading, so I decided to bring reading to
somewhere I was: the Fediverse.
Currently @tomes is posting its way through O, Pioneers! by Willa
Cather, a book I chose because it was a relatively short novel I
hadn't read yet. And what a pleasant choice it turned out to be. If I
never load up another book for @tomes, this will still feel like a
rousing success.
As I posted, I re-learned what I learned last year:
that 20 minutes a day can be surprisingly productive,
that I am happiest in writing code when it's just for me or for a
small group of people I know personally.
I hope I will remember these lessons longer into 2026 than I did in
2025.
The last few days have each featured a very productive half hour. I'm
letting the ebook bot sit as-is for now. It's working just
fine and while I was working on its reimplementation in Rust, I
remembered another Rust rewrite I wanted to get back to.
I'm in a song-listening club with some friends. The little bit of code
that runs it is a handful of Python scripts and systemd timers. For as
small as it is, I overbaked it a bit. There's a RabbitMQ server. This
doesn't need a RabbitMQ server. And I often wish there were one
service instead of five.
So that's what I've been rewriting and setting up. Since Christmas Eve
I've ported the code that generates the statistics page and the bit
that posts a pair of songs on Saturdays for a "flashback"
discussion. I had to think harder about async and moves and ownership
and errors.
I had to find a job scheduling library that would let me nicely mix
tasks that should run on an interval (every 5 minutes) and on a
schedule (every Saturday at 9am). I found turnkeeper
which serves that nicely. I nearly gave up on it when I was running
into a "future cannot be sent between threads safely" error... But it
turned out that organizing my code better resolved the issue.
A satisfying resolution, even if fundamentally I'm not exactly sure
where a future was trying to go between threads.
Yesterday and today I started a Rust project where I'm re-implementing
the ebook-splitting code and where I'll write the new algorithm I
mentioned the other day.
Part of picking up Rust again is getting my bearings, especially
around organizing code into modules. I think I finally have the rule I
need to remember that always trips me up:
When you have binary and library code, they are different crates and
the library crate controls all the Rust source except the one file
that makes the binary, main.rs. That's why in main.rs you use PACKAGE_NAME::... and everywhere else you use crate::.... The
binary has to import the library. The library gets to talk about
itself as the crate.
Yesterday was basically a day off. I looked a little bit at the
current state of Scheme implementations... I don't know what I'm
waiting for, but I think I'm waiting a little longer.
Today I wrote notes toward a new ebook chunking algorithm for
@tomes.
The idea being the splitting works from the whole instead of
accumulating from the beginning. Trying to balance chunks better.
As an example, a series of chapters with the following character
counts:
12,000
8,000
12,000
Currently, the accumulation strategy grows each chunk until hitting
around 8,000 characters, and would result in chunks approximately like
so:
8,000
8,000 (spanning the chapter 1-2 border)
8,000 (spanning the chapter 2-3 border)
8,000
Instead, look first for any chapters within the threshold, and make
their chunks (nearly?) invincible. Then chunk the remainders
"evenly":
6,000 (chapter 1, front half)
6,000 (chapter 1, back half)
8,000 (the entirety of chapter 2)
6,000 (chapter 2, front half)
6,000 (chapter 2, back half)
Additionally, apply some penalties to certain pieces of markup to try
to avoid breaking up sections that would likely suffer.
For example, near the middle of a long chapter:
<p>
.... long paragraph ...
</p>
<p>"Quick dialog," she said.</p>
<p>"Witty retort," he replied</p>
<p>"Devastating comeback."</p>
<p>
.... long paragraph ...
</p>
It'd be nice to penalize breaking a chunk between short paragraphs,
likely to be dialog that would be better to stay together. And have
large penalties near the beginning and end of a chapter, to avoid
cutting too close to natural seams.
Then find the lowest penalty cut points near the point where a naïve
even split would go.
All my thoughts about cleaning up the code that powers
@tomes@phantasmal.work got sidetracked by starting on Tumble
Forth, which promises, "Starting from bare metal on the
PC platform, we build a Forth from scratch..."
I came across it from a sequence of clicks that started from browsing
the #DecemberAdventure hashtag and ended up derailing my morning.
Now here I am, looking at wikis and trying to write assembly.
mov al, 0 ; clear lines
mov cl, 0 ; starting at the left
mov ch, 0 ; starting at the top
mov dh, 7 ; until line 8 (which is enough)
mov ah, 0x06 ; Scroll up window
int 0x10 ; Interrupt
I wrote a few things in Uxn earlier this year, which primed me
for getting captured by a tutorial for implementing Forth from
scratch.
I think today will just be the quick morning update to handle ebooks
with multiple title entries by simply picking the first one. In
the case in front of me,
["Frankenstein", "Or, the Modern Prometheus", "Frankenstein, or the Modern Prometheus"]
it will choose Frankenstein.
Meanwhile, O Pioneers! is proving to be a good read. It wasn't even
on my list!
One assumption of the script that splits up the xhtml files is that
each immediate child of the <body>'s <section> will be "small". So
all it does is take each child, see if adding it to the current chunk
is still within the size threshold and either add it or make a new
chunk.
However, Frankenstein proved that assumption false. There were two
examples of children that were big: another <section> and
<blockquote>. The <blockquote> examples are kind of fun, because
Frankenstein is a story-within-a-story (-within-a-story...).
Today's solution was to "unwrap" <section>s. A <section> doesn't
do anything in a fediverse post, so it seems safe to do that.
<blockquote>s impact rendering so I'm unwrapping it, but re-wrapping
each child in its own <blockquote>. So this:
<blockquote>
<p>Three be the things I shall have till I die:</p>
<p>Laughter and hope and a sock in the eye.</p>
</blockquote>
Becomes this:
<blockquote>
<p>Three be the things I shall have till I die:</p>
</blockquote>
<blockquote>
<p>Laughter and hope and a sock in the eye.</p>
</blockquote>
Semantically bad, structurally questionable, but renders fine.