Ryan FischerSoftware engineer · Charlotte, NC ryan@onomatopoeia.biz

Software

Independent products, community websites, and experiments.

Independent softwareAug 2025–Present · Public launch May 2026

Sitzmark

Study words, follow player progress, and explore Scrabble tournament results.

I build the React/Vite interface with TypeScript, Python services, and PostgreSQL reporting. Production data covers 21,392 players, 8,915 tournament events, 1,353,388 distinct games, and 2,662,989 player-round result rows.

Implementation details
  • Entity resolution across Scrabble organizations combines source provenance and human review of ambiguous matches.
  • PostgreSQL materialized views cut a player-dashboard request from about 10 seconds to 0.26 seconds.
  • Repaired migration regressions that erased resolved records and added regression and integrity checks.
  • Maintain 1,008 passing tests: 560 Python backend, 404 Vitest, and 44 Playwright. Led a root-cause cleanup of 159 failing tests without skipping any.
  • GitLab CI configured; DigitalOcean hosting uses systemd and scripted deployment. Database migrations, structured logging, and backup/restore documentation support operations.
  • Player filters, historical ratings, accounts, preferences, admin corrections, source reconciliation, content aggregation, and experimental word-game interfaces.
  • Prototyped an OCR pipeline that combines a board photograph and move list into a GCG game record with move-by-move playback; not released as a general-purpose feature.
  • Codex and Claude support a spec-driven, test-gated, human-reviewed workflow.

React/Vite / TypeScript / Python / PostgreSQL / Vitest / Playwright

Visit project ↗

Engineering write-up ↗

Builds on Badqoph, a Scrabble community directory begun in 2007.

Builds on earlier ScrabTube work.

Lex or Hex needs no account. Word Wisp requires an account.

Independent softwareApr 2026 – Present · Live since November 2026

Scrabble Explorer

Search, replay, and ask plain-English questions about 60,728 recorded Scrabble games.

Downloads 62,323 annotated game files politely (one request a second, resumable) and replays them with a parser shared with Sitzmark: 1.7 million moves, 3.1 million word occurrences, and 6.0 million tile placements in SQLite.

Implementation details
  • “Ask the archive”: an open-weight model (llama.cpp) running on my own hardware, reached through a reverse SSH tunnel, turns each question into one read-only SQL query. Answers come back as tables or charts that link to the games, players, and words they mention, and the SQL is always shown.
  • Safety: the model never touches the database. Generated SQL runs in a separate process on a read-only connection; SQLite’s authorizer checks every query against an allowlist of tables, columns, and functions; every query is limited to 500 rows, 2 MB, and 15 seconds; result rows are never sent to the model; write requests, attempts to get secrets, and prompt-override attempts are refused before any model call.
  • Evaluation: 53 reference questions scored by exact row-for-row comparison of results (no model grading) at temperature 0: 47 of 53 (88.7%) overall, 10 of 12 on held-out questions written after tuning ended, and 19 of 19 correct refusals and clarifying questions. These measurements use a fixed snapshot of the archive.
  • Performance: a score-range question took 45 seconds because SQLite’s query planner misjudged a filter; a one-line hint brought the query to about 0.3 seconds.
  • Hosting: Astro and Svelte on a shared 1 GB droplet under a 400 MB memory cap, with Apache in front. When the home model is offline, the site says so and everything else keeps working.

TypeScript / Astro / Svelte / Node.js / SQLite (FTS5) / Drizzle ORM / Vitest / Playwright / llama.cpp

Visit project ↗

Watch the demo ↗

Scrabble Explorer demo / 2:13Watch on YouTube ↗
Independent softwarec. 2016–2021, revived 2026

Podcast Dynamite

A podcast catalog connecting networks, shows, episodes, and credits.

A podcast catalog built from scratch with RSS ingestion and de-duplication. Earlier implementations used React/PHP/MySQL, Perl ingestion, and cron. The current rebuild combines Angular with RxJS, Java Spring Boot, jOOQ, PostgreSQL, Docker builds, and CI configuration. A collaborator wrote backend authentication.

Angular / TypeScript / RxJS / Java Spring Boot / jOOQ / PostgreSQL / Docker

Visit project ↗
Independent website2026 development

Wonderfish Films website

The website for my separate filmmaking and editing portfolio.

A Next.js 14/TypeScript site using App Router, server and client components, responsive images, metadata, and same-origin contact/CAPTCHA Route Handlers that proxy to the shared backend. Scripted Linux releases use checksummed artifacts, SSH transfer, and smoke checks; GitLab CI is configured. Film credits and editing samples live on the separate Film/Media page and Wonderfish.

Next.js 14 / React / TypeScript

Visit project ↗
Community website

Charlotte Scrabble Club

Club news, study resources, and an archive of tournament photographs.

A React and TypeScript site with resource pages, a photo archive, responsive navigation, and contact forms backed by the shared contact service.

React / TypeScript / Vite

Visit project ↗
Independent experiment2021

Anagrams on Stream

Anagrams played through Twitch chat, with a desktop display for streamers.

Go handles the game and chat connection; JavaScript renders the tile pool and players in an NW.js desktop interface.

Go / JavaScript / NW.js / Twitch IRC

View source ↗
Independent software2010–2019

Scrabble Rotisserie

A fantasy-style tournament game run for about ten championship cycles.

Perl-based ingestion and scheduled roster and standings updates, PHP interfaces, MySQL persistence, and JavaScript. Reconciled irregular player names, changing divisions, withdrawals, and official tournament records.

Perl / PHP / MySQL / JavaScript

View source ↗
Command-line study toolNov 2023; expanded 2024

Zephyr

Queries a word-study database and generates HTML statistics.

A Perl/DBI command-line tool that queries SQLite and generates HTML word-study statistics.

Perl / DBI / SQLite / HTML