Plugin Creator Tool: Python Library for Generating Pack Definitions

Started by CrazyChucky, February 14, 2019, 09:40:48 PM

Previous topic - Next topic

CrazyChucky

I don't know if anyone besides me will find this useful, but here goes! In short, this Python library is a tool to help generate drafting packs for Lackey, giving more intuitive control over what Lackey calls "chances"?the probability of different possible pack layouts.

Official documentation on Lackey pack definitions: http://www.lackeyccg.com/packdefinitions.html

The Problem

Let's use Magic as an example. A basic modern booster pack contains:

1 Rare
3 Uncommon
10 Common

(And 1 basic land, but those aren't drafted, so we'll ignore them.)
However, about 1 in 8 packs has a mythic rare instead of a rare. Ideally you'd be able to write something like this:

13%: 1 Mythic, 87%: 1 Rare
3 Uncommon
10 Common

Unfortunately Lackey defines chances only on a per-pack basis, not on subsets of a pack like individual card slots. So your definition needs to look like this instead:

13%:
1 Mythic
3 Uncommon
10 Common
87%:
1 Rare
3 Uncommon
10 Common

So far that's only a little added repetition. But the problem becomes much more pronounced when you have multiple, or even nested, branching points within your configuration. Consider the Shadows Over Innistrad set: in addition to the rare/mythic split, one slot is either a common OR uncommon double-faced card, and another slot is either a regular common OR a rare OR or mythic double-faced card. Never mind the actual numbers... The basic idea should look like:

13%: 1 Mythic, 87%: 1 Rare
3 Uncommon
8 Common
%: 1 Common, %: 1 DFC Mythic, %: 1 DFC Rare
%: 1 DFC Common, %: 1 DFC Uncommon

But to work in Lackey, you have to calculate each of those branch points out to a list of TWELVE different possible configurations. I dunno about you, but I don't want to do that by hand. Which brings me to...

The Solution

Well, for me at least. And maybe for you too, if you know (or decide to learn) Python!

I've posted the entire file here as an attachment, lackeyPacks.py. I've also included my Magic-specific file that imports and uses the library, so you can see what it looks like in practice. I make no claim or warranty of any kind for either of these files. But my intention is that you can use the lackeyPacks.py file basically as-is; you should only need to edit "possibleFields" up at the top so it knows what fields you have in your card files. Then you can write your own equivalent of my magicPacks.py, that imports it, defines your packs, and writes your pack definition file(s).

Most of the defined classes correspond to XML tags in Lackey's pack definition files: Pack, Kind, Crit, and CommonCrit. Branch is basically the same as a chance; that is, a branch that contains only kinds is a chance. However, any given entry within a branch can instead be a branchpoint, which itself includes multiple branches. When you create a pack object, it automatically analyzes its entries and resolves all branchpoints until it has a list of chances that Lackey can understand.

Let's go through an example. In magicPacks.py, you can see I define some variables for criteria I'll need often:

mythic = Crit('Rarity', 'IS', 'M')
rare = Crit('Rarity', 'IS', 'R')
uncommon = Crit('Rarity', 'IS', 'U')
common = Crit('Rarity', 'IS', 'C')
land = Crit('Rarity', 'IS', 'L')

This makes defining kinds easy: "Kind(1, rare)" corresponds to a kind tag in the XML file telling Lackey to include one card whose rarity is rare.

Here's the entries for a default Magic pack:

defaultEntries = (
BranchPoint(
Branch(Kind(1, mythic), prob=13), #1/8
Branch(Kind(1, rare), prob=87),
),
Kind(3, uncommon),
Kind(10, common),
)

After that you can do something like:

Pack('The Excellent Card Set', 'booster', defaultEntries)
And that will generate a pack. You'll probably also want to define one or more commonCrits, such as specifying that all cards in the pack have to come from a certain set. I make myself a Booster class as a subclass of Pack, as shorthand to take care of some things like that that are the same for (almost) all Magic booster packs. But that's probably more trouble than it's worth if your plugin only has a few different packs.

The writePacksToFile function writes a collection of packs to a specified file, which should then be ready to put in your plugin!

Known Limitations

The biggest one is that Lackey does NOT understand probabilities with a decimal component. That is, it understands 57, but not 57.25. Including any probabilities like this makes Lackey glitch and always choose the first chance listed for the pack. This becomes a much bigger problem the more chances you have and the smaller each one gets, especially since no one single chance can have less than a 1% probability.

Trevor mentioned fixing this in this forum post; just in case he does someday, I've included a setting flag at the top of the file. Change "roundToIntegers" to False and the library should happily spit out much more accurate numbers for you.

The other is available evals. The doc mentions "IS, CONTAINS, DOESNTCONTAIN,ISGREATERTHAN, among others." I don't know what those others are, but I do know that I haven't been able to get ISGREATERTHAN to work. So I recommend sticking with those first three. If you somehow discover others, first, please post here and let me know! And second, the list can easily be edited at the top of the file.


xdarkgeox

Neato tool, although I don't use pack feature any expansion that tackle lacky problems I can appreciate.

Jerod_tb


CrazyChucky