Skip to main content

Magic: The Gathering

Magic: The Gathering

Dernière mise à jour : 2026-05-10

Source

  • Bulk Scryfall : https://api.scryfall.com/bulk-dataall_cards.json téléchargé localement
  • Traduction : Haiku traduit les cartes manquantes (FR souvent en retard sur l'anglais sur Scryfall)
  • Collection Qdrant : magic-cards
  • Data dir : MAGIC_CARDS_DATA_DIR (défaut /app/data/magic-cards)
    • all-cards.json : bulk Scryfall (téléchargé)
    • cards.json : extrait + dédupliqué par oracle_id, version FR

Code

Fichier Rôle
src/services/cards/sources/magic.ts Implémente CardSource (load, normalize, getImageUrl)
scripts/magic-cards/download-bulk.ts Télécharge all-cards.json Scryfall
scripts/magic-cards/extract-cards.ts Filtre + dédupe par oracle_id, version FR
scripts/magic-cards/translate-missing.ts Bat ch Haiku traduit cartes manquantes (~3000/batch)
scripts/magic-cards/ingest.ts Pousse vers Qdrant magic-cards
scripts/meta-mtg/sync.ts Sync 17Lands API
scripts/meta-mtg/sync-constructed.ts Scrape MTGGoldfish
scripts/meta-mtg/sync-tournament.ts Scrape MTGTop8
scripts/meta-mtg/fix-legalities.ts Re-vérifie les formats Standard après rotation

Payload Qdrant magic-cards

{
  id: pointId,
  name: string,            // FR
  name_en: string,         // EN
  set_label: string,       // ex: "Strixhaven (STX)"
  rarity: 'common' | 'uncommon' | 'rare' | 'mythic',
  card_type: string,       // "Creature — Human Wizard"
  mana_cost: string,       // "{2}{U}{U}"
  cmc: number,             // 4
  card_mtg_color_identity: string[],  // ['U', 'B']
  card_mtg_legal_formats: string[],   // ['standard', 'modern', 'legacy', ...]
  card_mtg_layout: string, // 'normal' | 'modal_dfc' | 'transform' | etc.
  faces: [...],            // pour double-face
  power: string,
  toughness: string,
  text: string,            // ability text (effet)
  image_url: string,       // CDN Scryfall
}

Symboles UI

  • Webfont mana-font (Andrew Gioia) chargée depuis npm package
  • Helper frontend/src/lib/mana.ts : regex /{[WUBRGCSTXP0-9/]+}/g<i class="ms ms-w">
  • Active uniquement si game.hasCardDatabase === 'magic-cards' (guard dans useArbiterMarkdown)

Méta-game

3 sources combinées :

  • 17Lands : draft analytics (winrate, pick order). Activable via META_MTG_SET=BLB (code set 17Lands).
  • MTGGoldfish : constructed metagame. Activable via META_MTG_FORMATS=standard,modern,pioneer.
  • MTGTop8 : top 8 tournois. Activable via META_TOURNAMENT_ENABLED=true + META_TOURNAMENT_FORMATS.

Toutes les sources poussent dans Qdrant comme chunks [META]. Le RAG retrieval méta filtre sur meta_format + meta_set selon la question.

Deckbuilding

  • Spec Haiku par défaut Standard : 60 mainboard, 15 sideboard, max 4 par non-basique
  • Filtre Qdrant : card_mtg_legal_formats contient spec.format
  • Post-filtre TS : card_mtg_color_identity ⊆ spec.colors (Qdrant ne gère pas bien le subset)
  • Basic lands FR/EN whitelistés pour bypass max copies : Plains/Island/Swamp/Mountain/Forest/Wastes + Plaine/Île/Marais/Montagne/Forêt

Set matching

set-aliases.ts normalise les noms d'extensions :

  • "Strixhaven" → "STX"
  • "Wilds of Eldraine" → "WOE"
  • etc.

Permet à l'utilisateur de citer un set par son nom complet, le filtre Qdrant s'applique sur le code 3 lettres.

Multi-query MTG

retrieve/multi-query-mtg.ts : Haiku décompose la question en JSON :

{
  colors: string[],       // ['R', 'G']
  cmcMax: number,         // 3
  types: string[],        // ['Creature']
  themes: string[],       // ['elf', 'tribal']
  format: string,         // 'standard'
  set: string             // 'BLB'
}

Chaque champ devient un filter Qdrant natif (payload matching) → réduit le candidate set avant le rerank.

Workflow update

Voir mettre-a-jour-cartes.md pour le détail (workflow 4 étapes : download → extract → translate-missing → ingest, + fix-legalities post-rotation).