Adam Johnson

Home | Blog | Projects

Making My Own Black Mirror Bandersnatch Easter Egg

2019-01-24

Lion

The TV program Black Mirror released an interactive choose-your-own-adventure film on Netflix called Bandersnatch over the holiday period. I enjoyed playing through it and finding the various endings, especially since I recently played The Stanley Parable which is in the same genre but with more humour. Bandersnatch has many endings and easter eggs, so naturally there’s a whole subreddit dedicated to tracking them down. The most impressive is an embedded Spectrum tape noise containing a QR code that leads to a real ZX Spectrum game made in 2018 by developer Matt Wescott.

Netflix are running an extensive advertising campaign for Bandersnatch across London, with several different adverts all featuring pseudocode. I’ve spotted them on billboards, buses, and even on the stairs of hipster central station Shoreditch High Street:

Pseudocode on stairs at Shoreditch High Street Station

The code looks like Python, although it won’t actually run as it’s not valid syntax. However, this got me looking at the packages it seems to import.

bandersnatch is a tool by the Python Packaging Authority, for running a mirror of the Python Package Index (PyPI). The name is not based on the Black Mirror episode, the package pre-dates it. Instead, both take the name from Lewis Carroll’s fictional monster, featured in Through the Looking Glass.

None of the other names featured in the adverts - open_time_path, commuter, etc. - seem to exist as open source packages on PyPI. Except, now, blackmirror, which I just created as my own unofficial easter egg.

If you now run pip install blackmirror, you’ll get a command blackmirror, which has one sub-command blackmirror bandersnatch. Running this presents you with a timed choice screen that imitates those in the interactive film:

Running Blackmirror Bandersnatch

Depending on your choice, a different web page will open.

I wrote it in a few hours using a bunch of neat tools.

The CLI command parsing is done with argparse from Python’s standard library. Although alternatives exist like docopt, I’ve always found argparse pretty easy to use.

The rendering on screen is down with curses, which is quite a thin wrapper around the curses C library. I hadn’t had a chance to use it before so this was an educational exercise. It’s nice that it’s built-in and complete, but it’s not really “Pythonic” as the function names are still typically obscure abbreviated C names, such as stdscr.getch (standard screen/whole window, get character). I wrote the minimum of disposable code here, but if I were doing anything more complicated, like a full choose-your-own-adventure, wrapping curses beneath a comprehensible higher level API would be my first priority.

Lastly, in order to get the image of the Bandersnatch from Netflix into a terminal-renderable format, I I extracted it from the marketing material with GIMP:

Netflix Bandersnatch Preview Netflix Bandersnatch in GIMP

…and then used a short node script using the image-to-ascii package:

Converting the Bandersnatch image with image-to-ascii

This is an excellent library and it has a bunch of options to make it really easy to convert an image to the ASCII art you want.

Overall, this was an enjoyable and educational way to spend a morning. Code is on GitHub if you want to take a look, however I don’t expect to work on it any further. Enjoy!


Tags: python

Subscribe to my weekly digest email