Libre and gratis music streaming — your music, your server, your freedom. RompMusic is a complete self-hosted system: libre (GPL-3.0) and gratis (no subscription). You own your music and data; no tracking, no proprietary services.
Notable env: MUSIC_PATH (library root), AUTO_SCAN_INTERVAL_HOURS, BEETS_AUTO_INTERVAL_HOURS. Dashboard scans use a background DB session so they continue if the tab closes.
Client (Android playback)
Background playback uses react-native-track-player: native service owns the queue; JS dispatches play/pause/seek; events sync back to the store. Patch included for Kotlin nullability with Expo SDK 54.
Docker (umbrella)
git clone --recursive https://github.com/151henry151/rompmusic.git
cd rompmusic
cp .env.example .env
# Edit DB_PASSWORD, JWT_SECRET, …
docker compose up -d
Multiplayer web chess where each player’s board is partially hidden: you always see your own pieces, but you only discover the rest along paths your pieces have traveled. Standard chess rules; server is authoritative. Credits: Charlie Bishop conceived Dark Chess; this implementation was built in collaboration with him.
Fog-of-war board; lobby; vs computer (bot uses same fog rules); challenges; random colors.
Fischer time controls (minutes+increment); server-side clocks; captured-piece counts.
Post-game review: fog lifts; replay full position history.
Full chess via chess.js: check, mate, stalemate, castling, en passant, promotion, draws, resign.
Disconnect handling; return to lobby.
How visibility works
The server keeps the true position and per-player path memory; each client gets a masked view. Opponent moves do not reveal the board for you.
Your pieces — always visible.
Your traveled squares — cumulative paths: pawns (each step); knights (chosen L-route, every square on the L); sliders (full ray); kings (start/end; castling paths); en passant capture square on path.
Captures against you — capture square revealed afterward.
Visible squares — empty reads empty; occupied shows that piece if visible.
Probes — illegal pawn push into block, or fake diagonal capture to empty (non–en passant): lose turn without moving; destination stays explored.
Sliders — enemy on ray: capture first blocking piece; (friendly-block behavior per engine rules).
Into check — illegal destinations still highlight; attempt fails without passing turn; hypothetical attackers flash red.
Server sends dark-chess targets after piece select; every move is validated.
Node 18+; ESM. npm install, npm start → http://localhost:3333 (override PORT). State is in memory—one process or sticky sessions. Behind nginx, proxy /darkchess/ and /darkchess/socket.io/ (v1.3.1+ uses relative assets and socket path). GPL-3.0+.
Gödel, Escher, Bach companion
An interactive, chapter-by-chapter companion to Gödel, Escher, Bach: An Eternal Golden Braid by Douglas R. Hofstadter. Fan-made educational project; book text is Hofstadter’s (PDFs split per chapter).
pdfs/ — intro.pdf, chapter-01.pdf … (one scroll range per iframe).
scripts/split_geb_pdf.py — regenerate PDFs from full book (Python 3, pypdf).
PLAN.md — chapter plan and companion concepts.
Build: none—serve static files from /geb/. Each chapter embeds only its PDF segment so viewers cannot scroll into adjacent chapters.
Doodlr
Collaborative, zoomable pixel-art canvas with a 6-level hierarchical grid (729×729 pixels total). Draw pixels, zoom 1–6 in a 3×3 section grid per level, consistent alignment across zoom. Production: Expo web at /doodlr/app/, API proxied at /doodlr/api/.
GET /level/{level} — canvas data; levels 2–6 need section_x, section_y
POST /paint — { x, y, color }
POST /zoom — validate { level, section_x, section_y }
Getting started
bash ./start-backend.sh # http://localhost:8000
bash ./start-frontend.sh # Expo; press w for web
Structure: backend/, frontend/, optional shared/. Version in VERSION; license GPL-3.0-or-later.
Listen
Android app that continuously records ambient audio in the background and maintains a configurable rolling buffer—review recent conversations or sounds. GPL-3.0; all storage local; no cloud upload for core recording.
Quality presets: Low 16 kbps, Medium 32 kbps, High 128 kbps.
Export; WorkManager for rotation; Room DB for segment metadata.
How it works
ListenForegroundService orchestrates capture; MediaRecorder for encoding; segments as files; SegmentManagerService for rotation. Flow: record → split → prune when over retention.
Privacy
No network permission required for core recording; microphone permission explicit; optional encryption; one-tap delete.
Archive to Video
Turn archive.org audio collections into YouTube videos: paste a details URL, preview tracks, sign in with YouTube, then download, mux still artwork + audio (e.g. 1080p H.264 / AAC), upload, and create a playlist. GPL-3.0. Web UI at /archive-to-video/app/; CLI for headless use.
FastAPI/uvicorn (systemd on hromp), ffmpeg, Python 3. CLI: python upload.py <archive.org URL> after install—see repo README.
Anthill
Godot 4.2+ (GDScript) grain-scale voxel simulation of an ant colony inspired by Lasius niger: recruitment pheromone trails, cuticular hydrocarbon footprints, alarm-like signaling, nest excavation in granular substrate, brood and workers—not a casual game but a research-oriented model with HUD and validation export.
Instrumentation — CSV logs, tracing; see docs/reference/technical_specification.txt.
Run
Prebuilt Windows EXE, Linux AppImage, and raw ELF on GitHub Releases (mirrored under hromp /downloads/). Or open game/anthill in Godot 4.2+.
invoice-gen
Flask app for small businesses and freelancers: manage companies and clients, add labor and itemized lines, upload logos, apply sales tax, and generate invoices (HTML preview + Excel download). Draft autosave syncs to the server and browser storage. Production on hromp: Docker + Gunicorn behind nginx at /invoice/ via SCRIPT_NAME=/invoice.
Production-style: docker-compose up --build (Gunicorn). Dev with hot reload: docker-compose -f docker-compose.dev.yml or ./switch-env.sh dev / prod. Key env: FLASK_ENV, SECRET_KEY, DATABASE_URL, SCRIPT_NAME=/invoice when mounted under a prefix.
Extras
Optional Google Places address autocomplete — API key in credentials.ini (see README).
REST-style JSON endpoints for clients, companies, invoice number checks, sales tax CRUD, session selections.
Test harness script populates sample businesses, clients, and invoices for manual QA.
Weather dashboard
Real-time GOES-19 satellite animations, NWS current conditions and 7-day forecast, forecast maps, and severe weather alerts—vanilla HTML/CSS/JS (no framework), dark theme, grid layout. MIT.
CONUS GeoColor, snow/ice, day/night cloud combo, full-disk GeoColor, air mass RGB, sandwich RGB, ozone, water vapor (lower/mid/upper), dust RGB, and more—24-frame loops with hover-to-pause and click-through to NOAA.
Location & alerts
ZIP-based location with coordinate lookup (Zippopotam.us); dismissible, color-coded alerts. Temperature and precipitation forecast map links update with the selected location.
Technical
Custom frame-based animation; fetch() to NWS and STAR endpoints; CSS Grid/Flexbox. Files: index.html, styles.css, links.txt. Serve with any static host (python3 -m http.server for local dev).
Word roots
Browser tools around Donald J. Borror’sDictionary of Word Roots and Combining Forms (1960): searchable index extracted from the bundled PDF, a species-name / compound builder from plain English, and an in-app link to the full PDF. Vite + React + TypeScript; runtime loads only dictionary.json—no API. GPL-3.0.
cd web && npm install && npm run dev
# Production: VITE_BASE=/word_roots/ for https://hromp.com/word_roots/
python3 scripts/extract_dictionary.py # regenerate dictionary.json from PDF
Requires pdftotext (Poppler) to regenerate JSON from the PDF.
Eternal Weave
Canvas puzzle game in a “block universe” framing: you shape one 4D worldtube—3D space (x,y,z) across discrete time slices. The UI tracks level, score, chronons, lockline, anchors, and toggles A-series / B-series observation modes plus frame tilt and orbit camera. Static game.js + styles.css under /time/.
Shape future slices before the lockline passes them; follow anchor schedule and resolve entries on the paradox ledger. Lore text per level explains the temporal metaphor (“every slice exists at once,” observation frontier freezing the past).
Controls (excerpt)
F/R or arrows — move selected time slice; WASD / QE — move y / x / z at that slice.
Z/X — frame tilt; Space — A/B view; Shift — camera preset; mouse drag orbit, wheel zoom; Backspace reset; Enter advance after stabilization.
Mobile: on-screen slice and move grids.
SpeedRead
RSVP reader: paste text or upload PDF, TXT, MD, HTML, XML, JSON, CSV. pdf.js (bundled worker) extracts PDF text in the browser—no document upload to a backend. Adjustable WPM, font size, optional center-letter highlight, play/pause and word skip. DM Sans + JetBrains Mono.
Vanilla JS modules: timer, tokenizer, display; CSS variables for typography. Keyboard: Space play/pause, arrows for prev/next word. Privacy: processing stays in the tab; hromp only serves static assets.
Day / night map
Real-time day/night terminator on a world map: D3 v7 + TopoJSON v3, 110m country data, current time display, and short educational text on axial tilt and seasons. Dependencies load from CDN—open index.html locally or visit /mercator/. MIT.
index.html, style.css, map.js, data/countries-110m.json. The map redraws the terminator continuously for the viewer’s “now.”
Solar System calculator
Single-file interactive tool: enter a Sun diameter and get all planet diameters and orbital distances to the same scale, plus a pairwise distance calculator between solar system bodies. No npm—one index.html, MIT.
Serve the file from any static root; README includes an example nginx location block for a subpath.
Travel time calculator
Trip duration from a trapezoidal velocity profile: total distance, max speed, and separate acceleration and deceleration durations. Supports metric (km, km/h) and imperial (mi, mph). Static index.html; no dependencies.
Accel phase — user-specified ramp time. Cruise — remaining distance at max speed. Decel phase — user-specified ramp down. Total time is the sum—useful for rough ETA when acceleration matters (not constant-speed-only).
Birthday in π
Pick a calendar date and search for MMDDYYYY as a digit string in the first ten million decimal digits of π. Digits load in chunks to keep memory low; search runs entirely in the browser. Includes short educational copy on irrational/transcendental π and normality.
Single-file Three.js (r128) + OrbitControls 3D cube; cubejs Kociemba two-phase solver vendored under lib/ with a same-origin worker so Firefox can run the solver. Face turns via keyboard (U…S, Shift for prime) or drag on a face; scramble, show scramble, animated solve, reset. Single static index.html workflow; live at /charlie/.
HUD Top menu picks which WCA face is “up” (persisted in localStorage); camera distance rotates with the choice so the perspective stays corner-like. Notation and solver stay standard (U = white on +Y in the model).
On Denoting
Interactive companion to Bertrand Russell’s 1905 Mind paper “On Denoting.” Left pane: full article typeset for long reading (Libre Baskerville) with a reading level switcher—Full article vs ELI5 / ELI10 / ELI20 summaries that walk through definite descriptions, Meinong/Frege objections, and the three puzzles (Waverley, king of France, difference between A and B). Right pane: companion iframe (split layout collapses to stack on narrow screens).
Makes Russell’s analysis of denoting phrases—existence/uniqueness conditions, primary vs secondary occurrence, knowledge by description—readable without a PDF reader, while optional ELI layers scaffold the logic for students.
IPA reader
Understanding the IPA — static explainer with embedded chart image, prose on consonants (place, manner, voicing) and vowels (height, backness, rounding), a link to UCLA’s interactive chart with audio (ucla_ipa.html), Ken Stevens x-ray video, and a long article on English spelling vs phonology. Optional Flask backend proxied at /ipa/api/ for IPA lookup from the inline form. Submodule: ipa-chart/ → served at /ipa/.
Teaching copy credited to Amy Reynolds (UNC-Chapel Hill); English spelling article credited to Sarada Mauck (Iowa State) in-page.
Too Hot
Project hub whose production site is its2hot.org—developed in the too-hot GitHub repo and deployed off the main hromp static tree. The hromp /too-hot/ page is a landing stub only: it documents that marketing and app assets ship from Git + CI to the external host.
Exact stack lives in the repo; expect versioned static or server-rendered pages with deploy to the its2hot server. hromp keeps a pointer for consistent navigation with other portfolio entries.