- Fix MtgSet model to match database schema (removed created_at, added image column) - Create load_mtgjson_data.py script to load AllSetFiles, AllPrintings.psql, and other MTGJSON data - Create download_mtgjson_data.py script to download MTGJSON API data files - Add SPEC_synergy-mapping-engine.md documentation API endpoints are now working (200 OK) but database needs data loading via download_mtgjson_data.py then load_mtgjson_data.py
3.9 KiB
Technical Specification: MTG Synergy Mapping Engine
1. Project Overview
The goal is to create a Python-based data pipeline that processes MTG card data from MTGJSON, identifies synergistic relationships between cards, and stores these relationships in a PostgreSQL database. This "Data Map" will power a deck-building assistant that suggests cards based on mechanical and strategic complementarity.
2. Tech Stack
- Language: Python 3.12+
- Libraries:
pandas(data manipulation),SQLAlchemy(ORM),psycopg2(DB driver),re(regex for text processing). - Database: PostgreSQL.
- Data Source: MTGJSON (
AllPrintings.json,AllSets.json).
3. Phase 1: Data Ingestion & Normalization
The script must flatten the nested MTGJSON structure into a relational format.
3.1 Extraction
Extract the following fields from AllPrintings.json:
name,manaCost,types,text(oracle text),colorIdentity,set.
3.2 Text Processing (TextProcessor Class)
Implement a class to convert raw oracle text into "Functional Tokens."
- Regex Mapping: Use a dictionary of regex patterns to identify key actions.
- Example:
"draw a card"\rightarrowTOKEN_DRAW_1 - Example:
"destroy all creatures"\rightarrowTOKEN_BOARD_WIPE_CREATURE
- Example:
- Tagging: Extract subtypes (Tribes) from the
typesfield (e.g., "Elf", "Zombie").
4. Phase 2: The Synergy Engine (Logic)
The engine must evaluate every card pair and assign a weighted connection based on three tiers of synergy.
Tier A: Hard Synergies (Weight: 1.0)
Logic: Direct mechanical triggers.
- Tribal Link: If
Card_A.tags(Tribe)\capCard_B.text(contains Tribe name)\neq \emptyset. - Trigger-Response: Identify "Providers" (e.g., "Whenever you gain life") and "Payoffs" (e.g., "When you gain life, [Effect]"). Link Provider
\rightarrowPayoff.
Tier B: Functional Similarity (Weight: 0.6)
Logic: Substitution/Role mapping.
- Role Dictionary: Define roles (e.g.,
RAMP,CARD_DRAW,REMOVAL). - Mapping: If both cards share the same
Role_IDbased on their Functional Tokens, create a link.
Tier C: Strategic Archetypes (Weight: 0.3)
Logic: Thematic co-occurrence.
- Archetype Buckets: Define keyword groups (e.g.,
GRAVEYARD_STRAT= ["mill", "graveyard", "reanimate"]). - Density Check: If both cards have a high overlap of keywords from the same bucket, create a link.
5. Phase 3: Database Schema (PSQL)
Implement the following schema:
Table: cards
card_id: UUID (Primary Key)name: VARCHARoracle_text: TEXTmana_cost: VARCHARcolor_identity: ARRAY[VARCHAR]tags: ARRAY[VARCHAR] (Stored functional tokens and tribes)
Table: synergy_types
type_id: INT (Primary Key)label: VARCHAR (e.g., 'Tribal', 'Mechanical', 'Substitute')
Table: card_connections
card_id_a: UUID (FK\rightarrowcards)card_id_b: UUID (FK\rightarrowcards)type_id: INT (FK\rightarrowsynergy_types)weight: FLOAT- Constraint:
CHECK (card_id_a < card_id_b)to prevent bidirectional duplicates.
6. Phase 4: Execution Pipeline
The script must execute in the following order:
- Ingest: Parse JSON
\rightarrowBulk load intocardstable. - Analyze: Run
TextProcessor\rightarrowUpdatecards.tags. - Map:
- Iterate through card pairs.
- Evaluate Tiers A, B, and C.
- Insert identified synergies into
card_connections.
- Index: Create B-Tree indices on
card_id_aandcard_id_b.
7. Phase 5: Recommendation Logic (API Level)
The resulting database must support the following query logic for the API:
- Input: A list of
card_idscurrently in a deck. - Query: Find all
card_id_blinked to any of the input IDs incard_connections. - Aggregate: Sum the
weightfor each suggested card. - Filter: Remove suggestions that do not match the
color_identityof the deck. - Output: Return the top
Ncards sorted by aggregate weight.