Skip to main content
Mana optimization is critical for any multi-color Magic deck. The MTG Deck Builder automatically analyzes your mana base to ensure you have sufficient sources of each color, accounting for multi-color lands, fetch lands, and color requirements across your deck.

Multi-color mana source handling

The tool tracks which colors each land can produce using the ProducibleManaColors property:

Mana color representation

  • Single color lands: "G" (Forest), "U" (Island), etc.
  • Dual lands: "B,G" (Overgrown Tomb), "U,W" (Hallowed Fountain)
  • Colorless sources: "C" (Wastes, generic colorless)
  • Fetch lands: "F" (indicates fetching capability)
  • Five-color lands: "B,G,R,U,W" (Command Tower)
// From ProbabilityCell.js:38-42
if (this.props.card.type.includes('Land')) {
  let manapic = (this.props.card.ProducibleManaColors.includes('C') || 
                 this.props.card.ProducibleManaColors.includes('F')) ? 
                'Cmana.png' : 
                (this.props.card.ProducibleManaColors.split(',').join('').slice(0, 
                  Math.min(this.props.card.ProducibleManaColors.length, 2)) + 'mana.png')
}
Multi-color lands are particularly valuable because they count toward multiple color requirements simultaneously.

Fetch land support and compatibility

Fetch lands are handled with special logic to account for their color-fixing capabilities:

How fetch lands work

Fetch lands have a fetchOptions property that specifies which land types they can search for:
// Example: Flooded Strand
{
  name: "Flooded Strand",
  ProducibleManaColors: "F",
  fetchOptions: "Plains,Island"
}

Fetch land resolution

The manaToFetch function determines what colors a fetch land can produce:
// From ArithmaticHelpers.js:328-343
function manaToFetch(deck, fetchOptions) {
  deck = deck.filter(v => {
    return v.type.includes(fetchOptions.split(',')[0]) ||
           v.type.includes(fetchOptions.split(',')[1])
  })
  mana = deck.reduce((a, b) => {
    b.ProducibleManaColors.split(',').forEach(v => {
      if (!a.ProducibleManaColors.includes(v)) 
        a.ProducibleManaColors += v + ','
    })
    return a
  }, { ProducibleManaColors: '' })
  mana.ProducibleManaColors = mana.ProducibleManaColors.slice(0, -1)
  return mana
}
This function:
  1. Filters the deck for lands matching the fetch land’s fetchOptions
  2. Aggregates all colors those lands can produce
  3. Returns a consolidated list of producible colors
A Flooded Strand in a deck with Hallowed Fountain (W,U) and Watery Grave (U,B) can effectively produce White, Blue, or Black mana.

Fetch land integration in probability

When calculating probabilities, the algorithm:
  1. Separates fetch lands from other lands based on their utility for the specific card:
    // From ArithmaticHelpers.js:62-71
    let fetches = deck.filter(v => {
      if (v.ProducibleManaColors) {
        if (v.ProducibleManaColors.includes('F')) {
          return manaToFetch(deck, v.fetchOptions).ProducibleManaColors
            .split(',').reduce((a, b) => {
              return a || C[b] > 0  // C is the card's cost
            }, false)
        }
      }
      else return false
    })
    
  2. Adjusts mana costs when fetch lands are drawn, reducing color requirements by the fetched colors
  3. Sterilizes the deck by adding aggregate color tags to lands that can be enhanced by fetched lands:
    // From ArithmaticHelpers.js:105-112
    others = others.map(card => {
      if (card.ProducibleManaColors) {
        if (card.ProducibleManaColors.split(',').includes(colorsFetched[0])) 
          card.ProducibleManaColors += ',' + colorsFetched[0] + colorsFetched[1]
        else if (card.ProducibleManaColors.split(',').includes(colorsFetched[1])) 
          card.ProducibleManaColors += ',' + colorsFetched[0] + colorsFetched[1]
      }
      return card
    })
    
Fetch land calculations assume optimal play - that you’ll always fetch the land you need most. Real-game scenarios may vary based on information and sequencing.

Determining sufficient colored mana

The cardPlayable function performs a comprehensive check to determine if your deck can support a card:

Playability conditions

From ArithmaticHelpers.js:347-375:
function cardPlayable(draws, card, deck, startingHandSize = 7) {
  let cost = cardCost(card);
  let convertedManaCost = Object.keys(cost).reduce((a, b) => a + cost[b], 0);
  let manaBase = JSONmanaBase(deck);
  
  // 1. Turn condition: enough turns elapsed
  let turnCondition = draws - startingHandSize >= convertedManaCost - 1;
  
  // 2. Mana condition: enough total lands
  let manaCondition = 
    Object.keys(manaBase).reduce((a, b) => a + manaBase[b], 0) >= convertedManaCost;
  
  // 3. Color condition: enough of each required color
  delete cost.C  // Ignore colorless requirement
  let colorCondition = Object.keys(cost).reduce((a, b) => {
    Object.keys(manaBase).forEach(v => {
      if (v.split(',').includes(b)) {
        let min = Math.min(manaBase[v], cost[b]);
        cost[b] -= min;
        manaBase[v] -= min;
      }
    });
    return a && cost[b] <= 0;
  }, true);
  
  // 4. Includes condition: card is in deck
  let includesCondition = deck.map(v => v.name).includes(card.name);
  
  return colorCondition && manaCondition && turnCondition && includesCondition;
}

Color matching algorithm

The color condition check:
  1. Iterates through each required color in the card’s cost
  2. Matches lands that can produce that color (including multi-color lands)
  3. Allocates lands to color requirements using a greedy algorithm
  4. Ensures all colors have sufficient sources after allocation
