Releases

Changelog

Every change in every release. Grab the latest from the Releases page.

0.6.2

Latest

Windows installer — read this if Defender complains

Windows Defender has been quarantining MTGA Tracker.exe from the 0.6.1 installer as Trojan:Win32/Wacatac.B!ml (sometimes .C!ml). The tracker is not malware; the !ml suffix marks a machine-learning guess, not a match against anything known, and it fires on unsigned PyInstaller apps constantly. The shape of this one is exactly what the heuristics distrust: a freshly built, unsigned executable with no publisher that tails another program's log, runs a local web server, launches helper processes, and — for the collection exporter — reads Arena's memory.

This release does the two free things that help:

  • The PyInstaller bootloader is compiled from source on the build machine instead of shipping the prebuilt one that every PyInstaller-packed trojan also ships, so the exe no longer shares those bytes with them.
  • Both executables carry a real version resource (company, product, description, version) — an anonymous exe scores worse than a described one.

Signing the binaries is the only complete cure and it costs money every year, so it is not happening for a free tool; each release is instead submitted to Microsoft as a false positive, which clears that build within a day or two. If Defender has already quarantined your install: Windows Security → Protection history → the Wacatac entry → Restore, then Allow on device, or reinstall after the verdict clears. Details in QUICKSTART.

Performance

Measured on a ~1000-game database. Numbers are cold loads from the tracker itself; a warm dashboard is faster still.

  • Overview: 803 ms → 227 ms (about a quarter of the time). All Games and deck pages load in under half the time; the opponent page in about a fifth.
  • Refreshes between games answer in ~8 ms instead of recomputing everything. Read endpoints are memoized against a fingerprint of the analytics tables; the tracker's heartbeat doesn't invalidate it, while a finished game, a saved note, or an AI archetype landing invalidates it immediately (60-second ceiling either way).
  • How: six new indexes (participants by game/role/deck, deck cards by participant and zone, opening hands and draws by participant, games by match), one set-based draw-quality pass for the overview and All Games instead of one query per game, and a cached split-card name lookup for exports. Existing databases pick up the indexes at their next launch — a one-time build of about 0.3 s.

New

  • Wildcards on the Overview, beside the deck search: common, uncommon, rare, and mythic counts read from the inventory block Arena writes to its log at launch and on every event join (gold, gems, and vault progress are stored too). Nothing shows until the tracker has seen one.
  • Live Scoreboard shows your lifetime record against the opponent's commander in Brawl, one line per commander, hidden until you've faced it.
  • The menu-bar item is now Live Scoreboard, matching the page.

Fixes

  • Opponent colour pips could stay blank until turn 7. When Arena's card database wasn't readable at the moment the tracker built its colour index, the index was cached for the session with only cards from earlier games. It now keeps retrying Arena's layers until they answer, looks up unknown cards on demand, and basic lands light their colour on turn one.
  • The scoreboard's "Looks like…" guess could flip to an impossible archetype (Gruul → Mono-Red after a Forest). Lands no longer count as evidence, and a guess whose colours contradict the table is dropped.
  • All Games flood/screw badges disagreed with the game page for a couple dozen games — the list ignored ramped lands and the real land ratio. Both now use the same rules.
  • Profile and combat columns were blank for decks past the 40th. The Decks table lists up to 100 decks but its combat telemetry stopped at 40, so players with many small decks saw dashes on rows with plenty of games.

Docs

  • README, Quick Start, and AGENTS refreshed; the in-game overlay plan rewritten for Tauri v2 with the rail/panel design mockup (docs/plans/OVERLAY_TRACKER_PLAN.md). The overlay itself ships in a later release.

