Projects

Things I build for the love of it.

Multiforum

Personal project

2019 – Present

Multiforum started as a reaction to Reddit, specifically to two questions that come up constantly: Why was I downvoted? And why was my post removed? So I’ve spent the years since 2019 building an open-source community platform where these issues are addressed transparently. There are no downvotes; instead, a thumbs-down opens a text box where feedback has to be expressed in words instead of as a number. Voting happens only within an individual forum, so the people whose opinions shape a community are its actual members, not drive-by strangers. And moderation is public, transparent, and auditable: if the same post is reported five times, all five reports collect on a single page that works much like a GitHub issue, where anyone can see what was decided and why.

Multiforum runs on the idea that communities should be able to see and shape the systems governing them. People create topic-focused forums that can host discussions, events, collaborative wikis, and downloadable files. Content can be cross-posted to several forums, while voting, moderation, filters, and permissions remain specific to each community.

The app is split into a Nuxt frontend and a separate GraphQL backend that talk exclusively over GraphQL, with data stored in Neo4j and authentication handled by Auth0.

  • TypeScript
  • Nuxt 3 / Vue 3
  • Pinia
  • Tailwind CSS
  • GraphQL
  • Neo4j
  • Node.js
  • Auth0
  • Playwright
  • Cypress
1 of 4
Per-forum plugin settings: forum owners enable and version individual plugins (an attachment security scanner, ChatGPT bot profiles, a beta-reader bot) from the plugins their server admin has made available.

Beta Bot

Personal project

2025 – Present

Beta Bot is a local-first writing app that pairs manuscript management with AI-powered feedback. Authors organize books into chapters, parts, and sections in a responsive editor with live preview, while the app auto-generates structured chapter summaries that track plot points, characters, and events to keep continuity across a long manuscript.

It can produce contextual reviews in several styles (fan commentary, editorial notes, or line-editing suggestions) using customizable reviewer profiles that understand the story so far. A built-in wiki holds character sheets and lore pages with change tracking and cross-document search, plus global find-and-replace across every chapter.

Data stays on-device by default, with optional AES-encrypted backups to Google Drive. The web app is available now at beta-bot.net. Electron desktop and mobile app releases are planned, with the goal of providing the same core functionality as the web app across every platform.

The app also hides an optional illustrated mini-game, Bardwall, a haunted town whose economy runs on stories. Because it draws only from the passages you actually added in your saved chapter revisions, it turns real writing progress into an in-game reward.

  • Vue 3
  • TypeScript
  • Vite
  • Tailwind CSS
  • Pinia
  • TanStack Query
  • SQLite (sql.js)
  • Capacitor
  • Electron
  • OpenAI API
1 of 9
Bardwall, a mini-game that pays out only for words you actually wrote

Clockwork Town

Personal project

2025 – Present

Clockwork Town is a browser-based life simulator that renders human experience as an IT monitoring dashboard: residents are nodes, their needs are metrics, and their emotional states surface as alerts. It treats inner life with deadpan affection by describing psychology in the flat language of uptime monitoring.

Residents move through daily routines, commuting to work or school and returning home to sleep on schedules that shift across the week, while a live relationship graph shows friendships and family ties forming and drifting over time. You can build and run multiple towns at once, each with its own households, community spaces, and characters, all displayed through a Grafana-inspired real-time dashboard.

Play is single-player and offline-capable, with encrypted Google Drive backup and restore. The frontend talks to a schema-first GraphQL backend backed by an embedded Kùzu graph database.

  • Vue 3
  • TypeScript
  • Pinia
  • Vite
  • Tailwind CSS
  • ECharts
  • Node.js
  • GraphQL Yoga
  • Kùzu
1 of 4
The town-health dashboard renders residents’ inner lives as uptime monitoring: population, mean happiness, “SLA breaches” for unhappy residents, and per-need bars for food, sleep, hygiene, and more.

Things I Sew

I’m learning to sew. So far I’ve made two quilts and a moose. Here are the pictures.

My first quilt, an abstract 3D shape, hanging above the bed.
A second quilt, in a pattern called Alaska.
A stuffed moose, made from blue floral fabric with green antlers.

A fictional universe I’ve been building

Inside the Imperial Prediction Department’s restricted archive, an archivist watches a glowing projection of an improbable celebration where living people dance with ghosts.
An unreliable prediction in the restricted archive of the Imperial Prediction Department.

I’ve been building a fantasy world where supernatural powers have rules and constraints, institutions arise around those rules, and much of the story comes from people trying to operate inside them... or exploit them. The Imperial Prediction Department, pictured above, keeps a separate restricted archive for predictions deemed impossible or too far-fetched. The prediction on display is considered especially unreliable because several of the people shown in it are already dead.

Then there’s Heliconia, the Lady of Lost Causes: a goddess who can be summoned, but whose curse supernaturally forbids her from meddling directly in human affairs. She is permitted to intervene only when a cause is genuinely lost. After centuries spent looking for loopholes, she now has an Office of Curse Management, where lawyers and clerks resolve disputes with the curse in ways that preferably do not involve the curse punching her teeth out.

Elsewhere is Aeternaxis, a civilization in the underworld, where ghosts travel through rivers toward the sea to pass on. Aeternaxis prevents them from reaching it. Its people call the ocean the leachate, and its political factions disagree over how aggressively to exploit, contain, or outmaneuver the intelligence within it.

This world is the setting for a novel I’ve been drafting for years. It is currently over half a million words toward what will eventually be several books, and nowhere near done.

Which is why I built Beta Bot: to help keep it all straight.