FabioCeleste/laya-mtg-deckbuild

Model

Laya HOB Deckbuild

0

3 commits

1 linked in READMEs

updated Sep 28, 2026

See the code

README

Laya HOB Deckbuild

A Laya checkpoint fine-tuned to build the 40-card maindeck from a finished Magic: The Gathering draft pool for The Hobbit (HOB) Premier Draft. Given the whole pool, it answers one typed question per card, "how many copies go in the maindeck?", plus one question per basic land type (0–17 copies).

The labels are the decks that 17Lands users actually registered. The model imitates human deckbuilding; it does not search for the strongest possible deck.

Status: experimental. The numbers below come from the validation split recorded during training (epoch 3 of 4). A full held-out test run has not finished yet (see Benchmark status).

Benchmark

Validation agreement: non-basic cards 80.9%, basic lands 71.5%, all 79.6% vs ~55% majority baseline

Question typeLaya HOB deckbuild (val)Always the majority class
Non-basic cards (0…N copies, N = copies drafted)80.88%n/a
Basic lands (0–17 of each of the 5 types)71.49%n/a
All 12,440 questions79.56%~55%

Validation loss is 1.49, which means the model is overconfident. Temperatures were not fitted ([1.2, 1.2, 1.2]), so top-1 agreement is unaffected but the probabilities are poorly calibrated.

Benchmark status

A test-split run (split == "test", 345 builds) was started on 2026-09-28 on an Apple M-series Mac (MPS). The OS stopped it at 141/345 builds because it ran out of memory, before it saved any results. It takes about 12 s per build (roughly 28k input tokens), so a complete run needs about 70 minutes on a machine with more free memory than a 16 GB Mac. Until that run finishes, treat the validation figures as optimistic.

We found no published benchmark for maindeck selection from a drafted pool. Published MTG work covers pick prediction (UrzaGPT, DraftFM, Ward et al.) or deck strength (DraftEncoder), so there is no external number to compare against. The majority-class baseline above is the only reference point.

Training

Baseconvaiinnovations/laya (English, ModernBERT-large encoder, 421M params)
Data17Lands draft_data_public.HOB.PremierDraft.csv (pool = all picks of a draft_id) + game_data_public.HOB.PremierDraft.csv (registered deck_ / sideboard_ columns), same 3,000 strong-player drafts as the pick model
Builds3,457 exact-40-card builds: 2,762 train / 350 val / 345 test, split by draft_id
Card textMTGJSON HOB.json, compact type/cost/colors/P-T/rarity/keywords/rules text
Checkpointepoch 3 of 4 (checkpoint_epoch3)
Lengthsmax_len=1280, head_max_len=768

Input format

One request per build. state holds the whole pool (no basics, alphabetical). questions has one key per distinct non-basic card, followed by Forest, Island, Mountain, Plains, Swamp.

state = {
    "game": "Magic: The Gathering", "format": "Booster Draft", "event_type": "PremierDraft",
    "expansion": "HOB", "set_name": "The Hobbit",
    "pool": [{"name": "Bilbo Baggins, Burglar", "count": 2}, {"name": "Smaug's Fury", "count": 1}],
    "pool_size": 3,
}
PREFIX = ("Booster Draft deckbuild decision for the Magic: The Gathering set 'The Hobbit' (HOB). "
          "The player's full drafted pool of picked cards is already fixed; you are now choosing the "
          "40-card maindeck versus sideboard. ")
questions = {
    "Bilbo Baggins, Burglar": {
        "type": "choice",
        "instructions": PREFIX + (
            "This card was drafted 2 time(s) (copies beyond that number were never in the pool and are "
            "not valid options). How many copies of this card does the maindeck include? "
            "Bilbo Baggins, Burglar: Legendary Creature β€” Halfling Rogue, {2}{U}, U, 2/1, common, Scry. "
            "Text: When Bilbo Baggins enters, draw a card."),
        "criteria": {"0": "0 copies (sideboard only)", "1": "1 copy", "2": "2 copies (all drafted copies played)"},
    },
    # ... one entry per pool card ...
    "Plains": {
        "type": "choice",
        "instructions": PREFIX + (
            "Basic lands are unlimited and free to add while deckbuilding, so this count is not limited by "
            "the pool. How many copies of this basic land does the maindeck include (0 to 17)? "
            "Plains: Basic Land β€” Plains, mana value 0, colorless, common. Text: ({T}: Add {W}.)"),
        "criteria": {str(i): f"{i} cop{'y' if i == 1 else 'ies'}" for i in range(18)},
    },
    # ... Forest, Island, Mountain, Swamp ...
}

