Librarian of Alexandria

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A protocol for writing RSS readers, heavily inspired by the maildir format.

The core idea of Lektor is that you separate out the typical operation of an RSS reader into two programs which can work concurrently over a specific directory. One program is called a fetcher, and its purpose is to read remote feeds (of any format) and write them into the lektordir format. The other program is called a viewer, and its purpose is to take the files inside the lektordir and view them.

I've got the full format specified elsewhere but the core idea is that you've got a specified directory called your lektordir, which in turn contains four directories: src, tmp, new, and cur. The src directory contains representations of feeds, new contains unread posts, and cur contains read posts. (The tmp directory is an explicit staging place: fetchers will create posts in there and then atomically move them to new, which means that it's impossible for a viewer to ever observe an incomplete post. Even if a fetcher crashes, it will only be able to leave garbage in tmp, and not in new.)

The representations of feeds and posts are themselves also directories, with files and file contents standing in for a key-value structure. That means a given feed is represented by a directory which contains at least an id (its URI) a name (its human-readable name), and a post is a directory which contains at least an id (its URI), a title (its human-readable name), a content file (which is its content represented as HTML), and a feed (a symlink to the feed that produced it.) In both cases, there are other optional files, and also ways of representing fetcher- or viewer-specific metadata.

The use of directories means that fetchers and viewers don't even need a specific data serialization or deserialization format: unlike maildir, you don't even need to “parse” the format of individual entries. This means fetchers need only a bare minimum of functionality in order to write feeds—I had test programs which used basic shell scripts that wouldn't have been able to safely serialize JSON, but were able to write this format trivially.

My intention is not just to design the format—which has already been pretty thoroughly specified, albeit in beta format and without having been subjected to much testing—but also to write the tools needed to write an RSS and maybe ActivityPub reader on top of this format.

Why write it? Well, I wanted to write an RSS reader, because none of the existing ones are exactly what I want, and this seemed like a good way of splitting up the implementation into bite-sized chunks.

There are some interesting features you get out of separating out the fetcher and viewer operation. For one, fetchers become ridiculously simple: they don't even need to be full services, even, they can just be cron jobs which hit an endpoint, grab some data, and toss it into the lektordir. Instead of a reader which needs to support multiple simultaneous versions (e.g. Atom, various versions of RSS, newer ActivityStreams-based formats) you can have a separate fetcher for each. For that matter, you can have fetchers which don't strictly correspond to a real “feed”: for example, you can have one which uses a weather API to include “posts” that are just sporadic weather updates, or one which chunks pieces of your system log and puts one in your feed every day to give you status updates, or whatnot.

Separating out viewers means that you can now have multiple views on the same data as well. Maybe one viewer only cares about webcomics, so you can pull it up and read webcomic pages but let it omit blog posts. Another gives you a digest of headlines and emails them to you, leaving them unread (but of course omits anything you happen to have read during the day.) Another does nothing but pop up a message if you let unread posts pile up too long. Hell, you could have one that takes your combined posts and… puts them together into an RSS feed. Why not?

The cool thing about lektordir to me is that it lowers the barrier to entry to writing RSS-reader-like applications. It takes the parts and splits them behind a well-defined interface. But there's a lot of cool stuff that you get from trying to apply a one-thing-well philosophy to problems like this!

Why the name? It's for reading, and lektor means “reader” in several languages. I'll probably change the name at some point, though, because there's also a plain-text CMS called Lektor.

#backburner #software #web #tool

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A video game about driving around an inscrutable world.

There's not much more to it: just a world, with a barebones (and probably slightly inscrutable) set of objective that ask you to go from unexplained place to unexplained place. Unlike the previous game ideas I've described like Albulaan and Tales, I didn't intend for this to be procedurally generated: just hand-created grand and unexplained places.

Why write it? This is actually a slightly newer incarnation of an older small idea I had: a walking simulator built around a series of bizarre atmospheric places, filled with surrealist imagery you might find in something like the Codex Seraphinianus or Le Garage hermétique. I like the idea of driving around even more, though, in part because I just enjoy games about driving, and in part because the idea of having somewhat inscrutable signage that still reads as signage sounds like a lot of fun.

Also it would be good Blender practice for me.

Why the name? I guess this is the post where having an obligatory “name explanation” section in every post becomes really really unnecessary, huh?

#backburner #videogame

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A microtonal music tracker.

A tracker is a piece of software for writing music in an almost spreadsheet-like way: trackers give you tables of notes with other pieces of metadata next to them, like volume or other effects. Writing in a tracker can often involve writing small pieces of repeating music that get assembled together with relatively few tracks using relatively few instruments. It's no surprise that trackers are often used for writing chiptunes!

Microtonal music is music that uses a non-twelve-note scale. The specifics of why and how are complicated (and I've written about them elsewhere) but the short handwavey explanation is this: that the reason we use twelve notes per octave on most of the instruments you find in the Western world is that, when we split the octave into twelve equal or near-equal parts, we get notes which often sound good together, but that doesn't mean that's the only way of carving up the space of possible sounds in a way that sounds good together, though. We settled on twelve for lots of historical reasons, but there are plenty of other approaches that we could have taken that still sound good, although different!

So my goal for Hypsibius was to write a tracker that didn't hard-code the assumption that every note was a note on our traditional 12-note scale. Instead, I wanted the user to be able create (and export or import) scales which describe which notes were available to a given composition by specifying them in terms of cents, allowing a composition to have access to either more or fewer possible notes. For that matter, I wanted users to be able to specify how those scales repeat: some systems of tuning don't repeat every octave, but use larger intervals, so a user might want to use the Bohlen-Pierce scale which repeats not every octave but every tritave.

Once they had specified a scale, the user could then use that scale to write music, which could be played and exported. My plan was, at least at first, to stick to a relatively small number of waveforms—sine and square and saw waves—with the intention that most of the music created by Hypsibius would be chiptunes-like. Eventually I might add the ability to play other samples or soundfonts, but to begin with Hypsibius was going to be a pretty barebones affair: the interesting part isn't the instruments, but rather the ability to choose your palette before composing music.

Why write it? I've written before about microtonal tuning because it's a perennial fascination of mine. I love microtonal compositions, but on the other hand, I've found it's also somewhat hard for a casual and relatively inexperienced musician like myself to experiment with. Microtonal instruments are rare and software that supports microtonal music tends to be fiddly and rather hard to get familiar with: you often need to use explicit note-bending, since the MIDI format that underlies much of digital music hard-codes assumptions about 12-note scales.

On the other hand, one kind of music software that's straightforward, usually inexpensive, and requires no special equipment is the music tracker: there are plenty of open-source trackers out there, and some simple ones are even embedded in barebones software packages like the Pico-8 fantasy console. These are often ridiculously easy to get started with, with the major hurdle being their barebones, number-heavy interfaces, but those interfaces also make them even easier to create in the first place!

So that's why I figured I'd put them both together: trackers, being simple to make and use, could be a way of making microtonal music much more accessible. In particular, the idea of putting together a tracker which can be parameterized by arbitrary tunings simply by giving it a list of frequences in cents would allow a musician to experiment with wildly unusual tunings in a trivial way.

Why the name? Hypsibius is the genus of tardigrades, also known as “water bears”. Tardigrades are microscopic eight-legged creatures found all around the world, but are also famously resilient to wildly extreme conditions, and have been found in a stunning range of temperatures and environments. Many people find them alien and fascinating, and I also find microtonal music to be alien and fascinating, hence the association. They'd make a great logo or mascot, too.

(I was actually going to call them “extremophiles” in this description, but I discovered while writing this post that that's incorrect: tardigrades can survive in extreme conditions but, unlike true extremophiles, they do not seek them out or thrive in them.)

#backburner #software #music

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A space opera tabletop game.

The setting was loosely-specified: galaxy-spanning civilizations, faster-than-light travel, somewhere between science fiction and science fantasy. One stipulated constant, though, was the existence of the tentatively-named Emissaries of Guenashk: a sort of philosophical order of politically powerful warrior-monks whose job was to go out into the galaxy and be useful to the people. Crucially (and unlike the fictional pseudo-religious order that forms part of their obvious inspiration) they don't actually have any jursdiction to make sweeping judgments or pursue criminals of their own volition, but rather must be specifically asked to intercede in affairs and given explicit limits to how they can do so: if not asked, they must otherwise limit themselves to talking. Emissaries are often well-trained and have a wealth of knowledge and expertise, so in practice they often are asked to help in various situations, but their role can differ wildly, and overstepping their bounds is considered a major violation and grounds for expulsion from the order.

The players are therefore a group of Emissaries, with all that entails. That's why the events of a session are usually a situation where Emissaries are asked to intercede. Importantly, the design of both characters and situations means that non-violent techniques and situations are given just as much narrative weight and mechanical import as violent ones: a given player might stick entirely to the negotiating table, doing as much as they can to avoid pulling out the weapons, and a frank heart-to-heart with a character might be as powerful as a violent conflict with weapons drawn.

My original draft was more or less a science fiction rework of Dogs in the Vineyard, using a similar system of raises and sees to handle conflict resolution. Unlike Dogs, it had rather more guided character creation: each character was built of two halves (using a system inspired by Danger Patrol) where one half represented the character's origin and the other half represented their role: each half contributed skills and objects and relationships that could be drawn on later. That means that instead of simply choosing a class or playbook, you would always play a combination of two things, both equally important to you: you could be a Scientist who hails from a Lunar Base or an Ambassador from a Core World, but you could also swap those things and be a Scientist from a Core World or an Ambassador from a Lunar Base.

I've gradually moved away from the Dogs heritage over time, but there are some features of it I want to make sure I retain for this sort of game. In particular, the way that the Dogs conflict resolution encourages you to stick to less extreme conflicts until absolutely necessary, mechanically encouraging that reaching for the guns is usually the last resort, is integral to the kind of game I wanted to build. I was also working on mechanics that handled both organizations and ships in a more nuanced way, treating them as entities that can bring dice to bear in conflicts but also can take fallout themselves if things go poorly, and I had been moving towards a little bit more guidance than you usually get with a Dogs fight (which can be wonderfully flexible, but also daunting if you don't have ideas) but I'm going to have to do a careful reconsideration of the rules once I return to this project.

Why write it? I don't actually know if there's a game that I think is a perfect fit for the kind of space opera I was going for! In particular, I want to capture the kind of slower political scifi that you might find in 90's-era Star Trek or Babylon 5. I want players to be able to do elaborate political maneuvers as readily as sneaking or fighting. While there are definite Jedi similarities to the titular Guenashki order, the differences are just as important: they don't get powers or special supernatural guidance or even any specific authority, which means trying to rush in with heroic violence will often put them at odds with their very order. (Perhaps the role of the Guenashki becomes clearer if you think of their strict rules of engagement as closer to a kind of Prime Directive than anything in the Jedi code.)

Some of the various existing space opera games on my radar are Ironsworn Starforged, Scum and Villainy, and of course Lasers & Feelings. While I like all of these, none of them are quite suitable for the kind of political scifi I wanted: Ironsworn and Scum & Villainy, despite the more Star Wars set dressing, tend to lean towards Firefly or Cowboy Bebop in terms of what you actually do, and Lasers & Feelings is rather minimalist and ends up (at least in my experience) being a little bit slapstick. You could play a political maneuvering game in Lasers & Feelings, but none of the rules guide you to do so.

(There are also scifi games like Starfinder or the officially-licensed Star Wars RPGs, but I'm also omitting them here because they're so overtly combat-focused. Trying to play a political game using Starfinder is like trying to run a rom-com game in Monopoly: I suppose you could, but the rules wouldn't have your back at all.)

So Guenashk was my attempt at trying to build a game where you could play as TNG-era Picard. I didn't want it to prevent people from reaching towards aggressive negotiations, but my primary goal was that people should be able to create a character who never once uses a gun and that's fine. I still think that's a valuable sort of game.

Why the name? This was actually a name I used for an early draft of notes about Tales, but I decided it was a better fit for this project. The word Guenashk—which I originally wrote as /ɣʷeˈnašk/ in my notes—is nonsense.

#backburner #tabletop

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A programming language designed as a tiny experiment: what if a dynamic language were built to emulate the affordances of a static language with typeclasses or traits?

In practice, many dynamic languages are designed around storing data either in a handful of basic data structures—usually lists and associative arrays, sometimes adding a handful of others like sets—and then more sophisticated data modeling is done using some kind of object system. There are exceptions, of course—Erlang, for example, omits the object system entirely and sticks to simple data modeling plus processes—but it's definitely true of most of the commonly-used dynamic languages like Python and Ruby and JavaScript and Lua.

The experiment in Petri is that it uses a dynamic version of algebraic data types—which it calls tags, borrowing loosely from the Tulip language—and then provides a feature which allows functions to be implicitly looked up based on the tag. For example, the following program—using a syntax where keywords are marked explicitly with @1—creates a tag called Person, then defines how to print it to the screen using the Repr class:

@tag Person {name, age, pets}
@impl Repr(Person) {
  @fn repr(p) {
    "Person({p.name}, {p.age}, {p.pets})"
  }
}

We can now write a function which creates a Person and prints a representation of that person to the screen:

@fn main() {
  person := Person {name: "Ari", age: 33, pets: []};
  print(Repr::repr(person))
}

Underneath the hood, Repr is a map from tags to bundles of functions, so when we call Repr::repr, it'll look up the tag of its argument and find the relevant implementations of the functions, and then call that with the relevant parameter. In practice, we can also “open” any module-like thing—i.e. anything where we'd use :: to access a member—so we can also @open Repr in the root scope and then call repr instead of Repr::repr. (In practice, the prelude will pre-open several commonly-used classes, and also provide syntactic sugar for classes like Eq and Add.)

There's a little bit more practical sophistication to the typeclass mechanism, as well. For example, Eq is a typeclass with two “type” parameters, and it also provides a default implementation. It also does run-time introspection to find out whether a class has an implementation for two specific values! Also notice that, in the definition of Eq::eq, the parameters are capital letters, which reference the stand-in tag names that are parameters to the class Eq: this is how we indicate which argument tags to use to look up instances. It's possible to have methods that take extra parameters which are ignored for the purposes of instance lookup, in which case those parameters can be written as _.

@class Eq(A, B) {
  @fn eq(A, B);
  @default eq(a, b) {
    @if implemented(Eq(b, a)) {
      return Eq::eq(b, a)
    }
    False
  }
}

This also doesn't go over some other useful features for writing actual programs (e.g. a basic namespace mechanism, how file imports work, what other parts of the stdlib look like) but it gets at the core of the idea: a language that builds a dynamic version that tries to replicate the affordances provided by features like Haskell's typeclasses or Rust's traits.

Why write it? To be totally clear, Petri is more of a UI experiment than any kind of programming language innovation! After all, there's nothing new semantically in this idea: it's just multimethods. In terms of what you can express, there's almost nothing you get that's not already present in CLOS. The thing I'm interested in trying with Petri is more about affordances, figuring out what programs look like when these features are expressed in this way. After all, Python and Ruby and (modern) JavaScript are all languages with very similar basic features—dynamic types, object systems which provide sugar over hashtables of values and functions, some simple built-in data structures, and so forth—but programs in all three can look radically different because of the specific way those low-level building-blocks are combined. What if we took a tack that, while not unique, was still several steps outside of the Python/Ruby/JavaScript world?

I've got a background in both static and dynamic languages: I used to program in a lot of Python and Scheme, but my first two jobs used primarily Haskell and eventually smatterings of Rust, and more recently I've been working on Ruby-related infrastructure at Stripe, which means I spend most of my work time these days in a dynamic language with a static type system over top of it. I'm always interested in things that can bring affordances from one into the other, whether that means bringing static features to dynamic languages (as here) or dynamic features to static languages.

Admittedly, I doubt I'd actually use this language for much, but I still love tiny experimental programming languages. It'd be fun to see how far it could be pushed in practice, to see what at least medium-sized example programs look like in something like Petri.

Why the name? It's an miniature experiment, and miniature experiments are often found in Petri dishes.

#backburner #software #language #experimental


  1. This is also a feature borrowed from Tulip, and one that I think is very cool in general but especially for languages which are still growing. Modern languages often have a need to expand their vocabulary of keywords, which means they sometimes reserve a set keywords in case they're ever needed later, but even still languages might need to either context-sensitive keywords to introduce keywords without breaking existing programs or break backwards-compatibility to introduce new keywords which weren't previously reserved. None of these are inherently bad choices, to be clear, but I like the Tulip approach: if all keywords are in a particular namespace, then there's never any ambiguity or chance that a future revision will break your program since your variable is now reserved. Admittedly, it also is best when there's a syntax with a relatively low number of keywords, like the Haskell style. If you used this same approach for something like SQL, your program would be incredibly noisy with the sheer number of @ characters!

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A series of linked short stories about the starship Pausanias (named after the ancient geographer), a ship on a mission of research and peace, not unlike the sort of missions undertaken in other well-known cultural touchstones. Unfortunately for the crew of the Pausanias, one of the key magical technologies present in that other touchstone is something which is intractably difficult if not impossible to build in an appropriately general way: namely, automated translation.

Consequently, the plots of these stories would tend to get tripped up in the real-world difficulties of language and translation. These stories would explicitly delve into the vagaries and nuances of language that tend to get ignored when they appear in popular science fiction stories: considerations of dialect and language change and pragmatics and various other ways that language intersects with people and culture. Language is messy and multifaceted and strange and wonderful, and the stories should reflect that.

As an important side-note: I explicitly don't want this to be a work that prominently features conlangs as a major focus. There's a specific kind of science fiction and fantasy—obviously deeply inspired by the languages that J.R.R. Tolkien featured in The Hobbit and The Lord of the Rings—that features fictional but fully-developed languages prominently, and while I'm not inherently opposed to that as a practice, I'm not terribly interested in writing that kind of story myself. I don't want a reader to have to trudge through paragraphs of what to them are nonsense syllables to get to the story. Instead, I want the story to be about people and how their languages interact with who they are, and that might mean including a word or two of a fictional language, but it doesn't mean building an entire grammatical edifice to serve the half-dozen words which appear in one of the stories.

My plan was to write a handful of these and release them on a regular cadence before collecting them together. I've still got notes about the characters and the setting, and the biggest reason I've put it on the backburner is that I've been working on other fiction projects. Some day, I might start serializing the relevant stories on this very blog!

Why write it? Not surprisingly, given my own background in linguistics, many of my favorite science fiction stories are about language in some respect, like Samuel Delany's Babel-17 or Ted Chiang's Story of your Life or China Miéville's Embasssytown. It's not surprising that I'd want to try my hand at language-related science fiction.

It's surprisingly common for science fiction to gesture at language as an area of focus without actually delving deep into it. Star Trek is an obvious example here: they even once hired the linguist Mark Okrand to fill out grammatical details of the Klingon language, but with a few exceptions (like the famous episode Darmok in Star Trek: The Next Generation) they tend to gloss over language as a concern in most episodes. A perhaps more egregious example is the Stargate franchise: the premise of the movie Stargate was that a group of humans on the other side of a galaxy-spanning wormhole spoke an unfamiliar language, and it took a linguist to discern that it was descended from the Egyptian language as spoken on earth. When they used that movie as the basis for a related television series, they quickly dispensed with most of that premise: instead, the linguist character is really only present for deciphering mysterious ancient texts, since every planet they visit seems to be populated by English-speakers instead.

So as a person who cares deeply about language, I've always wanted to take the space opera format and use it to investigate language in the exact way that traditional space operas don't. I'd try to play in the space between works like Embassytown—which often focus on wild science-fiction premises about language—and Star Trek—which largely gloss over it. That is to say: I don't plan to write stories about the very limits of what language might be, like Story of your Life and Babel-17 did, nor do I want language to take the sidelines like it does in traditional space operas: rather, I want to reflect the ways that languages as we know them in the real world can be wild by transposing them to a fantastic setting, taking the space opera format and using it to grapple with the many things that real-world languages do. To put it pithily: why do the Klingons have only one language, to say nothing of dialect? Why have we never heard a Klingon code-switch? And after a generation of close contact with other languages, how does Klingon change1?

From another direction, one thing I've always found appealing—especially as a person who usually struggles with writing long-form prose—is the idea of writing explicitly episodic fiction, like short stories on a theme. To some degree, that's the same thing I'm doing in writing these backburner-project posts: forcing myself to work in small chunks on a schedule. It's also worth noting that historically serials have been a very common format for fiction even though they've fallen out of fashion a little bit. Doing a short serial—maybe six or eight parts, in total—would be a fun way of telling these stories, especially so that they don't necessarily outstay their welcome.

Why the name? This title is a working title, one I will dispense with as soon as I come up with a better one. Still, this working title is because the project is inspired by space opera like Star Trek, and it would at times involve both morphology and syntax, although those are admittedly a much smaller part of the focus than other aspects of language.

#backburner #fiction


  1. Okay, this is one where I should admit that Star Trek has addressed this question, at least a little bit. If you've watched Star Trek: Deep Space 9, you might be familiar with a drink called raktajino, which is enjoyed by many of the main cast members. Mark Okrand has asserted that this word is a borrowed compound from English and indirectly from Italian, since the drink is an adaptation of a traditional Klingon drink called ra'taj but prepared like a cappuccino.

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? An authoring tool for simplistic shape grammars intended for generative art.

A shape grammar is a tool for building two-dimensional objects. Like all grammars, you can think of a shape grammar as either a recognizer of a language or as a generator of a language, and for our purposes it makes more sense to think of them in the latter sense. Also like other grammars, it consists of a set of rules, each of which has a left-hand side and a right-hand side: generating a language from a grammar is a process of finding rules whose left-hand side matches some part of an intermediate state, and then replacing that part with whatever is specified by the right-hand side. Similarly, some components are considered 'non-terminals', which are symbols that always appear on the left-hand side of rules and are meant to be replaced, while others are 'terminals' which form the final output: once a state contains no non-terminals, we can say it has been fully generated by the grammar.

The biggest distinction between a shape grammar and a traditional grammar, then, is that a shape grammar operates over, well, shapes. In the case of Palladio, the intention was for it to operate over sprites on a square grid. As an example, consider a grammar defined by these three rules:

A simple three-rule shape grammar

These rules are very simple: when we see a symbol on the left of an arrow, it means we try to find that symbol and replace it with whatever is on the right-hand side. That means if we see a black circle, we replace it with the symbols on the right: in this case, a specific configuration of a black square and two red circles. Similarly, when we see a red circle, we can choose one of the two possible rules that applies here: either we can replace it with a black square, or we can replace it with a light blue square.

This grammar is non-deterministic, but generates a very small number of possible outputs: rule A will produce one terminal and two non-terminals, and we can non-determinstically apply rules B or C to the resulting non-terminals. In fact, here we can show all four possible outputs along with the rules we apply to get them:

The four possible outputs of the above shape grammar

That said, it's not hard to write grammars which produce infinite numbers of possible outputs. This grammar is not terribly interesting, but it does produce an infinite number of possible outputs: in particular, it produces an infinite number of vertical stacks of black squares.

A simple two-rule shape grammar that includes a rule which can apply recursively

We can't enumerate every possible output here, but you get the idea:

The first handful of outputs of the above shape grammar

My goal with Palladio was to write an authoring environment for grammars like these, with the specific intention of using them to produce tile-based pixel art pieces. This means not just providing the ability to create and edit rules like these, but with things like live outputs—possibly with a fixed random seed, for stability, and possibly with a large set of seeds, to see wide varieties—and maybe analysis of the output, alongside the ability to export specific results but also the data used to create these.

Why write it? For fun and experimentation! I don't just love making art, I love making tools that make art, and my favorite way to do so is using grammars. Grammars act like tiny constrained programs over some value domain, and you can still bring a very human touch to writing a grammar that produces a specific kind of output.

Doing a tool to support this that's both graphical and constrained to grids is a good way to make it easy to get started with. My plan was even to build tools to spin up Twitter bots as quickly as possible, too, so someone could design a grammar and then with minimal fuss start showing off the output of that grammar on the internet.

My original version (which I admittedly didn't get terribly far with) was written as a desktop app (in Rust and GTK) but I suspect that for the purposes of making it easy to use I'd probably reimplement it to have a web-based version as well, making it easy to open on any device. It'd be nice to also build simple-to-use libraries that can ingest the grammars described, as well, so they can be embedded in other applications like video games or art projects.

Why the name? After the architect Andrea Palladio, but specifically because one of the famous early papers about shape grammars in architecture was Stiny & Mitchell's 1979 paper The Palladian Grammar. Palladio was famously schematic in terms of how he designed and constructed houses, so Stiny & Mitchell were able to take those rules and turn them into mechanized rules which can express the set of possible villas that Palladio might have designed. For a more recent and accessible treatment on the subject, you might look at Possible Palladian Villas (Plus a Few Instructively Impossible Ones) by Freedman & Hersey.

#backburner #software #tool #procedural

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A video game that's been kicking around my head for ages: a roguelite loosely inspired by a childhood favorite of mine, Yoda Stories.

In effect, Tales is a roguelike in the classic vein, albeit with a slightly greater focus on non-violent NPC interaction. Each “run” happens in a different randomly-generated area and is built around a randomly generated task, but that task is gated by a number of smaller intermediate tasks, which might range from fights to sneaking to exploring to simple conversation with NPCs. The tree of objectives is also randomly generated, so the world needs to be explored a bit to fully grasp what's needed: you may need to acquire a replacement wheel for a vehicle, and that wheel may be a gift in exchange for getting rid of some bandits, but discovering both of those requires traversing the world a bit.

By and large I think the ideas described above aren't too interesting: a game like this would mostly succeed or fail based on world generation and the implementation of basic mechanics like combat. My mental image here for the combat is that it would be a simplistic real-time top-down brawler, smooth but not too deep or challenging. I'd want a small variety of weapons or abilities, but not to the point that you'd get the sheer combat depth of something like Hades, mostly because I'm not interested in that kind of depth myself. That simple fluid combat would be augmented with a simple conversation mechanic and a set of world generation processes which could create different kinds of worlds for different runs: dense multi-layered cities, sparsely-populated grasslands, networks of islands with ferries, and so forth.

Beyond the relatively straightforward mechanics, though, there is one interesting design problem I want to tackle with Tales: how to build a mechanic that allows for character progression without necessarily having an overarching difficulty curve. I'd like the level of difficulty of each run to stay relatively static: that is, the game itself should not get harder as you play more unless the player explicitly moves a difficulty slider. At the same time, I'd like to allow for players to gradually gain techniques and talents and customize a character. My current idea is that a character should have a fixed number of points, and before each run a player would be allowed to freely move points around, both into default abilities (like “strength”) and into new abilities which you pick up as you play the game (like proficiency with unusual weapons or the ability to use different non-standard techniques like fast-talking or hacking). Over time, the player can specialize in radically different ways of tackling runs, but without the straightforward consequences of leveling or getting better gear: they are not straightforwardly “stronger”, but rather have sacrificed some general abilities for more specific or unusual abilities. Ideally—although this would require some subtle tuning—this approach would allow a player to explicitly choose to tackle more difficult runs over time by specializing their character with more specific abilities that offer higher mechanical complexity, but that difficulty isn'ted baked-in to the assumptions of the game like it would be for other RPG-like games.

Why write it? There's something weirdly appealing about Yoda Stories. I've seen multiple other people—including Zach Barth of Zachtronics fame, as part of his article on reverse-engineering the graphics of the game—talk about how they remember the game fondly despite it being poorly-reviewed and, quite frankly, bad.

As I mentioned above, the success of a game like Tales would largely be dictated by world generation and basic mechanics. It's worth noting that Yoda Stories failed on both these counts. It had mediocre world-generation: it was a randomly-assembled quilt of pre-created sections, but those sections were assembled mostly at random, which meant there was often no indication you'd reached the end of the world: you'd simply be at the edge of a screen with plain desert and yet magically wouldn't be able to move. Even moreso, it had hilariously bad combat: it was a game with real-time movement, but movement was instantaneous on a square grid, so enemies could pop in and out of existence next to you as you swung your lightsaber.

That said, despite the problems, there was something about Yoda Stories that was still inspirational in a way that the other roguelike-ish games weren't for me. I do love Nethack, but even when first playing it I wasn't immediately compelled to make another. My suspicion is that the world of Nethack is a dungeon, but the world of Yoda Stories at least gestured at the idea of being a world where people lived, with little cities and farms and cabins and so forth. It's also restrained: one feature of Yoda Stories was that the difficulty was built around 'how long do you expect this game to take?' where the options ranged from 15 minutes to an hour, since the goal of Yoda Stories was to create a casual game more like Minesweeper than traditional roguelikes. I think this is still a worthy design goal: more games should be small and focused, with a gentle learning curve and no expectation that you'll play them forever. All this together means that a game which takes the things I like from Yoda Stories, but smooths out the roughest edges and plays up the most interesting strengths, still feels like a game I'd want to play.

Why the name? The name Tales is just a stand-in name. At one point, I was referring to it (in a wild Incal-inspired science fiction incarnation) as The Emissaries of Guenashk, but I later on borrowed that name for a tabletop project which I'm going to write about later this month.

#backburner #videogame #procedural

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A modern, debuggable, interactive PostScript implementation.

The first part is boring, and in fact doesn't really fit my criteria for these posts, because “just implement PostScript well” is not a super interesting project idea. But it's really worth calling out that many of the existing implementations—not surprisingly—really aren't designed for human beings. For example, if I accidentally pop too many elements in GhostScript, I get an informative but not terribly well-designed error like so:

GS>pop
Error: /stackunderflow in --pop--
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   % removed for space
Dictionary stack:
   --dict:729/1123(ro)(G)--   --dict:0/20(G)--   --dict:75/200(L)--
Current allocation mode is local

It's not hard to improve on the ergonomics here, since something like GhostScript isn't really designed for human ergonomics anyway!

But there's more to Endsay that I wanted to get around to, which is also designing an interactive debugger for PostScript: to begin with, I want step-by-step execution and breakpoints in code, so I can walk through the process of watching my document being drawn on the screen. But I think we can even do better: for one, supporting some amount of rewinding, so we can rewind the state of the world, undraw things that we have drawn. Even further, I suspect we can set breakpoints based on graphical content, as well: for example, selecting an area of the page to be rendered and then requesting that we break whenever that area gets drawn, or choosing a color and requesting that we break when that color is used. Something that interests me about this project is figuring out the right way to build and expose those primitives!

Why write it? The PostScript language is a weird beast, and in some ways it's the complete opposite of the languages I've pitched in these backburner posts: rather than using a non-Turing-complete language for a task conventionally understood as the purview of executable logic like in Parley it's a Turing-complete language for a format conventionally understood to be declarative. PostScript is a dynamically-typed stack-based language, roughly like Forth, that was originally created for printers: rather than rendering expensive raster versions of your document on your computer, you could produce a simple, terse program which would produce your document, send that program to the printer, and let it handle the rendering.

There was a very very narrow slice of history where this actually made sense—where printers were good enough to need bigger raster files than computers could comfortably generate and send, for example—and at no point was PostScript really intended for human writing. PostScript lives on in more restricted forms: for example, the EPS format is PostScript under the hood, while the PDF format was effectively designed as pre-executed PostScript.

That said, you absolutely can, as a human being, write PostScript by hand. I happen to like writing PostScript a lot. I wouldn't be interested in writing a PostScript implementation for practical rendering of images—those exist already, and are fine—but I'd love to write an implementation that's more user-friendly, even if the user is just me!

Plus, building debugging tools for creating 2D graphics sounds like a fascinating design question. I'd love to see what turns out to be useful and how best to expose these features!

Why the name? English is one of many languages to have had strong “linguistic purist” movements: that is to say, efforts to remove foreign influences by removing borrowed words and replacing them with native words or compounds. Thankfully, these efforts have mostly disappeared, despite the best efforts of tedious linguistic reactionaries like George Orwell.

While I by and large think that linguistic purism is an abysmally stupid endeavour, I nonetheless do appreicate the creative and artistic applications of linguistic purism. Consequently, I do enjoy reading about some of the alternative words once proposed as “pure” equivalents of foreign borrowings, just because they sound so whimsical and entertaining: for example, using starlore instead of “astronomy”, bendsome instead of “flexible”, and, of course, endsay instead of “postscript”.

#backburner #software #language

This is an entry from a list of projects I hope to some day finish. Return to the backburnered projects index.

What is it? A “tabletop” game designed to be played asynchronously and slowly.

The premise is this: as a player, your focus is on a single military unit in a vast and probably doomed war. Within that unit, you have a secondary even smaller focus: a single person, perhaps a soldier, perhaps a medic, perhaps a strategist, perhaps a random civilian who happened to tag along. As you play, you sometimes make decisions for the military unit: where to move, whether to retreat, when to find supplies, when to tough it out. You also make decisions and tell stories from the point of view of your focus: as the unit toughs it out, how does the focus feel about it?

Each player in a game of The Last Alliance of Men and Elves has their own distinct military unit and their own focus character within it, and as the game progresses, the unit-level actions affect one another, helping to shape the trajectory of the overall war before the final showdown.

There's a catch, though, that distinguishes it from many other tabletop games: it's designed to be played slowly, asynchronously, over a chat system like Discord. The intention is that each player would take only one turn every day or so—maybe more or maybe less, depending on the group's desire for the cadence of the game—and there's no specific requirement that players take turns in order.

One design goal was for this to be playable by people with busy lives who are rarely able to get to one place—physical or otherwise—to play tabletop games together. People whose schedules differ wildly could still contribute to a game of Last Alliance. This enforced a lot of interesting consequences to the design. I also planned to write a Discord bot to help facilitate games, a bot which could help remember details (e.g. current amounts of resources) and also do prompting (e.g. telling you when you last checked in and suggesting that you take another turn.)

Why write it? I've actually talked about this one before in more depth!. The COVID-19 pandemic definitely brought it into focus as an interesting idea, and if I were good at prioritizing projects I would have completed it in early 2020 so we could playtest it throughout the early days of the pandemic. That said, it predated the pandemic by quite a while: the post linked to is from January 2020, and I had been considering some of the related ideas back in 2019 even.

I think the ideas are interesting! I like the idea of asychronous play in general, even in video games, and I think several of the ideas pitched by Ian Bogost in his 2004 paper Asynchronous Multiplay are still compelling even when they have been implemented in the most heinous possible way by games like Farmville. One design goal of The Last Alliance of Men and Elves was to backport ideas from asynchronous multiplay in a video game context into a tabletop context, faciliated by chat systems.

I also just want to see what it's like to play this kind of game! I like the idea of playing a game I check in on every day or so, where the game itself is built around that level of interaction.

On a side-note, I also want to mention that the fantasy writing system I created here was originally intended as a way of creating interesting-looking backgrounds and design details for a draft of this game.

Why the name? The default milieu was intended to be loosely inspired by both stories from J.R.R. Tolkien's The Silmarillion as well as Glen Cook's The Black Company, and so the name was taken from Tolkien's narration. It was very much a working title, but I do like long and elaborate names for games and fiction, so I'll probably try to come up with a similar but more distinctive title whenever I return to the project.

#backburner #tabletop