Files
mtga-assistant/README.md
T
Aeth3randClaude Opus 5.5 90f846c70b Rewrite README with logo and screenshots
Add the logo and screenshots, restructure into features, installation,
usage, configuration and development, and bring everything up to date
(background mode, installers, menus, limitations). The project
description now covers Linux and Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:54:08 -04:00

227 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<p align="center">
<img src="images/mtga-assistant-icon.png" alt="MTGA Assistant logo" width="128">
</p>
<h1 align="center">MTGA Assistant</h1>
<p align="center">
A deck and game tracker for <b>Magic: The Gathering Arena</b> on Linux and Windows.
</p>
MTGA Assistant follows MTGA's `Player.log`, as Untapped.gg and other trackers do. It shows your
library with draw odds, everything revealed about your opponent, per-turn stats, and a filterable
history of every game you play. It runs natively on Linux (MTGA through Steam/Proton) and on
Windows (Steam, Epic or the standalone installer).
## Screenshots
**Match**: both players, the match, per-turn stats, your deck, a card preview and everything known
about the opponent.
![Match view during a Brawl game](images/screenshots/1-matchScreen.jpg)
**A past game** opened from History, with "Back to live" to return.
![A past game opened from History](images/screenshots/2-previousMatchScreen.jpg)
**History**: stats and every finished game; sort by any column.
![History view](images/screenshots/3-historyScreen.jpg)
**Filtered history**: right-click any value to filter; the stats follow the filter.
![History filtered to one commander](images/screenshots/4-historyScreenFiltered.jpg)
**Customization**: reorder and show/hide deck sections and turn stats.
![Arrange dialog](images/screenshots/5-customization.jpg)
## Features
### Match
Three rows; drag the dividers to resize them (sizes are remembered).
- **You · Match · Opponent**: life totals, poison/energy and other player counters, commanders
(with location and commander tax), emblems, hand/library/graveyard/exile counts, turn timer and
timeouts used, land drops used/allowed (e.g. `0/2` with extra land effects), who was on the play,
plus the match panel: turn, phase, game number, Bo3 score, who has been on the draw more, and
game time.
- **You · Turn · Opponent**: each player's stats for the selected turn and the whole game: cards
drawn, spells cast, lands played, creatures died, life gained/lost, damage, discards, mills,
exiles, spells countered, tokens, counters and land drops. The middle panel picks the turn
(◀ ▶, or *Live* to follow the current one).
- **My deck · Preview · Opponent**:
- *My deck*: the remaining library with draw odds, and your hand, stack, battlefield, graveyard,
exile and sideboard. Counts show copies in that zone against copies in the deck (`2/5`).
- *Opponent*: their battlefield, stack, graveyard and exile, cards known to be in their hand or
library (seen going back there, or revealed), and every card seen this match.
- *Preview*: hover a card to see its [Scryfall](https://scryfall.com) image. Clear it with ✕,
a click on the image, or Esc.
Card names, mana costs and types come from MTGA's own local card database, so they work offline.
### History
Every finished game is recorded with its date, event, deck, commanders, opponent, both decks'
colours, who was on the play, the result, turns and length. Above the list are your win rate
overall, for the last 10 and 100 games, for the last 7 days, and on the play and on the draw,
plus average game length and turns.
- **Sort**: click a column header; click again to reverse.
- **Filter**: right-click a cell to show only (or hide) games with that value, such as a deck,
commander, event, opponent's colours or play/draw. Filters combine, appear as removable chips,
and the stats follow them.
- **Open a game**: click it to view it in the Match page as it ended, including turn-by-turn
stats. *Back to live* returns to the current game.
- Columns can be resized; games from the previous MTGA session (`Player-prev.log`) are imported
on startup.
### Customization
- **⚙ Customize**: show or hide each panel of the Match page (You, Match, Opponent, Turn stats,
My deck, Preview, Opponent's cards) and the details in the player panels. The menu stays open
while you tick and untick.
- **Customize → Arrange deck sections and turn stats…**: reorder (drag, or ↑/↓) and show/hide the
My deck and Opponent sections and the turn stats.
All choices are remembered.
### Runs in the background
So that no game is missed, closing the window keeps the app running in the system tray (on
Hyprland, Waybar's tray) and recording history. Quit from the tray menu, *☰ → Quit*, or Ctrl+Q.
- **Opens when MTGA starts**: the app watches MTGA's log folder using OS file notifications
(inotify on Linux, ReadDirectoryChangesW on Windows) rather than polling. When MTGA launches it
starts a fresh `Player.log`, and the window pops up. This works for Steam, Epic and standalone
installs.
- **One instance**: starting the app again shows the running copy instead of opening a second
one.
- **Start at login**: *☰ → Start at login (in the background)*. The installers can also set this
up.
Both behaviours can be switched off in the ☰ menu.
## Requirements
- **Detailed logs enabled in MTGA**: *Options → Account → Detailed Logs (Plugin Support)*.
- **Python 3.12 or newer.** The installers check for it and offer to install it.
- MTGA's log, install folder and card database are found automatically:
- **Linux**: MTGA through Steam (Proton), found via your Steam library folders.
- **Windows**: Steam, Epic Games or the standalone installer. The log is always in
`%USERPROFILE%\AppData\LocalLow\Wizards Of The Coast\MTGA\Player.log`.
## Installation
### Linux
```sh
./install.sh
```
The installer:
1. Checks for Python 3.12+, offering your distro's install command (pacman, apt, dnf or zypper)
if it's missing.
2. Installs the app and its dependencies into `~/.local/share/mtga-assistant/app`. No root is
needed.
3. Checks that Qt can start, and suggests the missing system packages if it can't.
4. Installs the icon and a launcher, `~/.local/share/applications/mtga-assistant.desktop`, which
starts the app with `--background`.
5. Asks whether to start the app at login, then launches it.
Run `./install.sh` again after pulling to update. `./install.sh --uninstall` removes the app and
keeps your history and settings, and `--yes` answers every question with yes.
### Windows
1. Download this project (on the repository page: *Download ZIP*) and extract it.
2. Double-click **`install.bat`**.
The installer checks for Python 3.12+ (offering to install it with winget), installs the
dependencies into a private build folder, builds the app with PyInstaller, and installs it to
`%LOCALAPPDATA%\Programs\MTGA Assistant` with Start Menu and Desktop shortcuts. No admin rights are
needed. It asks whether to start the app at login, then launches it.
Run `install.bat` again to update after downloading a newer version. `install.bat -Uninstall`
removes the app and keeps your history and settings.
## Usage
Start the app before or after MTGA. On startup it reads the existing log to catch up on a match in
progress, then follows new lines. When MTGA restarts, the tracker resets for the new session.
| Shortcut | Action |
|---|---|
| Ctrl+1 / Ctrl+2 | Match / History |
| Esc | Clear the card preview |
| Ctrl+Q | Quit (closing the window only hides it) |
Command-line options: `--background` (start hidden), `--log PATH` and `--mtga-dir PATH` (override
auto-detection), `--replay PATH [--rate N]` (replay a saved log, for testing).
**Hyprland**: the window's app id is `mtga-assistant`. For example, to keep it floating on another
workspace:
```
windowrule = float, class:^(mtga-assistant)$
windowrule = workspace 2, class:^(mtga-assistant)$
```
## Configuration
Settings made in the app are saved automatically. An optional `config.toml` overrides
auto-detection and limits:
```toml
log_path = "/path/to/Player.log" # override auto-detection
mtga_dir = "/path/to/MTGA" # the folder containing MTGA_Data
cache_max_mb = 500 # card image cache cap
history_max_mb = 300 # cap for stored game details (summaries are always kept)
```
| | Config file | History | Card image cache |
|---|---|---|---|
| Linux | `~/.config/mtga-assistant/config.toml` | `~/.local/share/mtga-assistant/history.db` | `~/.cache/mtga-assistant/images/` |
| Windows | `%APPDATA%\mtga-assistant\config.toml` | `%LOCALAPPDATA%\mtga-assistant\history.db` | `%LOCALAPPDATA%\mtga-assistant\Cache\images\` |
- **Card images** are downloaded from Scryfall only for cards that actually appear (about
60–100 KB each). When the cache passes `cache_max_mb`, the least recently viewed images are
deleted. *☰ → Clear image cache* empties it.
- **History** takes roughly 20–100 KB per game. Past `history_max_mb`, the oldest games keep
their row in the list but can no longer be opened.
- **On Windows** the app reads a private copy of MTGA's card database (about 260 MB, in the cache
folder), so MTGA's updater is never blocked by the app holding the file open.
## Development
```sh
uv run mtga-assistant # run from the source tree
uv run mtga-assistant --replay path/to/Player-prev.log --rate 40
uv run pytest # tests
```
- **Windows build without installing**: on Windows with [uv](https://docs.astral.sh/uv/),
`powershell -ExecutionPolicy Bypass -File packaging\build_windows.ps1` produces
`dist\MTGA Assistant\MTGA Assistant.exe` and `dist\MTGA-Assistant-windows.zip`. PyInstaller
can't cross-compile, so this must run on Windows. On Linux, the same spec
(`uv run --group build pyinstaller packaging/mtga-assistant.spec`) builds a Linux bundle.
- **Icon**: the app icon comes from `images/mtga-assistant-icon.png`. After changing it, run
`uv run python packaging/make_icon.py` to regenerate the Windows `.ico` and the copy bundled
with the app.
## Known limitations
- **Gaps in the log**: MTGA leaves oversized game-state messages out of the log ("Message
summarized because one or more GameStateMessages exceeded the 50 GameObject or 50 Annotation
limit"), typically during board wipes. Later messages usually fill the gap in. If some of your
cards stay unaccounted for, the status bar shows "⚠ N of your cards not tracked" and library
odds may be slightly off.
- **Shuffled cards**: after a library shuffle, a known card's position in the opponent's library
is lost. It stays listed under "Library … known" until it shows up again, so if it's drawn
without being revealed it may stay listed.
- **Inferred land drops**: the log doesn't say how many land plays are allowed. They're inferred
from "additional land" effects in play, so conditional effects (e.g. "as long as you control an
Elf") are always counted.