Case study · 2020, 2026
BlipIt Baseball Legends
A self-playing, talking baseball simulator.
- Version
- 1.0.1
- Runs on
- Any modern browser; installable as an app
- First built
- June 2020
- Rebuilt
- 2026

What it is
Watch a nine-inning game play out pitch by pitch with a spoken announcer, or turn on Manager Mode and make the calls: steal, bunt, intentional walk, pinch hitter, defensive shift.
Origin
I started this in 2020, during the pandemic, building it with my then five-year-old son.
The first version went live at blipit.net that June. That month I gave a lightning talk at NextDor on refactoring the game’s code.
Make Refactoring Fun
Lightning talk at NextDor, June 2020, YouTube
Watch on YouTube: Make Refactoring Fun2020 to now
![The 2020 game: monospace play-by-play text, a scoreboard and a green diamond.]()
Rebuilt from sourceJun 2020 · The original self-playing baseball gameView this version ![The March 2026 Ballgame screen: a line score, controls, the diamond and batting stats.]()
Actual screenshotMar 2026 · Revived as BallgameView this version ![Today’s BlipIt Baseball Legends game screen with the scoreboard, the diamond and the play-by-play.]()
Actual screenshotNow · BlipIt Baseball Legends
Timeline
- self-playing-baseballShipped
The first version: a self-playing game with a talking announcer.
- Revived as BallgameShipped
Rebuilt as an installable web app, with custom teams.
- BlipIt Baseball LegendsShipped
Realism tuning against real baseball, then the rename.
- League ModeShipped
Seasons with a schedule and standings.
Managing, teams and leagues
- Auto-play
- Games always play themselves: pause, resume, and four speeds from Slow to Instant.
- Manager Mode
- Decision prompts with a 10-second auto-skip, so the game never stalls waiting for you.
- Seeded games
- The same seed replays the same game, pitch for pitch.
- Custom teams
- A team builder with JSON import and export; a checksum on every file catches corrupted imports.
- League Mode
- An 8-team season of 14 games per team (56 in all), with a round-robin schedule and standings.

Saves, custom teams and career statistics live in the browser’s IndexedDB through RxDB, so everything stays on the player’s device, and a saved game resumes mid-inning with its random generator state intact.
Calibrated against real baseball
In March 2026, simulated games scored and walked far more than real baseball, so the tuning treated realism as a measurement problem.
Before and after
| Measure | Before | After | Target |
|---|---|---|---|
| Runs per game | 13.0 | 7.79 | 8–9 |
| Walk rate | 15.3% | 10.2–11.5% | 8–9% |
| Strikeout rate | 19.2% | 22.7–24.7% | 22–23% |
About 14 measured tuning rounds in March 2026, on simulated games run in the browser. Every round followed the same rules: commit a baseline first, run 200 games, change one lever at a time, and let the browser run decide. Targets are approximate Major League averages; no single season is cited. The walk rate never reached its target, and the project’s docs call the remaining gap structural. The final check ran 200 games rather than the 300 originally planned.
Stack and quality
Built with React 19, TypeScript, Vite, RxDB / IndexedDB, Web Speech API, Playwright.
- Determinism testA dedicated Playwright project guards seeded replays
- Coverage floors85% of lines and statements, 90% of functions, 80% of branches
- Baseball reviewA baseball-manager review persona checks gameplay changes
How it was rebuilt
I wrote the 2020 version without AI. Most of the 2026 revival came through pull requests from the GitHub Copilot coding agent, which I merged after review: 119 of the 131 merged pull requests came from Copilot branches, under the same workflow as Verticopolis.
Status
Playable at blipit.net (version 1.0.1). In League Mode, the app marks a larger Standard league and a Full-length season as coming soon.
Last updated .
Contribute
I’m looking for contributors to BlipIt Baseball Legends. The code is open source, and the contributor guide covers setup, the quality gates and how changes get reviewed.
Receipts
The public work behind this page.


