Draftmancer Custom Card List Format

  1. Cube
  2. Advanced Card Specification
  3. Simple Layout
  4. Settings
  5. Sheets
  6. Pack Layouts
  7. Custom Cards

Cube

The simplest Custom Card List is a list of card names, one per line (see Advanced Card Specification). This will define a Cube, meaning packs will be composed of 15 (configurable) random cards from the list without replacement and without regards for their rarity.

Pack collation can be further customized by specifying Slots and Layouts (see below).

Note: Using a Custom Card List disables the following options: Restrict to Collection, Maximum rarity, Maximum duplicate copies and Foil.

Advanced Card Specification

Full syntax for a card line is inspired by the Arena Import/Export format and is defined as follows:
[Count] CardName [(Set) [CollectorNumber]]
All parameters between brackets ([]) are optional, only the card name is required.

Examples

The four following lines are equivalent and will add one copy of 'Incubation Druid' from Ravnica Allegiance. Here the set and collector number are both redundant as there's only one printing of the card (in Arena, and as of May 2020 :)):
1 Incubation Druid (RNA) 131
1 Incubation Druid (RNA)
1 Incubation Druid
Incubation Druid
This will add 8 copies of the full art "Unset" Forest:
8 Forest (ANA) 60
This will add one copy of each of the two version (#243 & #244) of the Azorius Guildgate of RNA:
1 Azorius Guildgate (RNA) 243
1 Azorius Guildgate (RNA) 244

Simple Layout

By specifying some card lists (hereafter named 'sheets') and card counts, you can create a simple pack layout. The following example mimicks a basic rarity distribution. For more customization, skip this section and continue reading :)

[SlotName(CardsPerBooster)]
Card Name 1
Card Name 2
...
[Slot2Name(CardsPerBooster)]
Card Name 3
Card Name 4
...
Each slot will be present in each booster. For example:
[Common(10)]
Card Name 1
Card Name 2
...
[Uncommon(3)]
Card Name 3
Card Name 4
...
[Rare(1)]
Card Name 5
Card Name 6
...

Will mimic the distribution of a standard Magic booster, except for the 1/8 Mythic/Rare ratio. Cards in the 'Common' slot don't have to be 'real' commons!

The following adds a Planeswalker in each pack:

[Planeswalker(1)]
Planeswalker Card Name 1
Planeswalker Card Name 2
...
[Common(9)]
Card Name 1
Card Name 2
...
[Uncommon(3)]
Card Name 3
Card Name 4
...
[Rare(1)]
Card Name 5
Card Name 6
...

Color balancing (if enabled) will be used only on the largest slot (in terms of cards per booster) and if it consist of at least 5 cards per booster. In both previous examples, the 'Common' slot will be color balanced if the option is enabled (which is the default value).

Settings

As the first section, you can declare a Settings block followed by a JSON object to control some global behaviors of your list.

[Settings]
{
	"settingName": "value",
	"anotherSetting": 125
}
				

Here are the possible settings with their description:

