harmonbee's thoughts

A postmortem on the second Sahasrara Scoop, featuring Seraph and The Holo Man

(This post was originally posted on Cohost.)

Left: A screenshot of the scoop running on the development version of the bot, Prosperbot. Right: A (cropped) second screenshot of the game running, this time with differently-coloured messages.

After the success of the previous scoop, Fern (@AceEmpress) and I were tasked with writing a follow-up for the second half of NSG's Liberation Cycle, Rebellion Without Rehearsal. This was hosted on the Sahasrara Discord bot (until about two weeks ago... I have been a bit slow in sorting this out), but will eventually be available online - Fern is writing the Twine port this time so keep an eye on their Cohost for that! I'll rechost it once it's live.

(EDIT: Fern completed the port, which you can find on our shared itch.io page.)

Thank you again for all of the excitement about the scoop - I'm aware that the bot was struggling a bit at times to run it, so I hope that if that stopped you from playing the game that you'll give it a go once the Twine version is out.

I've promised in a few places that I'd write about how the game came together, just like after the previous scoop. This follows after the cut - needless to say, massive spoilers for the scoop follow. A fair amount of this refers to the previous scoop - you may want to play through it or at least read the retrospective for that scoop first.


What's the idea with this scoop?

A lot of the idea was effectively a continuation of the previous scoop, both to resolve the story and also to reuse some of the tech included in Sahasrara for the previous scoop. Having been given an ice again - this time the huge unique ice Seraph - we went for a similar basic story of making a run and finding this ice. This time however, we were also given a card for the Runner to find on getting into the server: The Holo Man, the CEO of the massive media subsidiary Epiphany Analytica.

We had a few leads for designing the game.

We didn't want to copy the name-guessing structure of the previous scoop - and it felt like Seraph wouldn't be much of a talker, let's say - so needed a new idea. This led us to the idea of exploring the part of netspace that Seraph is trapped in, which would vainly be in Starlight's image, which slowly turns weird and corrupted as the old net influences of Seraph infected the place. Seraph could be treated like an abandoned science experiment: various notes and environmental clues giving the details needed to survive your eventual encounter with it.

We also wanted to again make use of Fern's and my writing strengths: mine being silly light-hearted stuff and theirs being the more ominous stuff. Luckily, this more ominous scoop came at a time where I am very busy, so they were able to sort out a lot of the writing.

The mechanics of the game

The game was split into three parts: the introduction, the main exploration of Seraph's abode, and the final encounter. We'll talk about each of these!

Like last time, this was prototyped in Twine. Here's an annotated version of the final minimap!

The overview in Twine, a mess of connected states which are grouped into the three parts mentioned.

My skills with the paint tool are unmatched.

The introduction

The introduction is very linear - just a lighthearted setup telling the player what they were going to do in the story. There were a couple of references to the previous scoop, with the recurring lawyer character being the obvious one but also the ridiculous Shaper way of breaking through Starlit Knight.

This was also where we introduced hex, your accomplice for this particular mission. To be bluntly honest, hex was a bit of a comfort character I made up. I've had the idea of a glitch witch stuck in my head from playing the game Beglitched in 2020, and has definitely been a bit of a gender thing for me since then! She's also in the unset that my local community are developing as a Shaper identity.

hex, glitch witch Whenever you cause an installed Runner card to become uninstalled, you may search your stack for another card with printed install cost 1c greater than the uninstalled card. Install it, paying all costs.

Look if you're going to give me the chance to write something that's at least kind of considered canon, I'm going to put my fun characters in. Especially as she could be there to help you during your exploration, to reassure and lower stress with jokes. Don't judge me.

I want to mention about a general tactic used within the writing, which is the build from lighthearted to ominous storytelling to make the ominous stuff hit harder. It's a pretty common tactic, but still seems important to mention - the introduction isn't just present so I can make a few silly jokes1, but to provide that important contrast.

Seraph's abode

This made up the main part of the game. When thinking about how to implement an exploration game, we thought about it in terms of stats, and focused everything around those. We went with three stats:

This section starts with a choice of door. The doors were designed to reflect the on-encounter effect of Seraph, with the chance to lose 3c, suffer two net damage (translated to losing an effort) or take a tag (translated to gaining two attention). Some people might argue that forcing a random, unknown penalty on the player at random is "bad design" or something - players could feel bad for losing something in a way that's technically in their control but without any reasonable way to decide - but it felt thematic as this is what finding an ice for the first time is like!

