mtg_python_deckbuilder/docs/user_guides/budget_mode.md
mwisnowski ac6c9f4daa
Some checks failed
CI / build (push) Has been cancelled
docs: documentation overhaul - archive, user guides, env parity (#62)
* docs: archive CLI runner scripts and Windows Docker guide, update web runner scripts

* docs: overhaul README and DOCKER.md, add 10 user guides

- README: Budget Mode section, corrected Further Reading links, theme badge descriptions, diagnostics expansion
- DOCKER.md: Windows path note, Budget Mode + Include/Exclude sections, env table additions
- docs/user_guides/: 10 new feature guides covering budget mode, include/exclude, locks/replace/permalinks, batch build, theme browser, random build, owned cards, partner mechanics, bracket compliance, quick build & skip controls

* fix: map PriceTimeoutError→503, add budget exceptions to status map; update error_handling.md

* docs: env var parity — add missing vars to .env.example and README table
2026-03-23 22:00:50 -07:00

4 KiB

Budget Mode

Build decks within a price target using per-card cost filtering and a soft-review summary.


Overview

Budget Mode filters the card selection pool to cards at or near a per-card price ceiling you set. Cards that exceed the ceiling are excluded from the randomized pool, but the final deck is never hard-rejected — over-budget cards that slip through are flagged for your review in the build summary.

Enable with ENABLE_BUDGET_MODE=1 (default: on).


Setting a Budget

In the New Deck modal, enter a per-card price ceiling in the Budget field. This ceiling is a UI input — it is not set via an environment variable.

  • Leave the field blank or set it to 0 to disable per-card filtering for that build.
  • The ceiling applies to all non-land cards drawn from the selection pool.

How Filtering Works

  1. Price data is loaded from a local cache sourced from Scryfall bulk data.
  2. Cards whose price exceeds ceiling * (1 + BUDGET_POOL_TOLERANCE) are excluded from the pool before selection begins.
  3. BUDGET_POOL_TOLERANCE (default 0.15) adds a 15% headroom above the ceiling. This smooths results for borderline-priced cards and avoids over-aggressive filtering.
  4. Selection then runs normally on the filtered pool — locked cards and Must Include cards are inserted before filtering.

Example: Ceiling = $2.00, tolerance = 0.15 → cards priced above $2.30 are excluded from the pool.


Build Summary

After a build completes, the budget summary panel shows:

  • Total estimated deck cost
  • Per-category cost breakdown (creatures, spells, lands, etc.)
  • Cards flagged as over-budget (above the ceiling, not the tolerance threshold)
  • Price badges on individual card rows: green (under ceiling), yellow (at ceiling), red (over ceiling)
  • A stale price indicator (clock icon) when a cached price is older than PRICE_STALE_WARNING_HOURS

The summary JSON export (deck_files/*.summary.json) includes the price breakdown per category.


Price Data & Caching

Prices are sourced from the Scryfall bulk data API and cached locally.

Behavior Setting
Background per-card refresh (7-day TTL) PRICE_LAZY_REFRESH=1 (default)
Full cache rebuild daily at 01:00 UTC PRICE_AUTO_REFRESH=1
Stale indicator threshold PRICE_STALE_WARNING_HOURS=24 (set to 0 to disable)

If a card has no price data, it is treated as free (fail-open) and selected normally. No card is hard-rejected due to a missing price.

To manually check cache status: /api/price/stats (when SHOW_DIAGNOSTICS=1).


Environment Variables

Variable Default Purpose
ENABLE_BUDGET_MODE 1 Enable budget controls and price display. Set to 0 to hide all budget UI.
BUDGET_POOL_TOLERANCE 0.15 Fractional overhead above the per-card ceiling before exclusion.
PRICE_AUTO_REFRESH 0 Rebuild the full price cache daily at 01:00 UTC.
PRICE_LAZY_REFRESH 1 Refresh stale per-card prices in the background.
PRICE_STALE_WARNING_HOURS 24 Hours before a cached price shows a stale indicator. 0 = disable.

FAQ

Why is a card over my ceiling still in the deck? The pool tolerance allows cards slightly above the ceiling into the selection pool to avoid overly thin pools. Cards that land in your deck despite being over ceiling are flagged in red in the budget summary. You can swap them using the Replace feature in Step 5.

Prices look stale — how do I refresh? Set PRICE_LAZY_REFRESH=1 (default) to refresh automatically in the background. For an immediate full refresh, set PRICE_AUTO_REFRESH=1 and restart the container, or trigger a manual refresh via the price stats API.

Does budget mode affect the commander? No. The commander is never filtered by price — only cards drawn from the selection pool are subject to the ceiling.

Can I use budget mode with Must Include cards? Yes. Must Include cards bypass the pool filter and are always added. They may appear as over-budget in the summary if they exceed the ceiling.