A Discord bot to generate Magic: the Gathering (MTG) boosters and sealed pools
The bot responds to the following commands:
!random
: generates a random pack from the whole history of Magic!standard
: generates a random standard pack!explorer
: generates a random explorer pack!historic
: generates a random (non-alchemy) historic pack!chaossealed
: generates 6 random (non-alchemy) historic packs!from {setcodes}
: generates random packs from a list of sets separated by "|" (e.g.,!from inv|pls|apc
generates one pack at random from either Invasion, Planeshift, or Apocalypse)
!{setcode}
: generates a pack from the indicated set (e.g.,!znr
generates a Zendikar Rising pack)!{setcode}sealed
: generates 6 packs from the indicated set (e.g.,!znrsealed
generates 6 Zendikar Rising packs)!{setcode}box
: generates a draft boooster box from the indicated set (e.g.,!znrbox
generates 36 Zendikar Rising packs)!collector {setcode}
: generates a collector pack from the indicated set (e.g.,!collector znr
generates a Zendikar Rising collector booster)!arena {setcode}
or!a-{setcode}
: generates an arena draft pack from the indicated set (e.g.,!arena znr
generates a Zendikar Rising arena draft booster)
!jmp
: generates a ramdom Jumpstart deck (without Arena replacements)!a-jmp
: generates a ramdom Jumpstart deck (with Arena replacements)!j22
: generates a ramdom Jumpstart 2022 deck
!cube cube_id
: generates a pack from the cube indicated by the CubeCobra Cube IDcube_id
!cubesealed cube_id
: generates 6 packs from the cube indicated by the CubeCobra Cube IDcube_id
By default, the bot generates packs randomly taking 15 cards from the cube, with no repetition, unless the cube contains multiples of a card. No color or rarity balance is attempted on cube packs.
The bot is also able to generate different pack formats, by using tags and the custom draft format feature on CubeCobra. If your cube has a custom draft format, configured on CubeCobra using only tags, and you have tagged all cards in the cube accordingly, the bot will create a pack with slots following the given tag. Morevover, if you set up the custom draft format to allow any number of copies of a card, the bot will respect that setting as well. Note: the bot will only follow the first pack of the first custom draft format setup on CubeCobra.
Whenever a command generates more than one pack, a sealeddeck.tech link and ID are attached. The link goes to a sealed pool containing the generated cards. Moreover, the bot answers the following command:
!addpack xyz123
: if issued replying to packs generated by the bot, adds those packs to the previously generated sealeddeck.tech pool with IDxyz123
You can ask the bot the list of commands by typing !help
, or get help on a
specific command with !help {command_name}
.
-
While replying to any command, the bot will mention the user who issued it, unless the command is followed by a mention, in which case the bot will mention that user instead. For example,
!znr @user#1234
has the bot mention user#1234 (instead of you) in its reply. -
Most of the pack-generating non-sealed commands can take a number to generate more than one pack. For example
!random 3
will generate 3 random packs.
The bot should works on python 3.9+
. All dependencies are listed in
requirements.txt
and should be installed for the bot to run.
If you are interested in running the tests or doing development, you should also
install the dependencies in requirements-dev.txt
. The easiest way to setup
your environment correctly is by using the provided devcontainer.json
configuration file.
To host your own bot you will need a Discord token. Once you have procured those for yourself, follow these steps:
-
Make a
config.yaml
file (seeconfig_template.yaml
for help) -
Download MTGJson data by running:
python -m boostertutor mtgjson
- Run the bot:
python -m boostertutor
For a complete list of commands and parameters you can check the help by running:
python -m boostertutor -h
All booster data comes from mtgjson, an open-source project that catalogs all MTG cards.
MTG boosters are not purely random, mathematically speaking. They are generated by collating together cards from print sheets in specific orders, this is what is kind of known in the limited world as "print run". How this is performed is not publicly disclosed by Wizards, but in practice the process generates boosters which enforce some desirable properties for limited play (like color balancing and no duplicates).
To try to produce boosters which feel similar to real MTG boosters, Booster Tutor uses what is known as Reuben's algorithm.
Reuben's algorithm
First, generate a booster using a pure random algorithm, then check against the following rules, and if any of the rules aren't met, generate a new booster. Repeat until a booster that conforms to the rules is generated. The rules are:
- A pack must never have more than 4 commons of the same color
- A pack must have at least 1 common card of each color
- A pack must have at least 1 common creature
- A pack must never have more than 2 uncommons of the same color
- A pack must never have repeated cards
To avoid infinite loops in presence of corner cases, Booster Tutor attempts at balancing packs with Reuben's algorithm up to a maximum number of iterations (default: 100).
Some packs (for example Mystery Boosters) are not balanced. Information on whether a pack should be balanced or not is obtained from the metadata by mtgjson.
- Of course, huge thanks to mtgjson
- Card images are taken from Scryfall
- Thanks to Sealeddeck.tech for working with me on integrating Booster Tutor with their tool
- Part of my data reading implementation is inspired by pymtgjson
- An interesting discussion over a few approaches on color balancing in MTG boosters from where I took Reuben's algorithm
- Wizards of the Coast, Magic: The Gathering, and their logos are trademarks of Wizards of the Coast LLC in the United States and other countries. © 1993-2023 Wizards. All Rights Reserved. Booster Tutor may use the trademarks and other intellectual property of Wizards of the Coast LLC, which is permitted under Wizards' Fan Site Policy. For more information about Wizards of the Coast or any of Wizards' trademarks or other intellectual property, please visit their website.