Skip to content

ls ~/work

Things I've built.

Games, tabletop tools, and front-end products. Most of them started as “I wish this existed” and ended up on the internet anyway. The live ones are free to try.

Audle

Live

A daily music-making instrument.

Everyone gets the same eight-source kit, then has five minutes to make something their own. A touch-and-keyboard sequencer, independently tuned cloned voices, shareable loops, and a daily listen-and-pick ritual, all running in the browser.

  • Svelte
  • TypeScript
  • Tone.js
  • Web Audio

Clowder

In development

A cat-colony sim where the cats write their own story.

A Redwall-inspired cat-colony sim in Rust/Bevy. Cats run on a utility-AI Maslow hierarchy, carry an 18-axis personality (plus zodiac), form and break social bonds, and generate emergent prose from a RON narrative system. Weather, seasons, wildlife, combat, magic, building. One small living world.

  • Rust
  • Bevy
  • Utility AI
  • ECS

Coaching & analysis platform for Warhammer 40K.

A browser-native (Rust → WASM via Bevy) post-game review and theorycrafting tool. Annotation-first: it records actions and never enforces rules. 20+ tools, per-phase timeline snapshots with rewind, geometric line-of-sight analysis, army-list import, and an OBS chroma-key overlay for casting. Free, and one of a kind.

  • Rust
  • Bevy
  • WASM
  • Geometry

In-game reference tool for Warhammer 40K.

A polished front-end product: movement, saves, stratagems, and keyword references generated from imported datasheets, tuned for fast table-side use. Versioned past v1.9, Cypress-tested, and deployed on Cloudflare. The clearest showcase of shipping and maintaining a real front-end app with users.

  • React
  • TypeScript
  • Zustand
  • Tailwind
  • Cypress
  • Cloudflare

A Stockfish-style evaluator for mahjong.

Input your tiles and game state, get a ranked list of viable target hands and a suggested discard. Explores whether fast static evaluation (rather than full search) translates to mahjong’s hidden-information structure. Ruleset-agnostic core with NMJL 2026 support.

  • TypeScript
  • SvelteKit
  • Vitest

small tools/

Useful, specific, and smaller on purpose.

40KDC

Live

Shared 40K schemas and typed data APIs in four languages.

Community-owned schemas plus an embedded, linked dataset API for 11th-edition tooling. TypeScript, Rust, Python, and Go implementations share one conformance corpus, while stable entity IDs let independent tools interoperate.

  • JSON Schema
  • TypeScript
  • Rust
  • Python
  • Go

A consent-first public repository for competitive army lists.

A browser extension and Cloudflare pipeline that capture army lists a user already receives from Best Coast Pairings, then normalize them to 40KDC entity IDs for public browsing and analysis. Uploads are visible, consent-gated, and pseudonymized by default.

  • TypeScript
  • Svelte
  • Cloudflare
  • Browser Extensions

Tournament pairings and rankings inside Discord.

A Rust Discord bot that pulls tournament pairings and rankings from Best Coast Pairings. It uses Poise and Serenity for Discord, SQLx with SQLite for state, and Tokio for the async runtime.

  • Rust
  • Poise
  • Serenity
  • SQLx

Perceptual color sorting for a physical paint rack.

A small Python utility that turns a paint inventory into an eight-row rack layout. It samples product imagery, sorts colors in CIE LAB space with nearest-neighbor and 2-opt passes, and keeps metallic paints in their own rows.

  • Python
  • Pillow
  • CIE LAB

Assemble a team of slot machines to slay beasts.

An idle game where reels are your party. A small, weird systems toy built in Rust.

  • Rust