Label rules for non-basic cards: "0" β†’ "0 copies (sideboard only)", middle values β†’ "1 copy" / "i copies", and the last value (= copies drafted) gets the suffix " (all drafted copies played)".

Usage

import laya
from huggingface_hub import snapshot_download

path = snapshot_download("FabioCeleste/laya-mtg-deckbuild")
agent = laya.load(path, device="cuda")  # or "mps" / "cpu"
answers = agent.predict(state, questions)["answers"]
deck = {name: int(a["choice"]) for name, a in answers.items() if int(a["choice"]) > 0}
print(sum(deck.values()), deck)

The model does not guarantee 40 cards. Each question is answered independently. To close the deck, add or remove copies from the answers with the lowest answer_confidence (usually basics) using probabilities. That repair step is your own logic, and it has not been evaluated.

Tested with laya==0.3.20. A full 37-question build took about 12 s on MPS.

Limitations

  • HOB Premier Draft only. Other sets and cards are out of distribution.
  • Validation-only metrics for now, and the probabilities are not calibrated.
  • Imitation of registered decks, which include the players' mistakes and personal style.
  • No guarantee of a legal 40-card total or a sensible mana base without post-processing.
  • Not affiliated with Wizards of the Coast or 17Lands.

Data license

Labels from 17Lands public datasets (CC BY 4.0). Card data from MTGJSON. The base model is Apache-2.0.

17lands
booster-draft
deckbuilding
laya
magic-the-gathering
model-index
safetensors
text-classification
typed-decisions

FabioCeleste/laya-mtg-deckbuild

Model

Laya HOB Deckbuild

0

3 commits

1 linked in READMEs

updated Sep 28, 2026

See the code

README

Laya HOB Deckbuild

A Laya checkpoint fine-tuned to build the 40-card maindeck from a finished Magic: The Gathering draft pool for The Hobbit (HOB) Premier Draft. Given the whole pool, it answers one typed question per card, "how many copies go in the maindeck?", plus one question per basic land type (0–17 copies).

The labels are the decks that 17Lands users actually registered. The model imitates human deckbuilding; it does not search for the strongest possible deck.

Status: experimental. The numbers below come from the validation split recorded during training (epoch 3 of 4). A full held-out test run has not finished yet (see Benchmark status).

Benchmark

Validation agreement: non-basic cards 80.9%, basic lands 71.5%, all 79.6% vs ~55% majority baseline

Question typeLaya HOB deckbuild (val)Always the majority class
Non-basic cards (0…N copies, N = copies drafted)80.88%n/a
Basic lands (0–17 of each of the 5 types)71.49%n/a
All 12,440 questions79.56%~55%

Validation loss is 1.49, which means the model is overconfident. Temperatures were not fitted ([1.2, 1.2, 1.2]), so top-1 agreement is unaffected but the probabilities are poorly calibrated.

Benchmark status

A test-split run (split == "test", 345 builds) was started on 2026-09-28 on an Apple M-series Mac (MPS). The OS stopped it at 141/345 builds because it ran out of memory, before it saved any results. It takes about 12 s per build (roughly 28k input tokens), so a complete run needs about 70 minutes on a machine with more free memory than a 16 GB Mac. Until that run finishes, treat the validation figures as optimistic.

We found no published benchmark for maindeck selection from a drafted pool. Published MTG work covers pick prediction (UrzaGPT, DraftFM, Ward et al.) or deck strength (DraftEncoder), so there is no external number to compare against. The majority-class baseline above is the only reference point.

Training

