Tonight on DBA 2
DBA2
Live from the sim
One real game from the engine, shown the way the bot posts it in Discord. The buttons work like the real ones.
Only you can see this ·
This is game 412, simulated offline by the real engine from a fixed seed (6). The embed text, glyphs, buttons, colors and the pager come from the bot's own formatting code, run on that game and saved as data. The ratings are real 2025 NBA player ratings. The names are invented. In Discord this game plays out over about 10 minutes, one edit per play. Layout widths are approximate.
Court Viewer is the bot's real front-end code running on this same game's recorded timeline. In Discord it is an Activity that streams that timeline from the bot. Solid rings are positions from the simulation. Dashed rings are movement drawn between them.
Tonight's rundown
The five systems that make the league feel alive.
-
7:00
The Engine
A possession-by-possession sim. Pick-and-roll, pick-and-pop, post-ups, turnovers that turn into loose-ball scrambles, and blocks credited to the right defender. Same seed, same game, every time.
-
7:12
The Front Office
Rule-based GMs with their own priorities. They counter trade offers, talk through deals, remember who burned them, and handle players who ask out or hold out.
-
7:24
The Newsroom
Media personas cover hot streaks, revenge games, rivalries and trade fallout. Before a story posts, every number it cites has to match a real stat. If it doesn't, the story is rejected and rewritten.
-
7:36
The Real Players
30 seasons of NBA data (1996–2025) translated into the sim's own ratings. It passes the eye test: John Stockton grades out at 99 passing vision and Rudy Gobert at 99 screen-setting.
-
7:48
Court Viewer
A Discord Activity. Open it in a voice channel and watch the game play out on an animated court, without leaving Discord. It is the third tab above.
Replay booth
Straight from the league's Discord server.
Why I built it
“The first version needed a paid AI call for every trade and every headline. I wanted a league that thinks for itself and costs nothing to run.”
DBA 1 worked, but the GMs, the media and the trade logic all leaned on a paid AI API, and it had nowhere cheap to live. DBA 2 is a from-scratch rebuild. The intelligence comes from layered rules instead: GMs with motives, writers with voices, players with moods.
The hardest part was proving it plays like basketball. Each phase ends at a gate: simulate 3 different leagues for 5 seasons each, then check every stat against real NBA ranges. A phase closes only when all of them pass. Phase 3 closed at 32 out of 32.
How it's builtstack · architecture · hard problems
Architecture
- Headless simulation core, built and validated before any Discord code existed.
- Phase-based league state machine: preseason → regular season → offseason, with every phase change made by the commissioner.
- Deterministic: every random draw comes from a seeded stream, so any game or season can be replayed and debugged exactly.
- The presentation layer returns plain panel objects. One small adapter turns them into Discord embeds, so the demo above runs the same formatting code offline.
- Real cap rules: hard cap, dead cap, contract structures.
Problems worth mentioning
- Fact-gated media. Each number a story cites is tied to a type of claim and checked against the box score before it can post.
- Real data, messy API. Season totals silently included playoff games (Jokić showed 89 games in an 82-game season), and advanced stats only exist from 2012-13 on. Both were caught by spot-checking known players and fixed.
- Tuning without cheating. Validation ranges come from separate runs, never from the run being graded.
- No spoilers. A game's box score stays hidden until its broadcast has finished. Try
/boxin the demo before the game ends.
1,355 commits · 19,259 test cases · private repo
Want to see a game?
DBA 2 runs in a private Discord league. Invites on request.