Consider casting Absorb with cost {W}{U}{U}:Required:
  • 1 White mana
  • 2 Blue mana
Available lands:
  • 4 Hallowed Fountain (W,U)
  • 6 Island (U)
  • 3 Plains (W)
Color matching:
  1. For White requirement (1): Use 1 Hallowed Fountain
    • Remaining: 3 Hallowed Fountain, 6 Island, 3 Plains
  2. For Blue requirement (2): Use 2 Island
    • Remaining: 3 Hallowed Fountain, 4 Island, 3 Plains
Result: ✓ Playable - sufficient sources of both colors

ProducibleManaColors property

The ProducibleManaColors property is the foundation of mana analysis:

Creating the mana base JSON

From ArithmaticHelpers.js:297-305:
function JSONmanaBase(deck) {
  return deck.reduce((a, b) => {
    if (b.ProducibleManaColors) {
      if (a[b.ProducibleManaColors]) 
        a[b.ProducibleManaColors]++;
      else if (b.ProducibleManaColors !== 'false') 
        a[b.ProducibleManaColors] = 1;
    }
    return a;
  }, {});
}
This creates an object like:
{
  "U": 8,        // 8 Islands
  "W": 4,        // 4 Plains
  "U,W": 4,      // 4 Hallowed Fountains
  "F": 2         // 2 Fetch lands
}

Handling split mana cards

For cards with hybrid mana costs (e.g., {W/U}), the algorithm:
  1. Detects multi-character color codes in the card cost
  2. Sterilizes the deck by adding aggregate color properties to matching lands
  3. Treats the hybrid cost as satisfied by either color
// From ArithmaticHelpers.js:42-55
Object.keys(C).forEach(v => {
  if (isNaN(parseInt(v)) && v.length > 1) {
    deck = deck.map(card => {
      if (card.ProducibleManaColors) {
        if (card.ProducibleManaColors.split('').reduce((a, b) => {
          return a || v.includes(b)
        }, false)) {
          card.ProducibleManaColors += ',' + v
        }
      }
      return card
    })
  }
})
This sterilization process ensures hybrid mana requirements are correctly evaluated against available mana sources.

Converting mana cost to requirements

The cardCost function parses mana cost strings into structured requirements:

Mana cost parsing

From ArithmaticHelpers.js:309-324:
function cardCost(card) {
  return card.manaCost
    .split('{')
    .slice(1)
    .map(v => v.slice(0, -1))
    .reduce((a, b) => {
      if (Object.keys(a).includes(b)) {
        a[b]++;
      } else {
        if (!['B', 'G', 'W', 'R', 'U'].includes(b[0]))
          a.C = !isNaN(parseInt(b)) ? parseInt(b) : 0;
        else a[b] = 1;
      }
      return a;
    }, { C: 0 });
}

Example conversions

Mana CostParsed Object
{1}{U}{C: 1, U: 1}
{2}{U}{U}{C: 2, U: 2}
{W}{U}{B}{C: 0, W: 1, U: 1, B: 1}
{3}{G}{G}{C: 3, G: 2}
Where:
  • C = Colorless/generic mana (can be paid with any color)
  • W, U, B, R, G = Specific color requirements
Converted mana cost (CMC) is calculated by summing all values: Object.keys(cost).reduce((a, b) => a + cost[b], 0)

Best practices for mana base construction

Based on the optimization algorithm, follow these guidelines:

1. Match land counts to color intensity

  • For each colored mana symbol in your costs, aim for 5-8 sources of that color
  • Cards with multiple symbols of one color (e.g., {U}{U}) require more sources
  • Use the probability percentages to identify color deficiencies
If a 2-mana card shows low probabilities on turn 2-3, you likely need more sources of its required colors.

2. Leverage multi-color lands

  • Dual lands count toward multiple colors simultaneously
  • They’re most valuable in 2-color decks
  • In 3+ color decks, prioritize lands that produce your most-required colors

3. Use fetch lands strategically

  • Fetch lands provide maximum flexibility when you have multiple fetchable land types
  • Pair fetch lands with dual lands (e.g., Polluted Delta + Watery Grave + Underground Sea)
  • Fetch lands are most valuable in decks with 3+ colors

4. Consider converted mana cost curve

  • The tool validates: draws - 7 >= CMC - 1
  • This means a 3-mana card needs to be cast by turn 3 at earliest
  • Ensure you have enough lands to support your curve: generally 17-18 lands minimum

5. Test your mana base

  • Look at turn 2-3 probabilities for your early game cards
  • They should be 60%+ for consistent gameplay
  • If probabilities are low, add more lands or adjust color sources
The calculator assumes you’ll play one land per turn. If your deck has ramp or card draw, actual performance may exceed calculated probabilities.

Identifying mana base issues

Signs your mana base needs improvement

  1. Low early-game probabilities: 2-3 mana cards showing less than 40% by turn 3
  2. Zero probabilities: colorCondition is failing - add more sources of that color
  3. Inconsistent colors: Some colors have high probabilities while others are low
  4. Too few lands: manaCondition failing - increase total land count

Quick fixes

  • Need more of a color: Add dual lands or basic lands of that color
  • Color fixing issues: Add fetch lands or multi-color lands
  • Too few lands overall: Aim for 24-26 lands in most decks (40% of deck)
  • Too many colors: Focus on 2-3 main colors, splash others sparingly

Deck building

Build and manage your MTG deck

Probability calculator

Understand probability calculations

Build docs developers (and LLMs) love