Browser game · baseball
Invicto
Draft a 12-player team from real World Baseball Classic rosters, 2006 to 2026, then simulate the tournament.
- Role
- Timeline
- Stack
- Links
By the numbers
3,175
player-edition records: 2,524 players, 23 countries, 6 editions
20,000
simulated tournaments per lineup in the difficulty test
4
languages: Spanish, English, Japanese and Korean
31.6 KB
of JavaScript, gzipped, with no UI framework
Build time
- Two public sources Wikipedia roster pages for 6 editions, and the SABR Lahman database.
- scripts
/build-data.ts Combines and validates the records, preserving each source URL and retrieval time. If a page yields fewer than 16 teams, the build stops. - 3,175 records One per player and edition: 2,524 players from 23 countries.
In the browser
- Draft Pick a 12-player lineup.
- Team rating A power mean with p = -4 combines contact, power, speed, defense, clutch and pitching. One weak category limits the whole lineup.
- Tournament Each roll uses rngFor(seed, ...path), so daily challenge rolls are reproducible regardless of call order.
The idea
Invicto turns the World Baseball Classic into a seven-game challenge. Roll a country and tournament edition to fill each of 12 lineup slots, drawing from all six Classics between 2006 and 2026. Then try to go 7-0.
What I built
A data pipeline combines Wikipedia rosters and the SABR Lahman database into 3,175 player-edition records. Each record retains its source URL and retrieval time. The build stops if a roster page yields fewer than 16 teams, and the data identifies two-way players automatically.
Team strength uses a power mean with exponent -4 across contact, power, speed, defense, clutch and pitching. That makes a weak category matter to the whole lineup. The game supports Spanish, English, Japanese and Korean. The same Cloudflare Worker uses D1 to record anonymous daily stats, count duplicate results once and store no IPs or cookies.
The hard parts
-
Imperfect public data
Rosters, names, positions and stats arrive in different formats. The pipeline joins them, validates each record and keeps every row’s source. When a player record is wrong, I can trace it back to the original page.
-
Making 7-0 a challenge
A strong lineup should have an advantage while still facing a difficult tournament. A Monte Carlo test runs 20,000 tournaments per lineup. An elite lineup must finish 7-0 between 2% and 5% of the time; one weak category must bring that below 2%.
-
Consistent daily rolls
Each random decision uses a stream identified by the seed and a path of labels. Daily players receive the same rolls regardless of the order they reveal them. Reloading the tab resumes the same seeded run.
Before and after
| Before | After | Source | |
|---|---|---|---|
| First screen on a slow connection | The title screen waited for 1.33 MB of roster data. | The title renders first, and the data loads when a run starts. | Commit 465db25, September 2, 2026 |
What’s next
Refresh the roster data after the next Classic.
Try it
Shared approaches
Make runs reproducible with seeded randomness
SWARMGEDDON, Flawless, The Veil · El Velo, Conuco, Coherente, This site
Tune difficulty with simulations
Flawless, The Veil · El Velo, Coherente, SWARMGEDDON
Test against real runtimes and data
Keep English and Spanish in sync
Protect saved progress
Conuco, Coherente, SWARMGEDDON, El Corre Corre