CwCardUtils ↑

A Ruby gem for analyzing Magic: The Gathering decklists and calculating various metrics.

Features ↑

Requirements ↑

Installation ↑

Add this line to your application’s Gemfile:

gem 'cw_card_utils'

And then execute:

bundle install

Or install directly:

gem install cw_card_utils

Quickstart ↑

require "cw_card_utils"

decklist_a = <<~DECK
4 Lightning Bolt
4 Monastery Swiftspear
20 Mountain
DECK

decklist_b = <<~DECK
4 Counterspell
4 Memory Deluge
4 Supreme Verdict
24 Island
DECK

a = CwCardUtils::DecklistParser::Parser.new(decklist_a).parse
b = CwCardUtils::DecklistParser::Parser.new(decklist_b).parse

puts a.archetype                  # => e.g., "Mono-Red Aggro"
puts a.color_identity_string      # => "Red"
puts a.collapsed_normalized_curve # => { "0-1"=>..., "2"=>..., ... }

cmp = CwCardUtils::DeckComparator.new(a, b)
pp cmp.compare[:on_play] # => win_rate_a, favored, notes, etc.

Configuration ↑

You can configure the card data source used by the library:

# In a Rails initializer (config/initializers/cw_card_utils.rb)
CwCardUtils.configure do |config|
  config.card_data_source = MyCustomDataSource.new
end

# Or set it directly
CwCardUtils.card_data_source = MyCustomDataSource.new

The default data source is CwCardUtils::ScryfallCmcData.instance, which loads card data from a local JSON file.

Usage ↑

Deck Parsing and Formats ↑

require 'cw_card_utils'

decklist = <<~DECK
  4 Lightning Bolt
  4 Mountain
  2 Shock
DECK

deck = CwCardUtils::DecklistParser::Parser.new(decklist).parse

# Common accessors
puts deck.mainboard_size  # => 10
puts deck.color_identity  # => ["R"]
puts deck.archetype       # => "Mono-Red Aggro" (string label)
puts deck.format          # => :standard, :modern, :commander (heuristic)

Parses common formats (MTGA, MTGO, Moxfield). Sideboard sections are detected (e.g., lines starting with “Sideboard”).

Curves and Summaries ↑

deck.curve                    # => { 0=>2, 1=>8, 2=>6, 3=>4, ... }
deck.normalized_curve         # => { 1=>0.22, 2=>0.18, ... }
deck.collapsed_curve          # => { "0-1"=>10, "2"=>6, "3"=>4, ... }
deck.collapsed_normalized_curve

Archetype Detection and Tags ↑

deck.archetype            # => "Izzet Control", "Selesnya Midrange", etc.
deck.main.first.tags      # => [:interaction, :draw, :etb, ...]
deck.color_identity_string# => "Azorius"

Synergy Probabilities ↑

sp = CwCardUtils::SynergyProbability.new(deck, deck_size: deck.size)
sp.prob_single(["Lightning Bolt"], 7)    # => Float 0..1
sp.prob_combo(["Card A", "Card B"], 10)  # => Float 0..1

Deck Comparison (Matchup) ↑

cmp = CwCardUtils::DeckComparator.new(deck_a, deck_b)
pp cmp.compare # => { on_play: {...}, on_draw: {...} }

Generating API Docs (RDoc) ↑

Bilingual (EN/JA) RDoc is embedded in the source. Generate HTML docs:

rdoc -f darkfish -o doc lib README.md --title "Crackling Wit: Card Utilities" --exclude '\.json$'

Then open doc/index.html.

Custom Data Sources ↑

You can implement your own card data source by inheriting from CwCardUtils::CardDataSource:

class MyCustomDataSource < CwCardUtils::CardDataSource
  def find_card(name)
    # Your implementation here
    # Should return a hash with card data or nil
  end
end

# Configure the library to use your data source
CwCardUtils.card_data_source = MyCustomDataSource.new

Development ↑

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing ↑

Bug reports and pull requests are welcome on GitHub at github.com/cracklingwit/cw_card_utils.

Data Sources ↑

The default data source for this gem is an extraction from the wonderful Scryfall Bulk Data set. It is intended to be used only to test the functionality of the gem and serve as a fallback source of data.

You should use your own source, preferably backed by a database that conforms to our card_data_source API for your own production projects.

A huge, huge thank you to the wonderful folks at Scryfall for the hard work they put into keeping their data accurate, up to date, and free for the community to use. We are not endorsed or supported by Scryfall in any way.

Fan Content Policy ↑

Crackling Wit’s Card Utils gem is unofficial Fan Content permitted under the Fan Content Policy. It is not approved/endorsed by Wizards. Portions of the materials used are property of Wizards of the Coast. © Wizards of the Coast LLC.