Skip to main content

dominion-setup is a Python library and CLI tool to set up a game of Dominion, the classic deck-building game.

Project description

dominion-setup

PyPI Supported Python Versions CI Test Documentation Status OpenSSF Best Practices

dominion-setup is a Python library and CLI tool to set up a game of Dominion, the classic deck-building game.

Features

  • Complete card database — ships with JSON data for every Dominion set released to date: Base, Intrigue, Seaside, Alchemy, Prosperity, Cornucopia & Guilds, Hinterlands, Dark Ages, Adventures, Empires, Nocturne, Renaissance, Menagerie, Allies, Plunder, Rising Sun, and Promo cards.
  • Edition-aware — correctly handles 1st and 2nd edition differences for Base, Intrigue, Seaside, Prosperity, Cornucopia & Guilds, and Hinterlands.
  • Rules-accurate generation — automatically applies all official setup rules, including:
    • Selecting 10 random Kingdom piles from the chosen set(s).
    • Drawing up to a configurable number of Landscape cards (Events, Landmarks, Projects, Ways, Traits).
    • Adding extra piles required by specific cards (Bane for Young Witch, Ferryman pile, Way of the Mouse pile, Riverboat pile, Approaching Army pile, Traveller chains for Page and Peasant, Prizes for Tournament, Rewards for Joust, Spirit/Zombie/Imp/Ghost piles for Nocturne cards, Artifacts for Flag Bearer / Border Guard / Treasurer / Swashbuckler, Loot, Horse pile, and more).
    • Choosing an Ally when any Liaison card is in the Kingdom.
    • Choosing a Prophecy when any Omen card is in the Kingdom.
    • Assigning Traits to random Action/Treasure Kingdom piles.
    • Randomly determining Colony/Platinum and Shelters based on Prosperity/Dark Ages representation, or allowing you to force them on or off.
    • Deriving the correct Potion, Ruins, and Heirloom basic piles.
    • Collecting all required materials (mats, tokens, cubes) and per-card setup instructions.
  • Flexible sorting — kingdom piles can be sorted by cost, name, or set.
  • Rich terminal output — the CLI renders colour-coded tables with Rich.
  • Fully typed — ships with a py.typed marker and complete type annotations.

Design

Architecture

The package is structured around four modules:

Module Responsibility
models Immutable dataclasses and enums (Card, CardCost, CardSet, Game, Pile, …)
loader Reads the bundled JSON data files and populates a CardDatabase
generator generate_game() — pure function that turns a CardDatabase into a Game
cli Click/Rich-Click command group (generate, list-cards, list-sets)

Card data

Every card in every set is stored in a small JSON file under dominion_setup/data/cards/. Each entry records the card's name, types, purpose (Basic, Kingdom Pile, Landscape, Mixed Pile Card, Non-Supply, Status), cost (coins, Potion, debt), set, supported edition(s), supply quantity, and the full instruction text used to derive materials and setup notes.

{
  "name": "Artisan",
  "types": ["Action"],
  "purpose": "Kingdom Pile",
  "cost": {"coins": 6},
  "set": "Base",
  "editions": [2],
  "quantity": 10,
  "image": "Artisan.jpg",
  "instructions": "Gain a card to your hand costing up to $5.\nPut a card from your hand onto your deck."
}

Generation algorithm

generate_game() performs the following steps in order:

  1. Build candidate pools — optionally restricted to particular sets and editions.
  2. Draw the Kingdom — randomly draw cards from the combined kingdom + landscape pool until 10 Kingdom piles are chosen, with landscapes drawn opportunistically up to max_landscapes.
  3. Resolve special piles — inspect the chosen Kingdom by name and type to add all rule-mandated extra piles and marks (Bane, Ferryman, Obelisk, Traits, Approaching Army, …).
  4. Resolve non-supply piles — Traveller chains, Spirit/Zombie piles, Prizes, Rewards, Loot, Horse, Artifacts, etc.
  5. Resolve basic supply — standard basics plus conditional Colony/Platinum, Potion, Ruins, Shelters, and Heirlooms.
  6. Collect materials — scan instruction text with regex and card types to determine which mats and tokens are needed.
  7. Collect setup instructions — extract Setup: sentences from card instructions and synthesise Heirloom setup text.
  8. Sort and return a fully populated Game object.

Installation

dominion-setup is available on PyPI. Install with uv or your package manager of choice:

uv add dominion-setup

You can also install the command-line interface of dominion-setup as a tool that is available on the PATH (i.e., globally):

uv tool install dominion-setup

Documentation

Check out the dominion-setup documentation for the User's Guide, API Reference and CLI Reference.

Usage

As a Library

Quick start — generate a random setup

from dominion_setup import load_card_database, generate_game

# Load the bundled card database (all sets, all editions)
db = load_card_database()

# Generate a random game — by default draws from ALL sets and editions
game = generate_game(db)

# Inspect the result
for pile in game.kingdom_piles:
    marks = f" [{', '.join(str(m) for m in pile.marks)}]" if pile.marks else ""
    print(f"  {pile.card.name} ({pile.card.cost}){marks}")

Choosing specific sets and editions

from dominion_setup import load_card_database, generate_game
from dominion_setup.models import CardSet, CardSetEdition, KingdomSortOrder

db = load_card_database()

game = generate_game(
    db,
    sets_editions={
        (CardSet.BASE, CardSetEdition.SECOND_EDITION),
        (CardSet.INTRIGUE, CardSetEdition.SECOND_EDITION),
        (CardSet.PROSPERITY, CardSetEdition.SECOND_EDITION),
    },
    sort_order=KingdomSortOrder.NAME,  # sort kingdom by name
    use_colony=True,  # always include Colony/Platinum
    use_shelters=False,  # never use Shelters
    max_landscapes=1,  # at most 1 landscape card
)

