Below you will find pages that utilize the taxonomy term “Side Projects”
25 years to a complete machine
Since around the year 2000 I have been piling features into a French Final Fantasy IV translation patch. Variable-width fonts in dialog, in battle messages, in menu descriptions. Redrawn battle, load/save, main, and two-column magic menus. An expanded inventory of 0x48 slots rendered through a paged window instead of the static grid the original engine assumed. Most of these were features the SNES ROM hacking scene of the era said could not be done on real hardware. Other hackers eventually pulled off equivalents on other titles, fair enough; modifying a compiled ROM is more convoluted than editing source code, but not impossible. Twenty-five years on, “impossible” reads as a fair approximation of how hard, not of whether.
Higgins: a neurosymbolic menubar buddy
Higgins is a local assistant that lives in the menubar. A Qwen 2.5 7B model runs on-device via MLX, a SQLite triple store remembers things across sessions, and a small collection of tools — AppleScript runners, EventKit bridges, gh CLI wrappers — lets him actually do work on the Mac. No cloud, no subscription, no data leaving the machine.
The name is a nod to Magnum P.I.’s reserved English major-domo. The vibe was aspirational; most of the engineering effort went into making sure he doesn’t cheerfully hallucinate your dentist appointment into 2023.
The most useless way to port a macOS app
I grew up fascinated by projects like GNUStep, Haiku, Etoile, Wine, and ReactOS. Engineering feats, all of them. They reverse-engineer or reimplement entire operating system APIs so that software written for one platform can run on another. And they almost always end up in the same place: impressive technically, starved for contributors, forever chasing a moving target they can never quite catch.
I never liked the state of the Linux desktop either. Not because it’s bad per se, but because it’s fragmented. A KDE app on GNOME looks alien. Firefox rolls its own everything. GTK and Qt will never agree on anything. Every toolkit draws its own widgets, manages its own text rendering, handles its own accessibility story. The result is a desktop that feels like a coalition of independent projects rather than a coherent system.
Full-text search and lyrics in a Go music server
The Tunes server started as a way to stream my music library from a Raspberry Pi. It’s accumulated features since then. Two recent additions changed how I interact with it day-to-day: accent-insensitive full-text search across the entire library, and lyrics, both embedded from audio files and fetched from LRClib.
The search problem
Searching a music library is harder than it sounds. You want “bjork” to match “Björk”. You want “cafe” to match “Café”. You want “creme” to match “Crème Brûlée” in an album title. And you want it fast enough that results appear as you type.
Calculon part 2: costing profiles, performance, and maneuvers
Part 1 covered the basics: six crates, Valhalla’s tile format, a driving cost model, bidirectional A*, many-to-many matrix, and an Axum HTTP server. Everything worked for the driving case on the Monaco dataset.
Since then, the engine gained bicycle and pedestrian costing, memory-mapped tiles, a comparison webapp, turn-by-turn directions in 34 languages, and enough performance work to make it usable on France-scale data. This is what changed.
Building a routing engine in Rust
A routing engine in Rust. Bidirectional A*, many-to-many distance matrices, Valhalla-compatible API. Six crates, about 8,000 lines.
Why
We use Valhalla for routing and distance matrices at Woosmap. It works most of the time. When it doesn’t, we’re stuck. We treat it as a black box: file an issue, upgrade, hope the next release fixes things. When the matrix returns wrong costs for certain edge cases or the engine routes you through someone’s driveway, there’s no realistic way for us to dig in. It’s a massive C++ codebase that assumes you’ve been living in it for years.
Tree: a browser that remembers where you came from
Every browser has tabs. Linear, flat, disposable. Open thirty of them researching one topic and they sit in a row with no indication that twelve of them came from the same Wikipedia article. Close the wrong one and the context is gone.
Tree is a macOS browser that replaces tabs with a tree. Every page knows its parent. Cmd+Click a link and it becomes a child node of the current page. The sidebar shows the full hierarchy: research paths branch naturally, and you can always trace back to where you started.
Building a GPU map renderer from scratch
Building a vector map renderer in Rust with wgpu. From “everything renders as points” to a full style-driven renderer running on desktop, iOS, and the browser.
Why
We built our maps stack on top of Mapbox GL: the JS SDK, then native SDKs on the C++ core.
For static maps we wrapped the C++ SDK in a Python library (maparazzo). It worked but the C++ renderer leaked memory. OpenGL contexts kept state around after objects were destroyed. We tried pooling Map instances, reusing GL contexts. It helped but never fully solved it.
Tunes
iTunes Match worked great for years: you uploaded your library, Apple matched what it could, and you had access to everything from any device. But Apple is clearly moving everyone toward Apple Music, and iTunes Match has been slowly rotting. The writing was on the wall.
I didn’t want to subscribe to Apple Music. I wanted to keep my library, my ratings, my play counts, my playlists, all the metadata accumulated over 20 years. So I built my own streaming setup: a Go backend that serves the library over HTTP, and SwiftUI apps that play it on iOS, macOS, and tvOS.