Skip to content

Repository files navigation

Data Diamond Baseball

CI React Vite Vitest License

A stat-based baseball simulator in the spirit of Micro League Baseball: real player stats drive probabilistic at-bat outcomes, rather than arcade-style reflexes or direct player control. v1 is a single exhibition game between the 2021 Atlanta Braves and 2021 Houston Astros, using each team's actual season stat lines.

Running it

npm install
npm run dev

Open the printed localhost URL. Click Next Play to step one plate appearance at a time, or Play Ball to simulate the full game instantly. New Game resets and replays with fresh randomness.

npm test

Runs the engine's Vitest suite, including a statistical check that simulates 20,000 plate appearances and confirms batters converge to within a few points of their real batting average.

How the simulation works

src/engine/ is pure logic with no UI dependencies:

  • statConversion.js turns each player's raw counting stats (PA, AB, H, 2B/3B/HR, BB, SO, HBP for batters; BF, H, BB, SO, HR for pitchers) into per-plate-appearance event rates.
  • log5.js blends a batter's and pitcher's rate for each event (walk, strikeout, homer, hit, etc.) against a league-average baseline, using the standard sabermetric log5 odds-ratio method. The baseline is derived from the two teams' own combined stats rather than an outside data source.
  • atBat.js rolls the blended probabilities to resolve one plate appearance into a walk, HBP, strikeout, homer, single/double/triple, or an out (further split into groundout/flyout/lineout by a league-typical batted-ball profile).
  • baseRunning.js applies that outcome to the current base/out state: force plays, double plays, sacrifice flies, tag-ups, extra-base advances.
  • fatigue.js degrades a pitcher's rates toward league average as their pitch count climbs past 75, so tiring starters get hit harder late.
  • gameState.js runs the 9-inning (+extras) game loop, rotates each team's fixed starter → setup → closer bullpen, and aggregates the batting and pitching box scores as the game plays out.

Data

src/data/teams/ holds each team's 9-batter lineup plus starter/setup/closer, entered by hand from Baseball-Reference's 2021 season totals. See statConversion.js for the exact fields each player record needs if you want to add another team.

The diamond

src/components/Diamond.jsx renders a simple pixel-art-style SVG diamond: grass, infield dirt, foul lines, bases, a pitcher and batter with an idle bob animation, and a batted ball that flies toward a spot on the field sized by hit type (short for a groundout, deep for a home run). Baserunners are tracked by id and slide between bases as gameState.js's lastPlay snapshot (the base state immediately before and after each plate appearance) changes. The ball's landing spot is randomized for visual variety only — it isn't driven by the engine's RNG and has no effect on the outcome.

What's not here yet

This is Phase 1+3 of the build (see the original build prompt for the full roadmap). Not yet implemented: manager controls (pinch hitters, steals, bunts, mid-game pitching changes), a roster/team editor, and season/series/ franchise modes. The engine is structured to support all of these without a rewrite.

About

Data Diamond Baseball — a stat-driven simulator in the spirit of Micro League Baseball. Real 2021 MLB rosters drive a log5-based at-bat engine, with a text box score/play-by-play UI (React + Vite).

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages