A Discord bot that translates Korean and Chinese summoner names in League of Legends games for subscribed users.
Shoutout to these 2 randos I found on porofessor's live games
Overview
LeagueOfRen monitors League of Legends players and automatically translates non-English summoner names in their games. When a subscribed player starts a game, the bot detects Korean/Chinese character usernames and provides translations in the Discord channel using AI.
Quick Start
Option A: Windows Users (Just Run It)
If you're on Windows and don't want to compile anything:
Download the latest leagueofren-windows-amd64.zip from Releases
Unzip the archive to a folder of your choice
Double-clickleagueofren.exe to run
Follow the setup wizard - On first launch, an interactive wizard walks you through:
Discord bot token setup (with link to Developer Portal)
Riot API key setup (with link to Developer Portal)
LLM provider choice (Anthropic or Google)
LLM API key setup
The wizard saves your configuration to .env automatically. The bot creates a local SQLite database - no PostgreSQL or Docker needed.
git clone https://github.com/jusunglee/leagueofren.git
cd leagueofren
make setup
4. Run the Bot
make run
On first run, an interactive setup wizard walks you through configuring:
Discord bot token
Riot API key
LLM provider (Anthropic or Google)
LLM API key
The wizard saves your configuration to .env automatically.
With PostgreSQL (optional, for development):
make db-up # Start PostgreSQL in Docker
make schema-apply # Apply database schema
# Edit .env to set DATABASE_URL to your PostgreSQL connection string
make run
Name Origin
The name comes from seeing 인 (in) and 人 (ren) frequently in games - Korean and Chinese characters meaning "person". I could never figure out the full underlying meanings of the names without looking them up (despite me being Korean), which inspired this bot.
Other languages
In theory, this is language-scalable but I started this project scoped down since 99% of foreign names I saw in NA were chinese and korean (I also live in NYC so I might just be region-scoped with a larger Asian population). In addition, the value of this feature rests entirely on the robustness and accuracy of the translations from the LLMs. Due to, what I think to be, a cultural phenomenon unique to Korean/Chinese communities where there's a gold mine of online content produced in their respective languages about league to provide enough context to LLM scrapers, I think these 2 languages specifically are well suited perhaps next to English to be potential language candidates for this project. I wonder if to support other languages, we'd have to use an intelligent model adapter based on the language.
Why Discord
We use Discord instead of just /msg -ing you in-game because it's, for good reason, not supported by the official riot server API. There's future plans to do this anyways with the game client API if enough people just want to deploy this locally, since you'll just be whispering to yourself and has gutted potential for abuse.
Features
Subscribe to Players: Track specific League of Legends usernames by region
Automatic Detection: Monitors when subscribed players enter games
Smart Translation: Uses AI (Claude Sonnet or Google Gemma) to translate Korean/Chinese usernames with context
Translation Caching: Stores translations in PostgreSQL to reduce API costs
Riot API Caching: Caches account lookups (24h) and game status (2min) to respect rate limits
Status Tracking: Records each check with status (OFFLINE, NEW_TRANSLATIONS, etc.)
Tech Stack
Language: Go 1.26
Database: SQLite (standalone) or PostgreSQL 16 (development/production)
# Database (PostgreSQL)
make db-up # Start PostgreSQL container
make db-down # Stop PostgreSQL container
make db-logs # View PostgreSQL logs
# Schema (Atlas - declarative migrations)
make schema-apply # Apply schema.sql to database
make schema-diff # Preview pending changes (dry run)
make schema-inspect # View current database schema
# Code generation
make sqlc # Regenerate Go code from SQL queries
# Run
make run # Run the bot
make watch # Run with hot reload (air)
# Build
make build # Build binary for current platform
make build-all # Build for Windows, Linux, macOS
make build-windows # Build Windows exe only
make build-linux # Build Linux binary only
make build-darwin # Build macOS binaries (amd64 + arm64)
# Testing
make translate-test names="托儿索,페이커" # Test with Anthropic (default)
make translate-test names="托儿索" provider=google # Test with Google Gemma
make translate-test names="托儿索" model=claude-haiku-4-5 # Test with specific model
Schema Changes
This project uses Atlas for declarative schema management. Instead of writing migrations, you edit schema.sql directly:
# 1. Edit schema.sql with your changes
# 2. Preview what Atlas will do
make schema-diff
# 3. Apply changes
make schema-apply
# 4. Regenerate Go code
make sqlc
riot_game_cache: Cached game status checks (2min TTL)
Discord Bot Setup
Required Bot Permissions
When inviting the bot to your server, use the OAuth2 URL Generator in the Discord Developer Portal with these settings:
Scopes:
bot
applications.commands
Bot Permissions:
Send Messages
Embed Links
Use Slash Commands
Users who run /subscribe or /unsubscribe must have the Manage Channels permission in the channel where they're issuing the command. The /list command is available to all users.
Discord Commands
/subscribe username:<name#tag> region:<region> - Subscribe to a player (requires Manage Channels)
/unsubscribe username:<name#tag> region:<region> - Unsubscribe from a player (requires Manage Channels)
I deployed everything on a digital ocean droplet because I hate usage based pricing. You can deploy this on any box, and more ux friendly dev platforms like railway might just read and handle the docker files for you but I haven't tested it out.
Droplet instructions
Clone the repo
Run gh auth
Run make deploy, which will prompt you to set up some env vars before running.
Observability
The production stack includes a full monitoring setup deployed alongside the application via docker-compose.prod.yml.
Stack
Prometheus — scrapes metrics from the web server, worker, and nginx every 15s. 15-day retention.
Loki — aggregates logs from all Docker containers via Promtail. 15-day retention.
Grafana — visualizes everything through a pre-provisioned "League of Ren" dashboard.
The website was 100% vibecoded. I'm not trying to spend hours figuring our which value of strokelinejoin to use.
Bot
I leaned on Claude quite heavily here, but I would stop short of calling this "vibe-coded". I came up with the initial plan in initial_plan.md and implemented this with prompts progressively by driving the technical direction myself. You can see my entire prompt history in claude_history.txt. I implemented the main evaluation loop by hand without AI (for fun), you can check out the commit history for the details.