01
Log a match by screenshot
The Overwatch suite is built around a single source of truth: the post-game scoreboard screenshot. Every other feature in this stage (stats, team records, head-to-head) reads from match records, and the fastest way to produce a match record is to drop a screenshot into /ow log and let the bot do the typing. Vision parsing extracts heroes, players, stats, the outcome, and the mode without you having to enter any of it by hand. Anyone with slash-command access in the guild can log matches.
- Take the scoreboard screenshot at the end of a match. The bot expects the standard end-of-game scoreboard with both teams visible. Cropping the rest of your monitor out is optional but helps parse accuracy.
- Run the log command with the screenshot attached to the slash interaction:
The bot defers the reply (a "thinking" placeholder), passes the image through Claude vision, and posts the parsed match record back in the channel when it is done./ow log image:<your scoreboard screenshot> - Pre-tag your own row with the optional
playeroption. The bot links your Discord account to the matching scoreboard row so the match counts toward your stats immediately:
If you skip this, the match is logged untagged and you tag yourself in a follow-up step (covered next)./ow log image:<screenshot> player:You#1234 - Pre-attribute the teams with optional
teamandopponentoptions so the bot does not have to ask:
The team tag matches a registered team in this guild; the opponent is free text. Skipping these triggers the attribution prompt described in the attribution sub-section below./ow log image:<screenshot> team:BB opponent:"Other Crew" - Wait for the parse to finish. Cold-start vision parsing takes 10 to 20 seconds. The bot defers the slash reply so Discord does not time out, and replaces the placeholder with the parsed record when Claude returns. If the parse fails (blurry screenshot, missing scoreboard rows), the bot returns an error in the same reply and the match is not stored.
Once the parse succeeds, the match is in the database with a short ID. Every later command in this stage references that short ID. The bot prints it in the reply, so copy it before you scroll away.
02
Tag yourself for stats
Logging a match captures the scoreboard, but the bot does not know which Discord user corresponds to which in-game name until you tell it. Tagging is how you link a Discord identity to a battletag in a specific match record. Once tagged, that match counts toward your /ow stats aggregate. Tagging is a per-user action; any member can tag themselves in matches they were in.
- Tag a single match after you log it:
The bot writes a tag record linking your Discord user to that in-game name inside match/ow tag match:abc123 user:@You battletag:You#1234abc123. The next time you run/ow stats, that match's row is included in your numbers. - Tag every past match retroactively if you have been playing in the guild for a while and only just started caring about stats:
The bot walks every match in the guild, finds rows whose scoreboard name matches the battletag you supplied, and writes tag records for each one. The first time you run this it can tag dozens of matches at once./ow tag-all user:@You battletag:You#1234 - Re-run tag-all later when new matches accumulate. The bot is idempotent; matches you have already tagged are skipped, only new matches with a matching row get a fresh tag record.
- Tag a teammate by changing the
useroption to their mention. You need their consent before doing this; tagging is identity-linking, and other members should not be silently mapped to a Discord account they did not approve. A mod permission is not required, but social courtesy is.
The bot also remembers your battletag as a "known alias" for the guild. Once an alias is on file, future /ow tag-all runs can apply it automatically as part of the broader match scan, and the attribution flow in the next sub-section uses aliases to suggest team membership without asking.
Tip. If two players in the same match share an in-game name, tag-all skips that match because the bot cannot tell which row is yours. You tag those matches manually with /ow tag and pick the correct row by short ID.
03
Hero pickers and 6v6 lineups
For pre-match decisions, the bot has a hero randomizer and a balanced 6v6 lineup picker. Both lean on each user's saved favorites if you've set any. These commands are stateless conveniences, useful when nobody at the keyboard wants to make the call.
- Pick one random hero. Optionally filter by role.
With/ow hero /ow hero role:Tank /ow hero favorites_only:truefavorites_only:true, the picker chooses only from heroes you've previously marked as favorites for that role. - Roll a balanced 6v6 open-queue lineup. One primary plus one backup per role.
The output covers Tank, Damage, and Support, so a single command sets up your whole team's lineup without anyone arguing./ow 6v6 /ow 6v6 favorites_only:true - Manage your favorites per role:
Favorites are per-user and follow you across guilds;/ow favorites /ow favorites-add-tank hero:Reinhardt /ow favorites-add-damage hero:Genji /ow favorites-add-support hero:Ana /ow favorites-remove hero:Reinhardt /ow favorites-clear/ow favorites-clearwipes all of them in one shot.
04
Create and roster a team
Teams are how the bot groups players for attribution, head-to-head records, scrim blocks, and tournament brackets. A team has a display name, a short tag for command arguments, a captain, and a roster. You can create one team for a casual friend group or several for a competitive guild running multiple lineups. Creating a team requires the relevant guild permission; rostering after creation is delegated to the captain.
- Create the team:
The/team create name:"Backline Bandits" tag:BB captain:@Captainnameis the display label that shows up in attribution prompts and head-to-head reports. Thetagis the short identifier you pass to other commands (team:BB). Thecaptaingets permission to add and remove members. - Add roster members one at a time as the captain:
Each call writes a roster entry linking that Discord user to the team. The roster is independent of any Discord role; you can run a team without giving members any visible role at all./team add team:BB user:@Friend - Sync the roster from a Discord role if you already maintain a role for the team:
The bot reads the role's current member list and writes a roster entry per member. Run it again any time the role changes; the roster updates in place. This is the easier path for a guild that already lives in roles./team edit team:BB role:@BackineBanditsRole - Hand off captaincy when the current captain steps back. Admins (Manage Server) can reassign:
The new captain inherits roster-management permission immediately; the previous captain reverts to a normal roster member./team set-captain team:BB user:@NewCaptain - List every team in the guild:
Names, tags, captains, and roster counts in a single reply. Quick way to see what is registered./team list - Show one team's detail including roster and aggregate record:
The bot prints the full member list, the team's win-loss record from logged matches, and the captain's mention./team show team:BB
Teams are per-guild. The same Discord user can sit on multiple teams in the same guild if your community runs multiple lineups, and a user in two different guilds is on entirely independent rosters in each.
05
Match attribution flow
Attribution is how a freshly logged match gets associated with a team and an opponent. The bot does most of the work by scanning the scoreboard against known aliases and rosters in your guild. If it sees a clear pattern (your team's roster on one side, an opponent name on the other), it proposes both via a button row and you confirm with one click. If it cannot guess, you set them by hand. You can also pre-attribute on the log command and skip the prompt entirely.
- Run
/ow logwith no team or opponent. After the parse finishes, the bot scans the scoreboard rows against known aliases. If your team's roster covers one side of the scoreboard, the bot identifies that side as your team automatically. - The bot proposes attribution with a button row under the parsed scoreboard: Confirm, Change team, Set opponent, Skip. Confirm accepts the bot's guess; Change team swaps to a different registered team; Set opponent prompts for the opposing name (free text); Skip leaves the match unattributed.
- Pre-attribute on the log command when you already know both sides, so the bot does not prompt:
The match lands fully attributed and the button row never appears./ow log image:<screenshot> team:BB opponent:"Other Crew" - Correct a wrong attribution later if you confirmed something hasty:
The bot rewrites the attribution on the existing match record. Stats and head-to-head reports refresh on the next read./ow correct match:abc123 team:NewTeam
The bot uses known aliases (the battletags you have tagged in past matches) to recognize team membership without asking. If three of your team's five rostered players are tagged on one side of a fresh scoreboard, the bot reasonably assumes that whole side is your team and proposes it. The more matches you tag, the more accurate attribution becomes over time.
Tip. Free-text opponents normalize for grouping. "Other Crew", "other crew", and "Other-Crew" all collapse to the same head-to-head bucket, so you do not have to be precise about casing or punctuation when typing the opposing team name.
06
Head-to-head records
Once you have logged a few matches against the same opponent, the head-to-head command pulls the running record. It is the "are we actually winning this rivalry?" command. Output includes the per-team-pair win-loss, the recent matches that produced it, outcomes per map, and the dates they were played. Useful for trash talk, useful for tracking whether a strategy actually works.
- Pull the record between your team and a named opponent:
The bot replies with the aggregate score (e.g., "BB 4, Other Crew 2"), a list of the most recent matches with the date and outcome of each, and per-match short IDs so you can pull individual scoreboards with/team head-to-head team:BB opponent:"Other Crew"/ow match. - Swap perspectives when both opponents are registered teams in the guild:
The same matches show up, but the record is presented from the other team's side./team head-to-head team:OC opponent:BBOC 2, BB 4reads differently thanBB 4, OC 2, even though they describe the same six games. Captains of either side see their own perspective. - Use the short IDs the head-to-head report prints to drill into individual matches.
/ow match short_id:abc123pulls the full scoreboard for that game so you can review hero compositions or stats.
The opponent argument accepts either a registered team tag (opponent:OC) or a free-text name (opponent:"Other Crew"). Free-text opponents normalize the way they do at attribution time, so casing and minor punctuation differences do not split the record into two buckets. If you have been logging matches against "OtherCrew" and "Other Crew" interchangeably, the head-to-head still shows a single combined record.
07
Per-user stats
Per-user stats roll up every match you have tagged yourself in. The output is a single embed with your win-loss, KDA, average damage per ten minutes, average healing per ten minutes, average mitigation per ten minutes, and a role breakdown so you can see how your numbers shift between tank, damage, and support. Any member can run their own stats; you can also look up someone else's by Discord mention or by literal battletag.
- Pull your own stats with no arguments:
The bot aggregates every match tagged to your Discord user across the guild and replies with the embed described above. Numbers update in real time as new matches are tagged./ow stats - Scope to a single role when you want to see how you actually play one position:
The bot filters the aggregate to matches where you played that role. The role breakdown collapses to a single line; the per-ten numbers are tighter because the sample is more uniform./ow stats role:tank - Look up by literal battletag when you want to see a player who is not in this Discord guild:
The bot finds every match row that name appears in (using a battletag index, not Discord identity) and aggregates from there. Useful for scouting an opponent before a match./ow stats battletag:SomePlayer#1234 - List recent matches in the guild as a flat feed:
The bot prints the most recent matches, newest first, with short IDs, mode, outcome, and the team attribution if any. Quick way to find a match you remember playing but cannot recall the short ID for./ow history
The per-ten denominators come from the match length the scoreboard reports. The bot does not estimate from match type; it reads the actual elapsed time so a long overtime game does not inflate your numbers and a short steamroll does not deflate them. The result is comparable across modes and across patches.
08
Reference tables for counters and maps
The bot ships two reference tools that read from CSVs in the codebase. They are quick lookups for the kind of question you'd otherwise tab out to a wiki to answer.
- Who counters this hero? Pass the role and the hero you're querying.
The bot returns counters grouped by counter role (Tank counters, Damage counters, Support counters) so you can see your options across the lineup./ow counters role:Tank hero:Reinhardt /ow counters role:Damage hero:Genji - Hero-to-map fit. Look up which heroes shine on a specific map.
Useful before queueing: if your map is announced and the hero pool is open, the table will tell you which picks have historically performed well there./ow maps map:Hanaoka
Tip. These tables live in CSVs at game-files/ in the bot codebase. If you spot bad or missing data, send a /feedback note and the bot owner can update them.
09
Scrim blocks
A scrim block groups a practice session against a single opponent into one tracked unit. Open a block in a channel, and every match you log there while it is open is automatically attributed to that scrim and folded into a running score — no per-match confirmation prompts. Close it when you are done and the channel goes back to normal logging. Any member of the team, or a manager, can run a block.
- Open the block in the channel you are scrimming from:
The/scrim start team:BB vs:"Other Crew" focus:"practice dive comps"teamis one of your registered teams;vsis the opponent (a registered team tag or free text); the optionalfocusis a note for what you are working on. - Log maps as normal. While the block is open, every
/ow login that channel is added to the scrim automatically and attributed to your team versus the opponent. You do not confirm each one. - Watch the score build — run
/scrim showwith no arguments and the bot reports this channel's open block, every map's result, and the running win-loss-draw tally:
Update the practice note mid-session with/scrim show/scrim focus text:"now drilling defense". - Close or abandon the block:
/scrim end /scrim cancel/scrim endfinalizes the block and returns the channel to ordinary infer-and-confirm logging./scrim cancelthrows the block away (it asks you to confirm first) but keeps the individual match records — they are just no longer grouped. - Review past blocks any time, no permissions needed:
/scrim list team:BB /scrim show id:<scrim-id>/scrim listshows the blocks for a team;/scrim showwith an ID pulls one block's full result.
Tip. Only one scrim block or series can be open in a channel at a time. If you try to start a block where a stale one was left open, the bot auto-closes the old one (after about 12 hours with no maps) so you are not stuck. Cancelling a block never deletes the maps you logged — it only removes the grouping.
10
Tournament brackets
Brackets run a full single- or double-elimination tournament out of your registered teams. You seed the teams, generate the bracket, and then each matchup plays out as an ordinary best-of series that the bot logs and clinches — winners advance automatically as results come in. Seeding and structural commands need Manage Server; playing a matchup is open to the captains involved.
- Seed the teams into a named event, one per call. Registration order is the seed order:
Use/bracket add event:"Summer Cup" team:BB /bracket add event:"Summer Cup" team:OC/bracket removeto drop a team before you generate. - Generate the bracket once the field is set:
Pick/bracket generate event:"Summer Cup" format:single bestof:3format:singleorformat:doubleand a best-of length. Addrandom:trueto shuffle the seeds. If the team count is not a power of two, the top seeds get first-round byes automatically. - View the bracket at any point:
Each slot has a label like/bracket show event:"Summer Cup"W-R1-1(winners round 1, match 1) and a status glyph: pending, ready to play, in progress, or decided. - Play a matchup as a captain of either side, or a mod. This opens a best-of series in the current channel with both teams and the bracket's best-of pre-filled:
Log maps with/bracket play event:"Summer Cup" slot:W-R1-1/ow logas usual; when a team clinches the series, the bot closes it and advances the winner downstream./bracket showreflects the new state on the next read. - Fix or restart if something goes wrong (Manage Server):
/bracket override event:"Summer Cup" slot:W-R1-1 winner:BB /bracket reset event:"Summer Cup"overrideforces a slot result and cascades the change downstream;reset, which asks you to confirm, clears the bracket structure while leaving every logged series and match intact.
Tip. Double elimination adds a losers bracket and a grand final that can require a reset game (slots labelled GF and GF2). Resetting or overriding never deletes match history — the scoreboards you logged stay in the database; only the bracket wiring changes.
Continue your tour
For the full slash-command surface, see the command reference.