{
	name: string;                       // The name of your cube.
	cardBack: string;                   // URL to a custom card back.
	cardTitleHeightFactor: number;      // Allows you to adjust the height of the card title when stacked in a column. Defaults to 1.
	showSlots: boolean;                 // If layouts are used, will display what slot generated which card.
	                                    //   If you want multiple slots to be displayed with the same name, use "##" to add a hidden identifier.
		                                //   For example, "Rare" and "Rare##Legendary" will both be displayed as "Rare".
	
	// The following properties provide default values for some session settings, applied when the list is uploaded.
	// They can still be overridden by the user via the UI.
	boostersPerPlayer: number;          // Specify the default value of the "boostersPerPlayer" session setting.
	withReplacement: boolean;           // Specify the default value of the "withReplacement" session setting. When enabled, cards are in illimited quantities and their count only affect their probability of being selected (defaults to false).
	duplicateProtection: boolean;       // Specify the default value of the "duplicateProtection" session setting. Prevents duplicates within a booster (defaults to true).
	colorBalance: boolean;              // Specify the default value of the "colorBalance" session setting. Tries to include one card of each color in the largest slot (defaults to true).

	boosterSettings: {picks: number | number[], burns: number | number[]}[]; // Allows you to customize some settings on a per booster basis.
	// Example:
	"boosterSettings": [
		{
			"picks": 1,
			"burns": 14
		}, 
		{
			"picks": [2, 1], // Simulate the "Double Masters mode", with 2 picks right after openning the booster, then 1.
			"burns": 0
		}, 
		{
			"picks": [3, 2, 1], // For booster #3: pick 3 and burn 1, then pick 2 burn 0 and finally pick 1 burn 0 until the pack is empty.
			"burns": [1, 0]
		}
	]

	layouts: Record<string, PackLayout> | Array<{ name: string; count: number }>; // See below

	// Specify the exact order of the pack layouts rather than picking them randomly. Useful for block drafts. 
	//   Array of layout names, array of arrays of layout names (weights inherited from the layout declaration) 
	//   or array of Record<string, number> to override the weights.
	predeterminedLayouts: string[] | string[][] | Record<string, number>[] | {name: string, weight: number}[][];
	// Examples:
	"predeterminedLayouts": ["SheetA", "SheetB", "SheetC"],
	"predeterminedLayouts": [["Set1_Rare", "Set1_Mythic"], ["Set2_Rare", "Set2_Mythic"]]
	"predeterminedLayouts": [{"Set1_Rare": 7, "Set1_Mythic": 1}, {"Set2_Rare": 7, "Set2_Mythic": 1}]
	"predeterminedLayouts": [[{"name": "Set1_Rare", "weight": 7}, {"name": "Set1_Mythic", "weight": 1}], [{"name": "Set2_Rare", "weight": 7}, {"name": "Set2_Mythic", "weight": 1}]]

	// Specify if the layouts are randomly picked with or without replacement (default: true).
	layoutWithReplacement: boolean;    
}

Sheets

Sheets are simply card lists, with some optional properties. They can be refered to in the layouts section, and assigned to slots. Here's the syntax:

# Header: Name followed by optional properties (JSON)
[SheetName {"collation": "random"}]
Card Name 1 # Then a list of cards, as described above.
Card Name 2
...
				

Sheet settings:

{
		# "random" is the default. 
		# "printRun" means cards are picked sequentionally from a random starting point.
		# "striped" means cards are picked as per striped collation (from very early sets).
		"collation": "random" | "printRun" | "striped", 
		"groupSize": integer, # Only for "printRun". Forces the random start point to be a multiple of this value (default: 1).
		"length": integer,    # Only for "striped" (required). Specifies the length of each row.
		"weights": integer[], # Only for "striped" (required). Specifies the chances of different stripe widths.
}