0.6.1

  • Renamed to Tapps Tracker everywhere you see it (menu bar, dashboard, window titles). App bundles, commands, and data folders are unchanged, so nothing moves on your machine.
  • Brawl: commanders everywhere. Game pages open with a commander-vs- commander strip and the Opening Hand names your commander (hover for the card); deck pages use the commander as the deck's signature art, add a slim commander banner above the decklist, and list the Opponent Commanders you've faced with your record against each. The overview's Brawl section is always visible (own nav entry) with Best Commander and Toughest Opponent Commander boxes backed by card art.
  • Brawl: decklists include the commander. Arena's submitted maindeck leaves the commander out, so a Brawl list now shows all of its cards; Arena exports gain a Commander section, and the commander's Games Seen is 100% — it is in the command zone every game. Scoreboard colors seed from the commander the moment it is revealed. (Brawl is recognized from Arena's match format, never from deck size.)
  • Fixed: Expected Lands used a flat 40% heuristic on the game page and an older decklist version on the deck page. The game page now uses the decklist submitted for that game (or the deck's nearest one); the deck page uses the newest decklist's land ratio; the label says est. only when no decklist exists at all.
  • Draw Quality reworked. Game page: Total Cards Drawn, Total Cards Seen, Lands Drawn, Lands Seen, Expected Lands, Longest Land Streak, Draw Status on one line, land percentages in the labels. The 8-draw-window and low-land- drought boxes are gone — the flood/screw evidence line already says it in words. Deck page shows per-game land averages with the share beside each label.
  • Opponent mulligans are tracked. Arena reports mulligans for both seats; the game page Mulligans box reads You / Opp. Games tracked before this release show a dash for the opponent.
  • Bo3 matches count once in opponent counts and the opponents list; the opponent page rolls each match into one expandable row with a Matches card. All Opponents is its own page with a back link, a search box that shows the count, and gold focus rings on every filter control.
  • Two-tier format filters on Recent Games and All Games: family pills (Standard, Historic, Modern, Pioneer, Timeless, Limited, Brawl, Events) with fly-out queue and Bo1/Bo3 refinements. All Games drops the redundant format dropdown and search box, widens the deck picker, and shows 30 rows.
  • Deck AI transparency. Settings, the Settings dialog, and the README now state exactly what the API key is used for: one small request per completed game, after the game ends, containing only the names of the cards your opponent revealed — never your deck, account, or log. Scoreboard colors and the mid-game deck label are computed locally and never use the key.
  • Live Log is now Live Scoreboard; the scoreboard keeps the previous game up across reloads with a "Waiting for next match…" pill; Stop Tracking shows as stopped immediately; Deck Finder pills stay lit for the current results.
  • Fixed: blank opponent color pips — the color index no longer caches an empty result when the analytics database is busy at startup, and it reads Arena's renamed Localizations table.
  • Release workflow actions bumped to their Node 24 majors; macos-debug.md documents the macOS "icon shudders and quits" launch failure and its fix.

0.6.0

  • Live Scoreboard. During a game the /live page shows your lifetime and today's record with the current deck, head-to-head record against the opponent, lands played per side, a ramp-aware draw-quality strip, a per-turn timer, your rank on ranked queues, and a best guess at the opponent's archetype from their revealed cards (matched locally against earlier identified games — no network). Between games the previous game's final scoreboard stays up with a Previous Game chip showing the result.
  • Opponents. New Opponents section on the overview: your five most-faced opponents with records, plus your record by opponent color combination — and a searchable Opponents page listing everyone you've ever been paired against.
  • Fixed: a handful of games recorded you as your own opponent. A migration cleans up the historical rows.
  • Removal accuracy overhaul. Removal, wipe, bounce, and counter classification audited against the card pool: edicts count as removal, graveyard hate and hand disruption do not, land destruction is excluded, temporary exile counts, and conditional sweepers are judged by outcome (a board wipe only when they actually cleared the board). Three migrations recount every historical game; docs/REMOVAL_CLASSIFICATION.md records every ruling.
  • Play/Draw and mulligan badges replace the old Mulligans column on Recent Games and All Games; All Games gains a Colors column; single gold focus rings on filter controls; consistent section spacing throughout.
  • Fixed: stopping the tracker from the menu bar now flips the dashboard's tracker state to off immediately; the All Opponents page no longer errors on load.
  • Restart the tracker after updating — migrations run at startup.

0.5.9.2

  • Fixed: exports could grab a deck instead of your collection. Arena keeps deck objects in memory that look exactly like a collection block, and the scanner could return one (34 cards exported instead of thousands). Candidate blocks are now gathered across all of Arena's memory and the largest valid one wins; deck-sized blocks are rejected outright.
  • Fixed: missing set codes on non-default installs. The export now finds Arena's card database via the install path Arena announces in its own log, so set codes fill in on any install location — and if the database still can't be found, the export says so instead of quietly shrinking.
  • New: Export for Archidekt. A fourth export format whose Scryfall ID column removes all import ambiguity (Moxfield reads it too). IDs resolve through Scryfall's batch API with fallbacks for Arena's mismatched collector numbers (Alchemy sets, special prints), then cache locally so repeat exports are instant and offline.
  • Card names no longer carry Arena's <nobr> markup in exports.

0.5.9.1

  • Fixed: collection export crashed on Windows with "int() argument must be a string … not 'NoneType'". Windows reports the first memory region at address zero, which the scanner mishandled before reading a single byte — the export never worked on Windows until now. macOS was unaffected.
  • Release versions now come from the git tag (setuptools-scm). The app, installers, and dashboard all derive their version from the v* tag the release was built from — no hand-edited version strings anywhere.

0.5.9

  • Ramped and searched lands now count in Lands Seen. A land pulled from your library straight onto the battlefield — Lumbering Worldwagon fetching a basic, Cultivate, fetch lands, and the like — used to vanish from every land count because it was never "drawn." It now shows up in Total Lands Seen for both live games and, via a one-time backfill of your history, past ones.
  • Fetched lands no longer read as flood, but still protect against screw. A land you searched out on purpose was not drawn against your will, so it is excluded from the flood side of the flood/screw math — ramp-heavy decks stop reading as flooded just for doing what they do. Screw keeps those lands, because a land you have (even a fetched one) is still mana in play and makes a mana-screw reading correctly less likely.
  • Export your MTGA collection from the Settings page — three buttons (.json, .csv, .txt) that read your full card collection out of the running game and write a file you can import into Moxfield and similar sites. Arena must be running with the collection loaded (open the Decks tab once); on macOS an administrator prompt appears, since reading another app's memory needs elevated access. Anchors are derived automatically from your own tracked decklists — nothing to type — and a second export within a few minutes reuses the first scan (no repeat prompt). Extraction technique adapted from NthPhantom10's MTGA-collection-exporter.

0.5.8

  • Live Log is now the Scoreboard — the old Qt play-by-play window is replaced by a live page in the dashboard (#/live): a hero scoreboard with both life totals, color pips, and deck name, a friendly format chip, the turn and game clock, and Brawl commander art with hover previews. Below it, a Live Feed that renders through the exact same timeline component as the /game page (so it reads identically), the current game's play-by-play, a retained "Previous Game" between matches with a closing "Game ended" banner, a session rail (record, runtime, live/ready status), and a scrolling Today's Games list. The Qt window is now a buried debug fallback (MTGA_TRACKER_QT_LOG=1).
  • Deck Finder moved into the dashboard — no more separate terminal window. Pick a site then a format, browse a per-site results table (win rates for untapped.gg, event placings for tournament sites, and so on), open any deck to export it to Arena or jump to the source, or hit "Surprise Me". Creator lists moved to the Settings page.
  • Settings is now a dashboard page (#/settings, gear icon on every page): Deck AI configuration, Deck Finder creators, a tracker-status readout (monitoring/card DB/log DB/version), a single sun/moon theme toggle, and the Database Health link — all in the web UI. The old Qt dialog remains as a fallback.
  • Colorless is a color: the colorless diamond ("C") now shows wherever colors do — Recent Games, the Decks table, deck and game pages, and the live scoreboard — for decks and opponents whose known cards are all colorless (Eldrazi, artifact decks), instead of showing nothing.
  • Sidebar & navigation: a Live Log entry above Overview that turns green while the tracker runs and red when it's stopped, an icon on every nav item (icon-only when the rail is collapsed), a Deck Finder button with a magnifier, and a global search that finds cards or decks.
  • Deck colors everywhere: color pips on the deck page header, a Colors column on the overview Decks table, and a Colors column in Recent Games (between Deck and Format). Colors are judged lands-first from real casting requirements — land identities carry double weight, hybrid pips ({U/B}) never force a color, a single off-color card never counts, and decks tracked before decklist capture fall back to the cards they were seen playing, so every deck gets pips.
  • Card page overhaul: sections reordered (Summary, Opening Hand Impact, opponent impact, Played By Side, Repeat Draws, Opponent Repeat Draws, Your Decks), an Avg Per Game metric, the same ambient card-art backdrop as the deck page, and a new "Opponent Could Have Played It" panel — games where the opponent's revealed colors could cast the card, how often they actually did, and the appearance rate. Computed live from existing data, no backfill.
  • Recent Games: the Match Record column is gone from the top level (a win is a win) — expanding a Bo3 match shows "Match record: 2–1" in the flyout instead.
  • Deck page polish: hero-sized signature art (with a by-name Scryfall fallback for new sets whose Arena-ID mapping hasn't landed yet), the Copy Arena Deck button moved into the topbar beside the card search, and Decklist Changes moved down between Vs Opponent Colors and Recent Games.
  • Overview: the deck page's Land Statistics (Normal/Flood/Screw split across all classified games) now heads the land section, Opponent Meta pages at 10 rows instead of silently cutting at 15, and the Decks table dropped Life Gained / Game to stop horizontal scrolling.
  • Fit and finish: Combat & Resources "(N drawn)" counts render as small muted one-line suffixes instead of wrapping, the card-search focus ring is a single clean accent border, pages scroll clear of the Back to top pill, official card-type symbols (chalice, claw mark, sunrise…) with singular labels in the deck-list type boxes, and "Imported Deck" games retitle themselves the moment the renamed deck's first game lands instead of waiting for a tracker restart.

0.5.7

Rolls up everything since 0.5.5 (including the 0.5.6 beta's date repair).

  • Mana columns everywhere cards are listed: the deck page's Deck List & Sideboard, and the game page's Opening Hand, Drawn Cards, Cards Played, and Opponent Deck tables all show each card's cost with official symbols.
  • Opponent Deck on the game page replaces "Opponent Revealed Cards", split into Opponent Played Cards (with the turn(s) each copy hit, like your own Cards Played table) and Opponent Revealed Cards (visible draws, discards, mills, exiles).
  • Table totals: proper totals rows on the deck list and sideboard, and on the game page's Drawn Cards, Cards Played, and Opponent Deck tables.
  • Mana costs on the deck list: a new Mana column (between Card and Type) shows each card's cost with the official MTG symbols — hybrid, twobrid, Phyrexian, X, the lot — rendered from a bundled icon font (mana-font), no network needed. Costs come from Arena's own local card database (backfilled into the tracker's cards table at startup and after each game, like color identities already were), with a browser-cached Scryfall lookup as fallback for anything Arena's DB doesn't cover. Works for every deck retroactively.
  • Deck list at a glance: MTGA-style card-type count boxes (Planeswalkers → Lands) above the deck list, plus "N cards total" lines under the main deck and sideboard tables.
  • Mana-value stats in Combat & Resources on both the game and deck pages: "Mana value / card played" and "Mana spent / turn" for you vs the opponent, computed from printed costs (lands excluded, X = 0) — a low cards-played count with high mana spent per turn reads very differently from four one-drops.
  • Repaired dates stored month/day-swapped by pre-0.5.5 versions for day-first locales: games recorded before the locale-aware parser (e.g. 9 August read as 8 September) landed months in the future and scrambled every date-sorted view. A one-time migration swaps them back using each tracker session's system-clock start time as the anchor — conservative by design, ambiguous rows are left untouched. Covers games, matches, turns, events, console logs, rank snapshots, and the payload archive. No database reset needed.

0.5.5

Brawl

  • Brawl is now a first-class format: commander win-rate tables on the Overview (your commanders and the ones you faced), an overall and per-queue record strip, Brawl queue labels plus commander matchup rows in Recent Games, and the commander tables page at 8 rows. The Competitive Brawl queue keeps its label even when Arena's deck attributes disagree, and Standard/Historic/ranked Brawl stay distinct everywhere.

Per-game combat & resource stats

  • New tracked categories on the game page — Removal (spot removal and board wipes played, with your drawn counts folded in, plus creatures/non-creatures lost to removal), Bounce (bounce cards played, permanents bounced to hand), Land Destruction (lands destroyed, successfully replaced by a land drop, lost for good, and the replacement rate), Counter Magic (counters played, and — from the actual stack outcome — how many landed vs failed), Tokens (created / destroyed / sacrificed / exiled per seat), and Poison counters. Card roles are classified from Arena rules text, so removal counts from the first game a card is drawn.
  • Historical games are backfilled automatically: a one-time migration recomputes the behavioral stats (removed/bounced permanents, lands, countered spells) for every old game from its recorded timeline, and scripts/backfill_card_role_stats.py fills the classification-based columns using the local Arena card database. Stats that genuinely cannot be reconstructed (tokens, poison, opponents' draws) show a dash rather than a fake zero.
  • Outcome reasons now detect decked, poisoned, and timeout endings that were previously labeled as concessions, and concede labels are short ("Opponent conceded" / "You conceded").

Deck page

  • Combat & Resources on the deck page: every game-page category as per-seat, per-game averages, in the identical column layout (the game and deck pages now share one deterministic arrangement instead of height-balanced masonry).
  • New Turn Timing (average your/opponent turn time per game and per turn) and Draw Quality (average cards and lands seen/drawn, expected land rate) sections; Formats became win-rate rectangles per queue with BO1/BO3 labels; Vs Opponent Colors opens with Best Against / Worst Against highlight cards.
  • The page picks up an ambient background tinted from the signature card's art, and metric cards across the deck and game pages gained icons.
  • Deck identity can no longer be misattributed: the decklist actually submitted to a game now arbitrates which deck the game belongs to, fixing games recorded under a previously-played deck's name when the tracker launched mid-queue.

Overview

  • Match-level records everywhere: a Bo3 counts once — top row shows Matches / Wins / Losses / Win Rate / longest streaks with icons, Wins vs Losses splits are colored and Wins-first, and How Games End presents per-reason percentages in side-by-side Wins and Losses tables.
  • Constructed Ranked section with lifetime match stats, a season dropdown, the rank chart, and per-season stats (constructed queues only — ranked Brawl tracks separately). New BO1-Ranked / BO3-Ranked quick filters, a searchable Deck filter, and the win-rate trend now covers the last 30 games.
  • Log timestamps are locale-safe: day/month order is learned from unambiguous entries (with a system-locale fallback), fixing "today's games" sorting between older dates for day-first locales, and dates render in the viewer's locale.

Game page

  • Cards Played shows the turn(s) each card was played, Opponent Revealed Cards shows the reveal turn, Drawn Cards pages at 10 turns, and the Repeat Draws card view always shows the 3 and 4+ buckets — including the opponent's repeat draws.

Fixes & maintenance

  • Fixed DB Health falsely reporting GAME_EVENT_ASSIGNMENT_MISMATCH for post-game tail events (Bo3 sideboarding gaps, rank updates, summary lines) — on a real database every flagged row was a tail and none were misassigned. The old repair also detached those rows, deleting real timeline entries. The finding and repair now only act on events whose timestamp falls inside a different game's window, and the reassignment runs automatically at tracker startup (a new index takes the pass from 4.4s to ~150ms) so nobody needs db_audit --repair by hand.
  • Stopped tracking Welcome Deck Duels (pre-made deck vs pre-made deck, e.g. "Welcome Deck Duels HOB"); migration v15 removes already-saved games of this mode and recomputes session stats. The README's "What isn't tracked" list and the dashboard's format filter are updated to match.
  • A new set's card database is picked up mid-session: after each game the tracker allows one re-scan for a newer Raw_CardDatabase, so set-release day no longer needs a restart when Arena drops the new DB alongside the old one. Arena's card DB is now always opened strictly read-only, so the tracker can never create or modify files in Arena's folder.
  • A concede during the opening mulligan decision is recorded as a real game instead of being skipped as a ghost.
  • Database hygiene: new indexes on the game-events timeline and payload archive, PRAGMA optimize each launch, and scripts/delete_untelemetered_games.py (which now VACUUMs after deleting) to drop early games recorded without combat telemetry.

0.5.4

  • Proper Windows installer: releases now ship MTGA-Tracker-<version>-setup.exe (Inno Setup) with a Start Menu entry, an Apps & Features uninstaller, and in-place upgrades. Installs per-user by default (no admin prompt) with an optional all-users/Program Files mode; uninstall asks before touching your tracked-game data. The portable -windows.zip is still published alongside it.
  • Multi-target spells show every target: Arena sends one TargetSpec annotation per chosen target, and the tracker kept only the last one — Ram Through showed only the creature taking damage, not the attacker dealing it. Targets now merge in selection order. BlockerDeclared annotations got the same hardening (every affected id is treated as a blocker).
  • The install-discovery log parser gained a second, Windows-verified marker (Arena's localization line names a file inside Downloads\Raw directly) and now normalizes Arena's mixed forward/back slashes.
  • The "Resolved N previously unknown card label(s)" message no longer repeats on every launch: duplicate-name placeholder rows are folded into the real card's row once, and only actual changes are counted.
  • Startup output tidied: Detailed Logs state prints only on changes, and one-time maintenance messages appear inside the startup banner instead of after it.

0.5.3

  • Arena installs are now found anywhere — standalone (.msi) installs on any drive included. The tracker reads the install path Arena itself announces in the head of Player.log (the Unity [Subsystems] header, verified against a real log) and derives the card-database folder from it, ahead of the Steam-library and Program Files guesses.
  • Databases recorded without the card DB heal completely. The startup backfill that rewrites Card #N placeholders now also covers mulligan-hand rows, labels with no matching cards row, and duplicate-name collisions — so a user whose install was previously unfindable gets their full history renamed on the first launch after updating. The DB Health finding for these labels now explains that restart-to-fix in plain language.
  • Builds no longer use UPX compression, which was tripping antivirus heuristics on the unsigned Windows executables.
  • Docs: AGENTS.md expanded and corrected as the single agent guide (no CLAUDE.md); added docs/MTGA_INSTALL_DISCOVERY.md.

0.5.2

  • Fixed the Deck Finder button on Windows flashing a console that instantly closed ("...is not recognized as an internal or external command"): cmd.exe cannot parse the backslash-escaped quotes Popen produces for argument lists, so the spaced exe path was split apart. The launcher now builds a single cmd /S /C line using cmd's own quoting rules. Double-clicking the exe always worked; only the menu-bar/dashboard launch was affected.

0.5.1

  • Fixed "Local Card DB: not found" on Windows (cards showing as Card #NNNN): the tracker now reads Steam's libraryfolders.vdf and checks every configured Steam library on every drive (root located via Program Files and the registry), plus Epic Games install paths — on Windows and macOS. When the DB still can't be found, the startup banner explains the consequence and the MTGA_DATA_DIR override.
  • Fixed the packaged Deck Finder starting with "No providers found": its provider modules load dynamically, so PyInstaller never bundled them. The build now collects every submodule and the registry has a frozen-build fallback list guarded by a drift test.
  • Windows path display now uses %USERPROFILE% instead of ~, so locations in the startup banner paste straight into Explorer or cmd.
  • The AI deck guess no longer prints a stray console line after "Ready for next game..." — it lands silently in the game record and shows on Game Detail.

0.5.0

  • Bundled the Deck Finder (MTGA Deck Downloader) as a companion tool: launch it from the menu bar or the dashboard sidebar, browse creator decklists (Moxfield, AetherHub, TCGplayer, magic.gg, MTGO, Untapped) in a sized terminal window, and copy lists in Arena import format. Its dependencies install with the tracker; creator lists live in deckfinder_config.json at the project top level.
  • Added AI opponent-deck identification: with an OpenAI, Anthropic, or Gemini key, one small background call after each completed game names the opponent's archetype by its dominant colors and strategy. Shown as the Opponent Deck Type on Game Detail (color label as fallback); it never blocks live tracking. Reasoning-class OpenAI models are asked for low effort and retried once on token-starved empty replies; failures now surface a real error via scripts/test_deck_ai.py.
  • Added a Settings… dialog to the menu bar app for the AI provider, key, and model, plus a Deck AI status line in the tracker startup banner.
  • Moved settings.json to the project top level next to config.py (installed builds keep it in the app data folder; the old data/settings.json migrates automatically) and anchored the .gitignore config.py pattern so the Deck Finder's config module is tracked.
  • Fixed finished games being overwritten by the next game's data when Arena re-sent a match's final GameOver state after the summary reset.