SQLite Adventure

Nearly a decade ago, before the site formerly known as Twitter went to total ratshit, @edent published a choose-your-own-adventure game where Twitter was the game engine.

This was perfect nerd-sniping bait for my team at work. How far could you bend a common tool and use it to build a game? How small could a game engine be?

In response, my colleagues and I set about writing a game engine that could fit within in a single tweet. My attempt from 2015 is lost to the sands of time, now that I’m one employer and several laptops distant, but I was recently inspired to go back and give it another go. All I can remember from my first attempt was that I cheated (slightly) by storing all of the game data within a SQLite database, allowing me to build my game engine with a simple set of select statements.

Starting fresh, I was able to build a reasonable experience using 3 tables for game data and 3 select statements within a bash script as the game engine. The tables are arrange as in this diagram, centred around a page entry with multiple lines of descriptions and multiple choices hanging off each.

A database diagram illustrating the three tables used in sqlite-adventure - page, description & choice.

I’ve uploaded my code so far to my sqlite-adventure repo. Clone the repo to a *nix-ish environment and run the ./build.sh script to create the database and tables and fill them with entries. The game can then be played by running the ./page <number> command and following along with the (as yet unwritten) story.

A screenshot of the result of running the command <code>./page 1</code>

It’s at this point, that the code-golf began. The full-fat, unfettered, version of the script comes in at an unreasonably large 335 characters. That’s practically a novel according to Twitter’s old limits. My first step was to rename all tables and columns to single characters and to remove some of the nicer formatting in the command’s output. These two steps allowed me to reduce the file down to 122 characters.

#!/bin/bash

sqlite3 a <<< "select t from p where p = $1; select c from d where p = $1; select t, c from c where f = $1;"

That’s small enough to fit within a tweet, but not small enough to satisfy my code-golf urges. There’s still multiple occurrences of relatively long words like “select” and “where” which could be replaced by some single character variables for a naïve form of dictionary compression.

#!/bin/bash
s=select;f=from;w=where
sqlite3 a<<<"$s t $f p $w p=$1;$s c $f d $w p=$1;$s t,c $f c $w f=$1;"

With all three occurrences of “select”, “from”, and “where” replaced with single character variables and all unnecessary whitespace removed my “game engine” is now just 106 characters long. The user experience isn’t as nice as the pre-shrunk version, but it’s still passable.

A screenshot of the result of running the command <code>./p 1</code>

There are a couple of places the engine could be further minimised, but I’m happy to leave it here for now.

2023-11-23

Leave a comment