Exploring the Game object

from dominion_setup import load_card_database, generate_game

db = load_card_database()
game = generate_game(db)

# Sets used in this game
print("Sets:", ", ".join(str(s) for s in game.sets_used))

# Kingdom piles (always 10, plus any special extras such as Bane)
for pile in game.kingdom_piles:
    print(
        f"  {pile.card.name:25s} {str(pile.card.cost):>5}  {', '.join(pile.card.types)}"
    )

# Landscape cards (Events, Landmarks, Projects, Ways, Traits)
if game.landscapes:
    print("Landscapes:")
    for card in game.landscapes:
        print(f"  {card.name}")

# Ally (present when any Liaison card is in the Kingdom)
if game.ally:
    print("Ally:", game.ally.name)

# Prophecy (present when any Omen card is in the Kingdom)
if game.prophecy:
    print("Prophecy:", game.prophecy.name)

# Druid Boons (present when Druid is in the Kingdom)
if game.druid_boons:
    print("Druid Boons:", ", ".join(b.name for b in game.druid_boons))

# Non-supply piles (Prizes, Rewards, Traveller chains, Spirits, …)
if game.non_supply_piles:
    print("Non-Supply:")
    for pile in game.non_supply_piles:
        print(f"  {pile.card.name}")

# Basic supply (Copper, Silver, Gold, Estate, Duchy, Province, Curse,
#               + conditional Colony/Platinum, Potion, Ruins, Shelters, Heirlooms)
for pile in game.basic_piles:
    print(f"  {pile.card.name}")

# Required mats and tokens
if game.materials:
    print("Materials:", ", ".join(str(m) for m in game.materials))

# Per-card setup instructions
for instruction in game.setup_instructions:
    print(f"  • {instruction}")

Querying the card database

from dominion_setup import load_card_database
from dominion_setup.models import CardSet, CardSetEdition, CardType, CardCost

db = load_card_database()

# All kingdom cards in Nocturne
nocturne_cards = db.get_cards_by_set_edition(
    CardSet.NOCTURNE, CardSetEdition.FIRST_EDITION
)
print(f"Nocturne has {len(nocturne_cards)} kingdom cards")

# All Action–Attack cards
attack_actions = [
    card
    for card in db.kingdom_cards.values()
    if CardType.ACTION in card.types and CardType.ATTACK in card.types
]

# All kingdom cards that cost $5
five_cost = db.get_cards_by_cost(CardCost(coins=5))

# Look up a card by name
village = db.get_card_by_name("Village")
print(village.name, village.cost, village.instructions)

As a CLI Tool

The dominion-setup command groups three sub-commands. Running it with no arguments is equivalent to dominion-setup generate.

dominion-setup generate — generate a random setup

Generate a random game from the Base 2nd edition (the default):

dominion-setup generate

Mix Intrigue 2e and Seaside 2e, sorted by name:

dominion-setup generate --set intrigue_2e --set seaside_2e --sort name

Use all cards from Dark Ages (always include Shelters, never Colony):

dominion-setup generate --set dark_ages --shelters --no-colony

Allow up to three landscape cards, mix Base 2e with Adventures:

dominion-setup generate --set base_2e --set adventures --max-landscapes 3

Force Colony/Platinum on when playing with a Prosperity mix:

dominion-setup generate --set base_2e --set prosperity_2e --colony

dominion-setup list-cards — browse the card database

List all kingdom cards sorted by cost (default):

dominion-setup list-cards

List only Base 2e cards:

dominion-setup list-cards --set base_2e

List all Attack cards across Base 2e and Intrigue 2e:

dominion-setup list-cards --set base_2e --set intrigue_2e --type attack

List all Action–Duration cards that cost exactly $4:

dominion-setup list-cards --type action --type duration --cost 4

List all Nocturne Night cards, sorted by name:

dominion-setup list-cards --set nocturne --type night --sort name

dominion-setup list-sets — list available sets

dominion-setup list-sets

This prints a table of every supported set (and edition, where applicable) together with its kingdom card count:

              Sets
 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
 ┃ Set                            ┃ Kingdom Cards ┃
 ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
 │ Base, 1E                       │            26 │
 │ Base, 2E                       │            26 │
 │ Intrigue, 1E                   │            26 │
 │ ...                            │           ... │
 └────────────────────────────────┴───────────────┘

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dominion_setup-2026.1.0.tar.gz (82.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dominion_setup-2026.1.0-py3-none-any.whl (80.6 kB view details)

Uploaded Python 3

File details

Details for the file dominion_setup-2026.1.0.tar.gz.

File metadata

  • Download URL: dominion_setup-2026.1.0.tar.gz
  • Upload date:
  • Size: 82.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dominion_setup-2026.1.0.tar.gz
Algorithm Hash digest
SHA256 0d05addec35aeb4595125c35cac0cdb6bf48abf2b07ecc5e1bdecb4b297afe33
MD5 7384c9845e891b6868711a9d58208c1a
BLAKE2b-256 b0be62b6d034696c3de26596677cbb329d1e934edcd0bcc7d3d5b7579d666304

See more details on using hashes here.

File details

Details for the file dominion_setup-2026.1.0-py3-none-any.whl.

File metadata

  • Download URL: dominion_setup-2026.1.0-py3-none-any.whl
  • Upload date:
  • Size: 80.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dominion_setup-2026.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 020409adee0bca065238a20e2fc6bffc79ce934846672fa5adf2d4ad599aca36
MD5 4cb5f82b26e385ebff3c42a2ab16c01d
BLAKE2b-256 c39fbc6f4b6ac52464250e67d8f9776815ae4fd76a313ed96151e17b9f459527

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page