# Building an AI lineup optimizer for a Discord esports bot (the algorithm, not the hype)

> Source: <https://dev.to/ravendev/building-an-ai-lineup-optimizer-for-a-discord-esports-bot-the-algorithm-not-the-hype-2hjh>
> Published: 2026-07-31 21:32:03+00:00

Every esports team captain has done this by hand at least once: open Discord, scroll through a dozen "I can play Thursday after 8" messages, cross-reference them against who plays Tank versus DPS, remember that one of your DPS is actually a sub, and try to assemble a starting five that can actually scrim tonight. It takes fifteen minutes, you get it slightly wrong, and you do it again the next day.

I build [Supatimer](https://supatimer.com), a free Discord bot for competitive gaming teams, and "generate the lineup for me" was the single most requested feature. This post is about how the lineup optimizer actually works, why it is genuinely AI (and not in the marketing sense), and where a large language model fits in versus where it absolutely does not.

Half the Discord bots on the market slapped "AI" on their landing page the week ChatGPT launched. Usually it means there is a chatbot command somewhere that proxies to an LLM. That is fine, but it is not what your team needs when it is 7:45pm and you have a scrim at 8.

There are two honest definitions of AI worth separating:

The lineup problem is squarely a problem for the first kind. So that is what I built first.

Strip away the gaming context and a lineup is a constrained assignment problem:

That is a textbook constraint satisfaction problem with an objective function on top. You are not asking a model to guess. You are enumerating feasible assignments and ranking them by an explicit score.

The core loop is unglamorous and that is the point:

```
1. Filter the player pool to "available" + "maybe" for the target time block.
2. Generate candidate assignments that satisfy the required composition
   (every required role slot filled by a player who can play that role).
3. Prune assignments that violate hard constraints
   (a player can't occupy two slots; required roles must be covered).
4. Score each surviving candidate:
       coverage  = required roles actually filled
       confidence = sum of availability weights (available > maybe)
       priority  = starters weighted above subs above trials
   score = w1*coverage + w2*confidence + w3*priority
5. Return the top-ranked lineup, plus the next best alternatives.
```

For a 5-to-6 player slot out of a roster of 7-10, the candidate space is small enough to enumerate exhaustively in well under a second. There is no heuristic guessing and no "the model thinks this is good" hand-waving. If the optimizer says these five players give you full role coverage at the highest availability confidence, you can read exactly why.

The captain's job shifts from *building* the lineup to *reviewing and overriding* one. That is the whole ergonomic win. In Discord it is one command: `/weekplan`

shows the optimal lineup for every block in the week, and `/early-lineup`

focuses a single upcoming window.

This is the part developers tend to get wrong in 2026, so it is worth being blunt: you should not use a language model to pick a lineup.

The optimization problem is small, well-defined, and rule-bound. That is exactly the regime where classical AI beats a language model, and pretending otherwise just to claim "LLM-powered" would make the product worse.

There is one spot in the scrim workflow that is genuinely a language problem: the messy DM you get from the opposing team.

"yo we can run tn at 9 your time, bo3, we ban bind you ban split, our discord is ..."

That is unstructured natural language with time, format, map veto, and contact details all tangled together. Parsing it with regex is a losing battle. So Supatimer has a second, separate AI system: an **LLM scrim parser** (currently in beta) that extracts structured fields - time, opponent, format, map vetoes, lobby details - from any free-form scrim message and turns them into a clean confirmation.

That is the right tool for the right job: a language model for the language problem, a constraint solver for the constraint problem. Two different systems, neither one pretending to be the other.

The lineup optimizer is live in [Supatimer](https://supatimer.com) right now, free, for 21 competitive games with role presets already configured. Players mark availability by tapping buttons on a weekly calendar in Discord, and `/weekplan`

builds the lineup. The [scrim tooling](https://supatimer.com/scrim-bot) handles confirmations and score tracking, and the [LLM scrim parser](https://supatimer.com/ai-discord-bot) is rolling out in beta.

If you run a competitive team and you are still building lineups by hand from scattered "I can play Thursday" messages, you do not have to.

*I'm Raven, the developer behind Supatimer. I built the optimizer because I was tired of assembling Overwatch lineups by hand every night. Questions, feedback, or want to nerd out about constraint solvers? Find me on the Supatimer Discord.*