Baseconvaiinnovations/laya (English, ModernBERT-large encoder, 421M params)
Data17Lands draft_data_public.HOB.PremierDraft.csv (pool = all picks of a draft_id) + game_data_public.HOB.PremierDraft.csv (registered deck_ / sideboard_ columns), same 3,000 strong-player drafts as the pick model
Builds3,457 exact-40-card builds: 2,762 train / 350 val / 345 test, split by draft_id
Card textMTGJSON HOB.json, compact type/cost/colors/P-T/rarity/keywords/rules text
Checkpointepoch 3 of 4 (checkpoint_epoch3)
Lengthsmax_len=1280, head_max_len=768

Input format

One request per build. state holds the whole pool (no basics, alphabetical). questions has one key per distinct non-basic card, followed by Forest, Island, Mountain, Plains, Swamp.

state = {
    "game": "Magic: The Gathering", "format": "Booster Draft", "event_type": "PremierDraft",
    "expansion": "HOB", "set_name": "The Hobbit",
    "pool": [{"name": "Bilbo Baggins, Burglar", "count": 2}, {"name": "Smaug's Fury", "count": 1}],
    "pool_size": 3,
}
PREFIX = ("Booster Draft deckbuild decision for the Magic: The Gathering set 'The Hobbit' (HOB). "
          "The player's full drafted pool of picked cards is already fixed; you are now choosing the "
          "40-card maindeck versus sideboard. ")
questions = {
    "Bilbo Baggins, Burglar": {
        "type": "choice",
        "instructions": PREFIX + (
            "This card was drafted 2 time(s) (copies beyond that number were never in the pool and are "
            "not valid options). How many copies of this card does the maindeck include? "
            "Bilbo Baggins, Burglar: Legendary Creature β€” Halfling Rogue, {2}{U}, U, 2/1, common, Scry. "
            "Text: When Bilbo Baggins enters, draw a card."),
        "criteria": {"0": "0 copies (sideboard only)", "1": "1 copy", "2": "2 copies (all drafted copies played)"},
    },
    # ... one entry per pool card ...
    "Plains": {
        "type": "choice",
        "instructions": PREFIX + (
            "Basic lands are unlimited and free to add while deckbuilding, so this count is not limited by "
            "the pool. How many copies of this basic land does the maindeck include (0 to 17)? "
            "Plains: Basic Land β€” Plains, mana value 0, colorless, common. Text: ({T}: Add {W}.)"),
        "criteria": {str(i): f"{i} cop{'y' if i == 1 else 'ies'}" for i in range(18)},
    },
    # ... Forest, Island, Mountain, Swamp ...
}

Label rules for non-basic cards: "0" β†’ "0 copies (sideboard only)", middle values β†’ "1 copy" / "i copies", and the last value (= copies drafted) gets the suffix " (all drafted copies played)".

Usage

import laya
from huggingface_hub import snapshot_download

path = snapshot_download("FabioCeleste/laya-mtg-deckbuild")
agent = laya.load(path, device="cuda")  # or "mps" / "cpu"
answers = agent.predict(state, questions)["answers"]
deck = {name: int(a["choice"]) for name, a in answers.items() if int(a["choice"]) > 0}
print(sum(deck.values()), deck)

The model does not guarantee 40 cards. Each question is answered independently. To close the deck, add or remove copies from the answers with the lowest answer_confidence (usually basics) using probabilities. That repair step is your own logic, and it has not been evaluated.

Tested with laya==0.3.20. A full 37-question build took about 12 s on MPS.

Limitations

  • HOB Premier Draft only. Other sets and cards are out of distribution.
  • Validation-only metrics for now, and the probabilities are not calibrated.
  • Imitation of registered decks, which include the players' mistakes and personal style.
  • No guarantee of a legal 40-card total or a sensible mana base without post-processing.
  • Not affiliated with Wizards of the Coast or 17Lands.

Data license

Labels from 17Lands public datasets (CC BY 4.0). Card data from MTGJSON. The base model is Apache-2.0.

17lands
booster-draft
deckbuilding
laya
magic-the-gathering
model-index
safetensors
text-classification
typed-decisions