Files
tarot/docs/REGISTRY_MAPPING.md
nose 79d4f1a09e k
2025-11-25 22:19:36 -08:00

3.8 KiB

Registry System: Position-Based Card Details

Overview

The registry uses a position-based lookup system that maps card positions (1-78) to interpretive data stored in CardDetailsRegistry. This system is independent of card names, allowing the same registry entries to work across different deck variants.

Design Principle

Card position is the permanent identifier, not the card name. This means:

  • Card #44 is always "Magus position" in the deck order
  • If you rename card #44 to "Magus", "Magician", "Mage", or any other variant, it still maps to the same registry entry
  • Different deck variants can have completely different names but use the same spiritual/interpretive data

File Organization

Your deck files follow this numbering (which drives card position):

  • 1-14: Cups (Ace, Ten, 2-9, Knight, Prince, Princess, Queen)
  • 15-28: Pentacles/Disks (same structure)
  • 29-42: Swords (same structure)
  • 43-64: Major Arcana (43=Fool, 44=Magus, ..., 64=Universe)
  • 65-78: Wands (same structure)

Example: 44_Magus.webp → Card at position 44 → Magus name → Registry position 44 → Details for position 44

Position-Based Lookup Process

Card created with number (position)
    ↓
card.number = 44
    ↓
load_into_card(card)
    ↓
get_by_position(44)
    ↓
Position 44 maps to registry key "I" (1st trump after Fool)
    ↓
registry.get("I") → Returns Magician/Magus details
    ↓
Details loaded into card object (independent of card.name)

Position Mapping

Minor Arcana Positions:

  • 1-14: Cups - Maps to "Ace of Cups" through "Queen of Cups"
  • 15-28: Pentacles - Maps to "Ace of Pentacles" through "Queen of Pentacles"
  • 29-42: Swords - Maps to "Ace of Swords" through "Queen of Swords"
  • 65-78: Wands - Maps to "Ace of Wands" through "Queen of Wands"

Major Arcana Positions:

  • 43 → "o" (Roman for 0/Fool)
  • 44 → "I" (Roman for 1/Magus)
  • 45 → "II" (Roman for 2)
  • ...continuing through...
  • 64 → "XXI" (Roman for 21/Universe)

Implementation

def _build_position_map(self) -> Dict[int, str]:
    """
    Maps card position (1-78) to registry key:
    - Minor Arcana: position → card name ("Ace of Cups", etc.)
    - Major Arcana: position → Roman numeral ("o", "I", "II", etc.)
    """
    # Builds complete 1-78 mapping
    return position_map

def get_by_position(self, position: int) -> Optional[Dict[str, Any]]:
    """Get details for a card by its position (1-78)."""
    registry_key = self._position_map.get(position)
    return self._details.get(registry_key)

def load_into_card(self, card: 'Card') -> bool:
    """Load card details using position-based lookup."""
    details = self.get_by_position(card.number)
    # Populate card with: explanation, interpretation, keywords, etc.

Why Position-Based?

  1. Deck Variant Independence: Different decks can use completely different names
  2. Stable Identity: Card position never changes across variants
  3. Scalable: Easily support new deck variants by just changing card names
  4. Future Proof: New interpretations can be added keyed to positions, not names

Example Flow

File: 44_Magus.webp ↓ Card object: number=44, name="Magus", arcana="Major" ↓ load_into_card(card) called ↓ get_by_position(44) returns registry key "I" ↓ Registry lookup: registry.get("I") ↓ Populates card with Magician/Magus interpretation:

  • keywords: ["manifestation", "resourcefulness", ...]
  • interpretation: "Communication; Conscious Will; ..."
  • guidance: "Focus your energy and intention..."

Key Point

Even if you rename card #44 to something completely different, it will still load the same interpretation because the lookup is based on position (44), not name ("Magus").

↓ Registry lookup: registry.get("o") ↓ Populates card with: explanation, interpretation, keywords, etc.