# Examples:
[common]                                                               # Defaults to random collation.
[common {"collation": "striped", "length": 11, "weights": [0,1,1,1,1]} # Uses striped collation from a sheet with 11 columns with equal chances of stripe widths 2, 3, 4, or 5.
[common {"collation": "printRun"}]                                     # Uses sequential collation, wraps from end to start
[special {"collation": "printRun","groupSize":2}                       # Uses sequential collation but can only start on 1st, 3rd, 5th, etc

Pack Layouts

For even more control, you can specify multiple Pack Layouts describing variations of a pack, each with an associated weight (or probability to be chosen). Important Note: When using pack layouts, sheets must be declared without a CardsPerBooster parameter.

As part of the [Settings] header, the syntax of a layout is as follow:

"layouts": {
	"LayoutName" : {
		"weight": 1,
		"slots": {
  			"SlotName1": 7,
 			"SlotName2": 3
		}
	}
}

Where Weight is an integer specifying how often this layout will be chosen when generating a pack. By default, and for convenience, each slot will be filled with cards from the sheet with the same name. In this example, each pack will contain 7 cards picked from the sheet named SlotName1 and 3 cards picked from SlotName2 .

Example implementing a mythic rarity:

[Settings]
{
	"layouts": {
		"Rare": {
			"weight": 7,
			"slots": {
  				"Rare": 1,
  				"Uncommon": 3,
  				"Common": 10
			}
		},
		"Mythic": {
			"weight": 1,
			"slots": {
  				"Mythic": 1,
  				"Uncommon": 3,
  				"Common": 10
			}
		}
	}
}
[Common]
..Card List..
[Uncommon]
..Card List..
[Rare]
..Card List..
[Mythic]
..Card List..
# Alternatively, slots can refer to multiple sheets rather than relying having the same name as a sheet:
[Settings]
{
	"layouts": {
		"Default": {
			"weight": 1,
			"slots": [
				{
					"name": "RareOrMythic", 
					"count": 1, 
					"sheets": [
						{"name": "Rare",   "weight": 7}, 
						{"name": "Mythic", "weight": 1}
					]
				},
				{"name": "Uncommon", "count": 3 },
				{"name": "Common",   "count": 10},
			]
		}
	}
}
[Common]
..Card List..
[Uncommon]
..Card List..
[Rare]
..Card List..
[Mythic]
..Card List..

More complex example mimicking the collation of Dominaria United (Exactly one legendary creature of varying rarity in each pack):

[Settings]
{
	"name": "Dominaria United",
	"withReplacement": true,
	"layouts": {
		"Rare": {
			"weight": 21,
			"slots": {
				"Rare": 1,
				"UncommonLegendary": 1,
				"Uncommon": 2,
  				"Common": 10
			}
		},
		"Mythic": {
			"weight": 3,
			"slots": {
				"Mythic": 1,
				"UncommonLegendary": 1,
  				"Uncommon": 2,
  				"Common": 10
			}
		},
		"RareLegendary": {
			"weight": 7,
			"slots": {
				"RareLegendary": 1,
				"Uncommon": 3,
  				"Common": 10
			}
		},
		"MythicLegendary": {
			"weight": 1,
			"slots": {
				"MythicLegendary": 1,
  				"Uncommon": 3,
  				"Common": 10
			}
		}
	}
}
[Common]
..List of all non-Legendary Creature Commons..
[Uncommon]
..List of all non-Legendary Creature Uncommons..
[Rare]
..List of all non-Legendary Creature Rares..
[Mythic]
..List of all non-Legendary Creature Mythics..
[UncommonLegendary]
..List of all Uncommon Legendary Creatures..
[RareLegendary]
..List of all Rare Legendary Creatures..
[MythicLegendary]
..List of all Mythic Legendary Creatures..
# Another way to generate the same packs.
# You can use the 'sheets' property to assign multiple sheets to a slot.
# It will randomly select a sheet before picking the cards normally.
[Settings]
{
    "withReplacement": true,
    "layouts": {
        "UncommonLegendary": {
            "weight": 24,
            "slots": [
                {
					"name": "RareOrMythic", 
					"count": 1, 
					"sheets": [
						{"name": "Rare",   "weight": 7}, 
						{"name": "Mythic", "weight": 1}
					]
				},
                {"name": "UncommonLegendary", "count": 1 },
                {"name": "Uncommon",          "count": 2 },
                {"name": "Common",            "count": 10}
            ]
        },
        "RareOrMythicLegendary": {
            "weight": 8,
            "slots": [
                {
					"name": "RareOrMythicLegendary", 
					"count": 1, 
					"sheets": [
						{"name": "RareLegendary",   "weight": 7}, 
						{"name": "MythicLegendary", "weight": 1}
					]},
                {"name": "Uncommon", "count": 3 },
                {"name": "Common",   "count": 10}
            ]
        }
    }
}
[Common]
..List of all non-Legendary Creature Commons..
[Uncommon]
..List of all non-Legendary Creature Uncommons..
[Rare]
..List of all non-Legendary Creature Rares..
[Mythic]
..List of all non-Legendary Creature Mythics..
[UncommonLegendary]
..List of all Uncommon Legendary Creatures..
[RareLegendary]
..List of all Rare Legendary Creatures..
[MythicLegendary]
..List of all Mythic Legendary Creatures..

Custom Cards

A cube can also be composed of user-defined cards specified as JSON data. The CustomCards section must be the first one in the file. Once defined in this section, custom cards can be refered to by name in sheets, just like regular cards.
[CustomCards]
[
	{	
		"name": "My 1st Custom Card",
		"rarity": "mythic",
		"mana_cost": "{2}{W}{W}",
		"type": "Legendary Creature",
		"subtypes": [
			"God"
		],
		"image": "https://domain.com/URL/to/image.png"
	},	
	{	
		"name": "My 2nd Custom Card",
		"mana_cost": "{W/B}{G}",
		"type": "Instant",
		"image_uris": {
			"en": "https://domain.com/URL/to/image2.png",
			"fr": "https://domain.com/URL/to/image2_fr.png"
		},
		"printed_names": {
			"en": "My 2nd Custom Card",
			"fr": "Ma deuxième carte personnalisée"
		},
		"back": {
			"name": "Back of my 2nd Custom Card",
			"printed_names": {
				"en": "Back of my 2nd Custom Card",
				"fr": "Dos de ma deuxième carte personnalisée"
			},
			"image_uris": {
				"en": "https://domain.com/URL/to/image2_back.png",
				"fr": "https://domain.com/URL/to/image2_back_fr.png"
			},
			"type": "Land",
			"subtypes": [
				"Forest"
			]
		}
	}
]
[MainSheet(15)]
4 My 1st Custom Card
4 My 2nd Custom Card
... Standard Card List ...

You can define multiple printings of the same card by varying the set and/or the collector number while keeping the name. Referring to these cards by name only (without specifying a set and a collector number) will always mean the first occurence. Duplicate cards by name will inherit all the properties of the first occurence, meaning that besides the name you only have specify the properties that are actually modified in the other printings. In the following example, only the first 'Nazgûl' has all the properties, the other ones will be completed automatically. Note how you can now refer to individual printings using the 'CardName (SET) Number' syntax.

[Settings]
{ "withReplacement": true } 
[CustomCards]
[
	{
		"name": "Nazgûl",
		"rarity": "uncommon",
		"mana_cost": "2B",
		"set": "ltr",
		"collector_number": "100", 
		"type": "Creature",
		"image": "https://cards.scryfall.io/large/front/8/3/833936c6-9381-4c0b-a81c-4a938be95040.jpg?1686968640"
	},
	{
		"name": "Nazgûl",
		"collector_number": "332",
		"image": "https://cards.scryfall.io/large/front/c/e/ce65226a-12cd-416a-bb60-12e9b35f609b.jpg?1686971256"
	},
	{
		"name": "Nazgûl",
		"collector_number": "333",
		"image": "https://cards.scryfall.io/large/front/6/9/69b32f90-b32f-41a6-af0c-1c967ec49b73.jpg?1686971268"
	},
	{
		"name": "Card related to Nazgûl somehow",
		"rarity": "uncommon",
		"mana_cost": "",
		"type": "Emblem",
		"image": "https://cards.scryfall.io/large/front/7/2/7215460e-8c06-47d0-94e5-d1832d0218af.jpg?1688215133",
		"related_cards": [
			"Nazgûl",
			"Nazgûl (LTR) 100",
			"Nazgûl (LTR) 332",
			"Nazgûl (LTR) 333"
		]
	}
]
[DefaultSheet]
Nazgûl
Nazgûl (LTR) 100
Nazgûl (LTR) 332
Nazgûl (LTR) 333
Card related to Nazgûl somehow

Full Card specification ('?' denotes an optional field):

CardFace {
	name: string;
	image_uris?: { [lang: string]: URL }; // Images for the card for each language.
	image?: URL; // Shortcut for image_uris.en. Use it instead of image_uris if you don't need to support multiple languages.
	type: string;
	printed_names?: { [lang: string]: string };
	subtypes?: Array<string>;
	oracle_text?: string; // Oracle text.
	power?: number | string; // Creature power
	toughness?: number | string; // Creature toughness
	loyalty?: number | string; // Planeswalker loyalty
}

CustomCard {
	name: string;
	mana_cost: string;
	type: string;
	image_uris?: { [lang: string]: URL }; // Images for the card for each language.
	image?: URL; // Shortcut for image_uris.en. Use it instead of image_uris if you don't need to support multiple languages.
	printed_names?: { [lang: string]: string };
	colors?: Array<"W" | "U" | "B" | "R" | "G">;
	set?: string;	
	collector_number?: string;
	rarity?: string;
	subtypes?: Array<string> = [];
	rating?: number = 0; // A rating of the strength of the card in a vacuum, between 0 and 5. This may help bots navigate drafts when they don't know any cards :^)
	layout?: string;
	back?: CardFace;
	related_cards?: Array<CardID | CardFace>; // You can use this field to display some related cards when right clicking on the card. CardID can be the name of another custom card, or a Scryfall ID.
	draft_effects?: Array<DraftEffect>; // See the list of valid effects bellow.
	foil?: boolean; // Override the default finish of the card
	oracle_text?: string; // Oracle text. 
	power?: number | string; // Creature power
	toughness?: number | string; // Creature toughness
	loyalty?: number | string; // Planeswalker loyalty
}
The mana cost field follows Scryfall Symbology (e.g. "{5}{G}{G}"). The image_uris and printed_names fields are objects with the language as key and the localized image URL or name as value (see previous example).

Draft Effects

You can apply some effects from Conspiracy cards to your custom cards using the draft_effects field. Here are the implemented effects:
# On pick effects:
FaceUp              # Reveal the card to other players and mark the card as face up. Important note: Necessary for most 'UsableEffects" to function correctly!.
Reveal              # Reveal the card to other players
NotePassingPlayer   # Note the previous player's name on the card.
NoteDraftedCards    # Note the number of cards drafted this round, including this card.
ChooseColors        # Note colors chosen by your neighbors and you.
AetherSearcher      # Reveal and note the next drafted card.
CanalDredger        # The last card of each booster is passed to you.
ArchdemonOfPaliano  # Pick the next 3 cards randomly.
# Optional on pick effects:
LoreSeeker          # "You may add a booster pack to the draft".
# Usable effects (when the card is already in the player's pool):
RemoveDraftCard     # Remove the picked card(s) from the draft and associate them with the card.
CogworkLibrarian    # Replace this card in a pack for an additional pick.
AgentOfAcquisitions # Pick the whole booster, skip until next round.
LeovoldsOperative   # Pick an additional card, skip the next booster.
NoteCardName        # Note the picked card's name on the card.
NoteCreatureName    # Note the picked creature's name on the card.
NoteCreatureTypes   # Note the picked creature's types on the card.
# Other:
TrackRemovedCardsNames     # Will display the names of cards removed by the 'RemoveDraftCard' effect.
TrackRemovedCardsSubtypes  # Will display the unique subtypes of cards removed by the 'RemoveDraftCard' effect.
CogworkGrinder             # Will display the number of cards removed by the 'RemoveDraftCard' effect.

# Example value for Cogwork Librarian
"draft_effects": [
	"FaceUp",
	"CogworkLibrarian"
]

# The following effects are custom and do not match official Conspiracy effects.
AddCards            # Adds additional cards to your draft pool.

# Example value for AddCards
"draft_effects": [
	{
		"type": "AddCards",
		"count": 1, # Optional, if omitted, all cards from the following array will be added. Otherwise, 'count' random cards will be added to your pool.
		"cards": ["Card Name 1", "Card Name 2"...],
		"duplicateProtection": true, # Optional, defaults to true. Duplicates of the same card can be used to increase its probability of being picked.
	}
]
Please note that only the combinations of effects found on actual Conspiracy cards are officially supported, some might not work as intended! See the list of supported official cards on this page of the GitHub wiki .

Comments

Comments starts with # and must be on their own line. They're ignored by the application and can be used to document your file.

# Cube File by Myself
# Written on this day
[Settings]
{
	# This enables picking with replacement
	"withReplacement": true
}
# This sheet contains all the cards because this is just an example of how to use comments!
[DefaultSheet]
Lightning Bolt