All projects/Community product 04
Community automation · Matchmaking · Self-hosted operations

BDBotPickup games, run by the bot.

A self-hosted Discord product that turns one /add command into a complete pickup-game workflow—gathering players, confirming attendance, balancing teams, finding the live lobby, recording results, and updating permanent ratings.

Follow one match
BDBot Discord message announcing a started lobby with balanced teams, captains, map, match preview, and win chances.Open full screenshot ↗
What players see

BDBot announces the teams, captains, selected map, and lobby instructions in one message. It then adds a readable match preview and predicted win chances so players know what they are joining.

My roleVolunteer Software Engineer · Product & Automation Architect
Built forAge of Empires II players and volunteer organisers in Bangladesh
Player effort1 command
DeliverySelf-hosted community product
/ The real problem

Eight players want a 4v4.
Nobody wants to organise it.

Before BDBot

Pickup games depended on one patient volunteer to gather eight people, chase no-shows, make fair teams, choose a map, locate the in-game lobby, and remember the result. Momentum disappeared while people waited, hand-picked teams felt unfair, and results buried in chat could not support a ladder anyone trusted.

After BDBot

A pickup game now costs one command from each player and no coordination from an organiser. No-shows are surfaced by a timed check-in, teams follow the community’s chosen fairness rules, stalled matches clear themselves, and every completed game contributes to a persistent competitive history.

One match, start to finish

Four stages. No organiser.

The bot does not just form teams. It owns the waiting, attendance, lobby handoff, result, and rating history that usually fall on a volunteer.

01

Gather

Players type /add. The bot keeps the queue current and starts building a match as soon as the configured team size is reached.

02

Confirm

A ready check proves everyone is present. Timeouts remove no-shows and cancel incomplete matches cleanly.

03

Build & join

Teams are balanced, drafted, or shuffled; a non-repeating map is chosen; and the live lobby feed produces a one-click route into the game.

04

Settle

A reported result recalculates ratings, settles predictions, updates the leaderboard, and writes the match into permanent history.

Inside Discord

The product explains itself where people already play.

Commands become readable community tools—players can understand the match, inspect their own history, and see the ladder without opening a separate dashboard.

BDBot Discord player profile showing rank, rating, match record, recent form, prediction performance, civilizations, maps, and teammates.Open screenshot ↗
02

Every player gets a living profile

The rank command turns permanent match history into a useful player view: rating, results, recent changes, current form, prediction accuracy, and performance patterns across civilizations, maps, and teammates.

BDBot Discord leaderboards showing player ratings and prediction rankings with records, streaks, and scores.Open screenshot ↗
03

The community can see what every game changes

Rating and prediction leaderboards update inside Discord, making the competitive history visible without a separate spreadsheet or an organiser manually calculating results.

The whole product

Problem, workflow, and result in one view.

This is the complete case-study map: what failed before, what the bot now handles, and why the engineering choices matter to players.

BDBot case study summary with challenge, solution, gather, confirm, build, and settle stages.Open full case-study map ↗
Why it holds up

Designed for the moments community tools usually fail.

Restarts, no-shows, conflicting entry points, and different channel rules were treated as product requirements—not edge cases.

01

Design for waiting and failure

A timed state machine gives every match a defined next step, deadline, and clean exit instead of allowing silent players or dead games to wait forever.

02

Persist what players can see

Queues and live matches are saved and restored across restarts, while results, players, rating history, and match records live in PostgreSQL or MySQL.

03

Give every door one brain

Discord interactions, text commands, authenticated web requests, and the one-second background loop share the same context and command logic, preventing different surfaces from disagreeing.

04

Configure the community, not the code

Team size, map rotation, rating method, timeouts, permissions, and language are channel-level settings that administrators can change without editing files or restarting the service.

Technical evidence

See the system behind the Discord messages.

These diagrams document the running services, match state machine, shared command layer, domain objects, and persistence boundaries.

BDBot system architecture connecting Discord, lobby and companion services, Gemini, Supabase, Python, Node, Express, and databases.Open diagram ↗
01

System architecture — a Python Discord process and Node/Express admin process share live bot state, persistence, and external services on one self-hosted server.

BDBot match state machine from add command through queue, check-in, team selection, reporting, ratings, persistence, and cleanup.Open diagram ↗
02

Match lifecycle — every pickup game has explicit states, timeouts, cancellation paths, rating updates, and a clean end.

BDBot domain architecture showing entry points, contexts, commands, queues, matches, configuration, statistics, and database tables.Open diagram ↗
03

Domain architecture — four entry points use one context interface and command layer before reaching queues, matches, configuration, statistics, and storage.

My contribution

I designed the workflow and built the product behind it.

Designed and built the product workflow, asynchronous Python bot, match state machine, Node and Express admin application, persistence layer, rating strategies, external-service integrations, localisation, and self-hosted operations.

  • Frame the organiser problem and design the end-to-end pickup-game experience.
  • Build the Python asyncio Discord bot and explicit match lifecycle.
  • Implement automatic balancing, captain drafting, random teams, map cooldowns, and three rating strategies.
  • Create the Node and Express dashboard, authenticated REST access, and live runtime configuration.
  • Integrate Discord, the AoE2 lobby WebSocket, AoE2Companion, Supabase, and supporting services.
  • Design restart recovery, database adapters, localisation, monitoring heartbeat, and self-hosted deployment.