After this, players have the chance to explore Seraph's abode freely. Fern came up with six locations for the player to explore: the garden, the library, the sermon hall, the confessional, the quarters and the courtyard. Fae wrote a few bullet point ideas for each place, and both of us each wrote a description for each place - me writing a calm, almost positive one and Fern writing the horrible corrupted version. In a moment of madness, Fern also wrote a unique corrupted transition for every location, six in all - so the passage you see when you hit 10 attention (when the world starts to corrupt more obviously) changes based on where you were when it happened. I'm not going to comment on how Fern went about this (both from a writing style point of view and also a "are you okay Fern that's a lot of writing" point of view), maybe they will at some point.

This was a big part of the lighthearted to ominous change we discussed earlier - my descriptions are shown before attention reaches 10 and Fern's after that point! Interactions with hex (all written by me except for the Server Log joke which was Fern's stroke of genius) were gated to only be in before the attention hit 10. The interaction with the confessional booth AI differs whether it is before or after the attention shift - at higher attention levels you get a shorter interaction because the AI itself has become corrupted. You can't look at the flowers in the courtyard past attention 10 - they have been flooded out. This adds ✨replay value™✨, as you can look at places in different orders. Wow it's almost as if we planned this out or something??

The players are exploring for a reason in all of this: to find details of how Seraph acts. We hid three logs within the world for players to find, with logs always being displayed in the same order regardless of what order they found them in (finding a log just prints out the next log you haven't seen). The logs are found as follows:

Unlike in the Starlit Knight scoop, nothing is locked behind finding these logs. This is because we also hid a bunch of clues around the world which state the solution less obviously: things like the inscription on the well (which hints that the High Priest's Quarters are safe from Seraph), various bits about not moving if you're trapped by Seraph and a couple of instances of the "bright noisy shapes" that Seraph attacks you with dissipating in water.

The final fight, and the aftermath

The final fight is effectively a test on what you've seen, based on the content of the logs and various environmental bits mentioned. Each attack is based on one of Seraph's subroutines!

The final monologue from The Holo Man was a joint piece by Fern and I, with me writing the first pass and Fern improving it. They had the idea of making the Holo Man's voices reflect the people you've met! I will never get over the fact that I wrote the final line, "You can't trash a concept." because (to toot my own horn for once) it fucks.

Implementing the game

I'm not going to get into loads of details because the main effort here was @distributive's (Ams), but I'm going to tell you how we ported the game from Twine to Sahasrara.

The Sahasrara bot has a small YAML-based system for importing stories into it. This format is bespoke - it was made because it made the most sense at the time, with some consultation with me as a programming languages expert to make sure there was nothing that would cause too many problems. It was designed to be a fairly easy job to implement in Sahasrara itself, and has grown to include an incredible set of features such as delayed messages and coloured messaged thanks to Ams' continuous work on it.

Unfortunately, its design is very different to Twine's. Twine lets you put links to other passages anywhere within the body of a passage (including nested within conditionals), while Sahasrara provides conditional links only at the end of passages. Twine was similarly laissez-faire about mutable variables compared to Sahasrara. Twine also used different syntax to Sahasrara for various bits, including if-statements.

This was all fair enough, and a problem we were willing to accept with the first scoop. That first scoop was manually ported to Sahasrara by Ams and I. It was a fair amount of work - that game had 67 passages totalling 6.8k words - but it was possible to manually port, and it worked.

This scoop was 151 passages, totalling 17.8k words. We could not port it manually.

Fortunately, I have a background in compilers (and teach on a university module about them!) so thought "oh I could just build a compiler from Twine code to Sahasrara". Reader, she was too optimistic. Too optimistic.

It took two evenings of implementation work to get a compiler which did most of it. Ams cleaned up the rest and added delayed messages, colours and images, which took another two late nights and lead to a YAML file with more than 2000 lines. The result is stellar, so I'm glad she did it, but we definitely learned something about how scalable this solution is. I know some people were curious about how they could write their own fiction for Sahasrara, to which I say: you can, just write it with Sahasrara in mind rather than Twine. It's definitely worth it - the results when using Sahasrara look stunning.

Special thanks

Phew, we made it to the end! There was a lot of content there, but I hope you found it interesting and enlightening. Here's some quick thanks at the end, which effectively credits the team behind this:


  1. To confirm, this is still a big part of the reason the introduction exists.

#from-cohost #interactive fiction #netrunner #netrunner scoops #twine