- Customize menu: a "Sections" group to show/hide each Match panel (You, Match, Opponent, Turn stats, My deck, Preview, Opponent's cards); rows collapse when all their panels are hidden. Player panel details follow, then Arrange. The submenus duplicating Arrange are gone. - The top bar's match summary only shows on the Match tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
5.8 KiB
Markdown
121 lines
5.8 KiB
Markdown
# mtga-assistant
|
||
|
||
A native Linux deck and game tracker for **Magic: The Gathering Arena** running under Steam/Proton.
|
||
It follows MTGA's `Player.log`, much like Untapped.gg and other trackers do, and shows:
|
||
|
||
Two views, switched from the top bar (Ctrl+1 / Ctrl+2):
|
||
|
||
- **Match**, from top to bottom (drag the dividers to resize; sizes are remembered):
|
||
- *You · Match · Opponent*: life totals, poison/energy and other player counters, commanders,
|
||
emblems, hand/library/graveyard counts, turn timer and timeouts, land drops used/allowed, who
|
||
was on the play, plus the match panel (turn, phase, game number, Bo3 score and draw count,
|
||
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, counters, tokens, land drops). The two sides mirror each other, with the
|
||
whole-game column next to the middle panel, which picks the turn (◀ ▶, or *Live* to follow
|
||
the current one).
|
||
- *My deck · Opponent · Preview*: remaining library with draw odds, your zones; the opponent's
|
||
board, graveyard, exile, cards known to be in their hand or library, and every card seen this
|
||
match; hover a card for its [Scryfall](https://scryfall.com) image.
|
||
- **History**: stats (win rate overall, last 10/100 games, last 7 days, on the play/draw, average
|
||
length and turns) and a sortable list of every finished game: date, event, deck, commanders,
|
||
opponent, both decks' colours, who was on the play, result, turns and length. Click a header to
|
||
sort, right-click a cell to show only (or hide) games with that value; the stats follow the
|
||
filters. Click a game to open it in the Match view ("Back to live" returns). Games from the
|
||
previous MTGA session (`Player-prev.log`) are imported on startup.
|
||
|
||
*⚙ Customize* shows or hides each panel of the Match page (You, Match, Opponent, Turn stats,
|
||
My deck, Preview, Opponent's cards) and the details in the player panels. *Customize → Arrange…*
|
||
reorders (drag, or ↑/↓) and shows/hides the My deck and Opponent sections and the turn stats.
|
||
Your choices are remembered.
|
||
|
||
Card names, mana costs and types come from MTGA's own local card database, so they work offline.
|
||
|
||
## Requirements
|
||
|
||
Runs on **Linux** and **Windows**.
|
||
|
||
- **Detailed logs enabled** in MTGA: *Options → Account → Detailed Logs (Plugin Support)*.
|
||
- MTGA's log, install folder and card database are auto-detected:
|
||
- Linux: MTGA through Steam (Proton), found via your Steam library folders.
|
||
- Windows: Steam, Epic Games or the standalone Wizards installer. The log is always in
|
||
`%USERPROFILE%\AppData\LocalLow\Wizards Of The Coast\MTGA\Player.log`.
|
||
- To run from source: [uv](https://docs.astral.sh/uv/) (`pacman -S uv` on Arch;
|
||
`winget install astral-sh.uv` on Windows).
|
||
|
||
## Running
|
||
|
||
From source (any OS):
|
||
|
||
```sh
|
||
uv run mtga-assistant # follow the live Player.log
|
||
uv run mtga-assistant --replay path/to/Player-prev.log --rate 40 # replay a saved log
|
||
uv run pytest # tests
|
||
```
|
||
|
||
On Windows you can instead use the packaged build: unzip `MTGA-Assistant-windows.zip` and run
|
||
`MTGA Assistant.exe`.
|
||
|
||
Start it 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 and replaces the log, the tracker resets.
|
||
|
||
### Linux desktop integration
|
||
|
||
On Wayland the window's app id is `mtga-assistant`. For example, to keep it floating on another
|
||
workspace in Hyprland:
|
||
|
||
```
|
||
windowrule = float, class:^(mtga-assistant)$
|
||
windowrule = workspace 2, class:^(mtga-assistant)$
|
||
```
|
||
|
||
### Building the Windows app
|
||
|
||
PyInstaller can't cross-compile, so build on Windows (with uv installed):
|
||
|
||
```powershell
|
||
powershell -ExecutionPolicy Bypass -File packaging\build_windows.ps1
|
||
```
|
||
|
||
This produces `dist\MTGA Assistant\MTGA Assistant.exe` and `dist\MTGA-Assistant-windows.zip`.
|
||
The same spec builds a Linux bundle when run on Linux
|
||
(`uv run --group build pyinstaller packaging/mtga-assistant.spec`). After editing
|
||
`assets/icon.svg`, regenerate the icons with `uv run python packaging/make_icon.py`.
|
||
|
||
## Configuration
|
||
|
||
Optional `config.toml`:
|
||
|
||
| | Config file | History | Image cache |
|
||
|---|---|---|---|
|
||
| Linux | `~/.config/mtga-assistant/config.toml` | `~/.local/share/mtga-assistant/` | `~/.cache/mtga-assistant/` |
|
||
| Windows | `%APPDATA%\mtga-assistant\config.toml` | `%LOCALAPPDATA%\mtga-assistant\` | `%LOCALAPPDATA%\mtga-assistant\Cache\` |
|
||
|
||
```toml
|
||
log_path = "/path/to/Player.log" # override auto-detection
|
||
mtga_dir = "/path/to/MTGA" # the folder containing MTGA_Data
|
||
cache_max_mb = 500 # image cache cap
|
||
history_max_mb = 300 # cap for stored game details (summaries are always kept)
|
||
```
|
||
|
||
Game history is stored in `history.db` (roughly 20–100 KB per game). On Windows the app reads a
|
||
private copy of MTGA's card database (kept in the cache folder, about 260 MB) so that MTGA's
|
||
updater is never blocked by the app holding the file open.
|
||
|
||
## Image cache
|
||
|
||
Images are downloaded only for cards that actually appear, at Scryfall's `normal` size (about
|
||
60–100 KB each), and stored in `~/.cache/mtga-assistant/images`. When the cache passes
|
||
`cache_max_mb`, the least recently viewed images are deleted. *Cache → Clear image cache* empties it.
|
||
|
||
## Known limitations
|
||
|
||
- 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. Some zones can then be stale until they next change. The app detects this and shows a
|
||
warning.
|
||
- 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. If it is drawn without being revealed, it may
|
||
stay listed.
|