Skip to content

Discord bot · MVP · Module 1 (LoL)

BogaBot

League of Legends ranking for your Discord group. It links Riot accounts, ingests matches from the Riot API, computes a configurable score per player and posts daily and weekly rankings in Discord. It also alerts live when a match ends and keeps an all-time ranking of trolls and blowouts.

A bogalabs product — a group of programmer friends building stuff for fun.

Read the wikiSource code ↗See commands
Python · discord.py · aiohttpLAS (la2 / americas) by default, configurable per regionDiscord as a databaseYAML scoringFree to use — clone the repo and run it on your server

What it does

A ranking that builds itself

The bot links the group's Riot accounts, reads matches from the API once a day, computes a score per player and posts it in Discord. Everything else hangs off that.

Daily and weekly ranking

A once-a-day job ingests the group's matches and posts the day's ranking. On Mondays, the weekly "Trolls and Pros" recap for the week that just closed (Ranked Flex only).

Configurable score

The formula lives in config/scoring.yaml: metrics, weights and normalization. The group tunes it without touching code and the change shows up on the next /ranking.

Live alerts

Every few minutes the bot checks for new matches and, for each one played with another linked member, posts a message tagging the players with their individual result.

Trolls and blowouts

Detects trolled games (KDA < 0.5 and FF before 20 min) and blowouts (a loss before 25 min) from the last 48 h, and keeps an all-time trolls ranking.

Discord as a database

Storage sits behind an interface; today it stores JSON messages in a private channel. Moving to SQLite or Postgres is writing a class and changing one line.

Modular by cogs

LoL is module 1. Adding features (including a future AI module) is dropping a folder into modules/ and registering it, without touching what already works.

Reference

Commands

Slash commands. The admin ones require the dev role and, if configured, must be run in the admin channel.

/link<Name#TAG>everyone

Links your Riot account to your Discord. It's validated against the Riot API; if the Riot ID doesn't exist, nothing is stored.

/unlinkeveryone

Unlinks your account. Your matches stop counting toward the ranking.

/ranking[Today | Week]everyone

Shows the group ranking on demand, without waiting for the automatic post.

/help · /ayudaeveryone

List the commands available for your role. They're two names for the same thing.

/link-admin<user> <Name#TAG>dev role

Links another server user's Riot account. Requires the dev role and, if configured, must be run in the admin channel.

/unlink-admin<user>dev role

Unlinks another server user's account.

/ingest-nowdev role

Forces a manual match ingestion. It's idempotent: the dedup by (match_id, puuid) skips what's already stored, so running it extra times duplicates nothing.

The score

How the ranking is calculated

A match only counts if you played it with at least one other linked member of the group — solo games are discarded on ingestion, like remakes. In each window (day, or week from Monday) the stats are aggregated per player and the engine applies the formula from config/scoring.yaml: it normalizes each metric with zscore and weights it.

Default weights

5.0win_rate win percentage
3.0kda (kills + assists) / deaths
2.0avg_deaths average deaths per match (lower is better)
1.5damage_per_min damage to champions per minute
1.0avg_vision average vision score
0.5games_played matches played (rewards participation)

It's tuned without touching code: change the weights in the YAML and the next /ranking comes out with the new formula.

Automatic job once a day (23:55 local time recommended): ingestion → the day's ranking. On Mondays, the weekly “Trolls and Pros” recap for the week that just closed, counting Ranked Flex only.