Jon Wire

A Software Engineer exploring the world with code.

Open Mint Trading Card Game (TCG) - Part 2

It's been about a year since I wrote about Open Mint TCG. Shortly after writing the first article, I dropped into deep focus leading the development of AWS Blocks. Combined with a much busier year for my family in general, I haven't had much time for Open Mint TCG β€” or really any leisurely writing. In the few spare moments I have had, I've been mired beneath the game concept's complexities and seemingly contradictory goals. Enter analysis paralysis and compounding exhaustion.

My pie-in-the-sky vision for Open Mint TCG was to create a game wherein the game itself was essentially a game state and a programming language that operate on that state. Every card would then just be code. This was supposed allow players to mint completely novel cards that could do "anything" to the game state. But designing a "programmable game engine" that could be "executed" by humans started to feel daunting and, frankly, too tedious to wrap my head around. (Both as the game creator and as a player.)

Combined with other goals that felt like they were pulling in opposing directions (which I'll cover shortly), the added complexity of a completely open-ended game was too much. Every time I thought about it my brain would thrash and often deadlock trying to resolve the design problems. So, I'm simplifying.

As I'm about to show, I believe it still makes sense to build on top of the ideas in my last article. But the path forward is now more refined and restricted in some ways. In that article I showed how we can "mine" cards by searching through "card DNA" for valid strings or "viable genes." In this case, the "DNA" would just be long strings consisting of a limited character set. If you didn't read the previous article, the short version is that we can cryptographically hash a candidate "DNA" string to determine whether it represents a valid card and what its attributes should be. This gives us a few desirable mining features:

  • "Blind" mining: The mining process isn't directed at specific cards.
  • Organic rarity: Attributes can be set to specific scarcity levels.
  • Predictable mining difficulty: Mining time per card and total population size are tunable.

(The precise predictable mining difficulty plan is itself tunable. It's not yet clear to me what the fun-optimizing ideal would be.)

In the last article, my examples focused on two numerical attributes (health and attack) and one boolean attribute (isValid or "viability"). I demonstrated how rarity or scarcity can be mathematically enforced by counting the zeros in hash hex strings. Because cryptographic hashes are intentionally unpredictable with each bit (and therefore digit) appearing random, the likelihood of a hash string containing \(N\) or more zeroes decreases rapidly as \(N\) increases. This approach makes it easy to visually demonstrate how hashes can be used to control rarity. But the math Open Mint TCG uses can actually be much simpler and more precise. Namely, we can simply divide a hash's range into "buckets" that map onto sets of macro-attributes. (Which I'll just call macros.) Those macros can be used to deterministically derive more detailed card properties, actions, effects, card naming, artwork generation, etc.

For example, if we use SHA-256 we get hashes that fall in the range of \([0, 2^{256} - 1)\). We can then set a threshold (1% for this article) to keep card population controlled β€” and maybe to make mining feel more like a search. From that valid pool, we we'll generate cards with a predefined random distribution for each "type" we want to see. Borrowing card types from MTG, we might create a "card type" distribution, assigning each card type a weight to avoid the tedium of repeatedly re-balancing percentages.

Card TypeWeightProbabilityHash Range
spell110.0%\(\text{H} \in [0.0\% \times 2^{256}, 10.0\% \times 2^{256})\)
enchantment220.0%\(\text{H} \in [10.0\% \times 2^{256}, 30.0\% \times 2^{256})\)
land220.0%\(\text{H} \in [30.0\% \times 2^{256}, 50.0\% \times 2^{256})\)
creature550.0%\(\text{H} \in [50.0\% \times 2^{256}, 100.0\% \times 2^{256})\)
For valid DNA where H = hash(hash(DNA + ":isValid") + ":type").

Then we can do the same thing for other attributes. When we find a creature card, we could also give it a species.

Creature SpeciesWeightProbabilityHash Range
human5049.0%\(\text{H} \in [0.0\% \times 2^{256}, 49.0\% \times 2^{256})\)
rat109.8%\(\text{H} \in [49.0\% \times 2^{256}, 58.8\% \times 2^{256})\)
bird2019.6%\(\text{H} \in [58.8\% \times 2^{256}, 78.4\% \times 2^{256})\)
bear109.8%\(\text{H} \in [78.4\% \times 2^{256}, 88.2\% \times 2^{256})\)
lizard109.8%\(\text{H} \in [88.2\% \times 2^{256}, 98.0\% \times 2^{256})\)
god22.0%\(\text{H} \in [98.0\% \times 2^{256}, 100.0\% \times 2^{256})\)
For valid DNA where H = hash(hash(DNA + ":isValid") + ":species").

And maybe we prefix those with an adjective ...

Creature AdjectiveWeightProbabilityHash Range
basic5045.0%\(\text{H} \in [0.0\% \times 2^{256}, 45.0\% \times 2^{256})\)
swift1513.5%\(\text{H} \in [45.0\% \times 2^{256}, 58.6\% \times 2^{256})\)
mighty1513.5%\(\text{H} \in [58.6\% \times 2^{256}, 72.1\% \times 2^{256})\)
armored1513.5%\(\text{H} \in [72.1\% \times 2^{256}, 85.6\% \times 2^{256})\)
colossal109.0%\(\text{H} \in [85.6\% \times 2^{256}, 94.6\% \times 2^{256})\)
silent54.5%\(\text{H} \in [94.6\% \times 2^{256}, 99.1\% \times 2^{256})\)
indestructible10.9%\(\text{H} \in [99.1\% \times 2^{256}, 100.0\% \times 2^{256})\)
For valid DNA where H = hash(hash(DNA + ":isValid") + ":adjective").

And then give them a class ...

Creature ClassWeightProbabilityHash Range
--1066.7%\(\text{H} \in [0.0\% \times 2^{256}, 66.7\% \times 2^{256})\)
soldier16.7%\(\text{H} \in [66.7\% \times 2^{256}, 73.3\% \times 2^{256})\)
warrior16.7%\(\text{H} \in [73.3\% \times 2^{256}, 80.0\% \times 2^{256})\)
cleric16.7%\(\text{H} \in [80.0\% \times 2^{256}, 86.7\% \times 2^{256})\)
rogue16.7%\(\text{H} \in [86.7\% \times 2^{256}, 93.3\% \times 2^{256})\)
wizard16.7%\(\text{H} \in [93.3\% \times 2^{256}, 100.0\% \times 2^{256})\)
For valid DNA where H = hash(hash(DNA + ":isValid") + ":class").

And finally, we map those attributes to card properties, effects, naming, artwork, etc. Combinations might create unique mappings. For example, a "swift lizard wizard" might map like this:

Property Power Toughness Effects
lizard 1 3
swift + First Strike
wizard x 2 Γ· 2 rounded down + Deal damage equal to power to any target on entry
lizard + wizard + Chameleon: Copy another target creature's abilities
- Deal damage equal to power to any target on entry
Final 2 1 First Strike, Chameleon: Copy another target creature's abilities

The actual underlying math can be done using exclusively integer math for precision and parity between platforms. Using this approach, if we look at the same example list of 4096 genetic codes from the last article, going from "aaaaaa" through "dddddd" (using only a, b, c, and d) and using the tables above, the set of cards would look like this.

TypeAdjectiveSpeciesClassCount
creaturearmoredbirdsoldier1
creaturearmoredbirdwizard1
creaturearmoredhuman--1
creaturearmoredratwarrior1
creaturebasiclizard--1
creaturecolossalrat--1
creaturemightylizard--1
creaturemightyratwizard1
creatureswiftlizard--1
creatureswiftlizardwizard1
creaturebasicbird--2
creaturemightyhuman--2
creaturebasichuman--5
spell------5
enchantment------6
land------6

The game will ultimately have a much wider range of genetic codes and broader set of attributes to mine. But that's the idea.

Now, about the economy ... 🧐 ...

I mentioned earlier how the game has some competing goals. The short version is that I want Open Mint TCG to have a sense of discovery and an engaging card economy β€” but without intrinsically making wins a function of spending.

Think of Magic: The Gathering (MTG) or PokΓ©mon. A defining characteristic of these games is card scarcity. In these games, scarcity comes from a combination of card utility and limited printing. This essentially creates a side game around card discovery, collection, and trading. Scarcity-driven economies like this attract geek attention even without an associated card game. But in the geeky card game genre they're a borderline expectation. And the ability for creators to benefit from creating cards is essential to fueling that economy.

But a scarcity-driven economy based around potent card properties stands directly opposed to the approachability of the game. For Open Mint TCG, a similar scarcity-driven economy would threaten the ability of players to sit down at the game table cheaply (or even for free) and play competitively β€” limited by their knowledge and skill rather than their financial investment. This type of approachability is a core design goal of Open Mint TCG.

The tension is amplified by the fact that we actually want high power cards to be more scarce! But we don't want them to cost more. We also want creators to be rewarded for producing unique cards! But we don't want that to force players to pay to win. And furthermore, we want to maintain an ongoing sense of discovery through card mining. But we don't want ongoing discovery to become inflationary, turning very rare card into a common card over time.

But there's hope!

Catching up a little with Aaron Jewell, he suggested two things that should help.

Firstly, he suggested the use of common entropy events. The point of these events is to produce unpredictable data (a random string) that be used when generating cards, which can then be used help constrain what can be played during any particular game while perpetuating card discovery. For example, the Open Mint TCG repository itself could be one source of global seasonal events, releasing a random event code every 4 to 6 months. And each code would be published with an allowed DNA length limit to constrain mining and maintain a card distribution within the event that keeps powerful cards rare.

The precise way this works at any given game table will be up to the event host (which could mean be "everyone at the table" for casual games). The official rules might suggest that last 2 years worth of global seasonal events be legal play by default. But this is still ultimately up to the host, who might choose to generate their own entropy and set mining limits to apply just to their group.

Using this mechanism, we don't have to worry too much about whether the pool contains some long-sought-after card, like a 10/10 Rogue Pirate Wizard β€” if it ultimately doesn't exist in the event's card pool, another event is coming around in a few months anyway. And, if you're really impatient, your play group can even publish your own event and make the sky the limit! Your cards are just not going to be play at someone else's table unless they agree to include your event in their event.

Incidentally, we'll need to find another term to use in place of event to help distinguish it from calendar events. But that's future me's concern...

That brings us to the second suggestion on creating economic scarcity. Uniqueness and scarcity cannot come from card properties. That leads to a pay-to-win mechanics. But, they can come from card flavor and printing! I.e., anyone can play the generic version of a card β€” the 10/10 Rogue Pirate Wizard β€” by printing it on paper for close to zero dollars. But to legally obtain the branded, functionally identical "Gigantic Swashbuckling Doctor Strange" variant β€” or whatever β€” with beautiful hand-drawn artwork and flavor text straight from the Issue 110 (again β€” or whatever), you would need to buy a legally licensed print. (Even just to get a high quality printing, you might order your generic 10/10 Rogue Pirate Wizard from a trusted print shop.)

So, without asking players to pay for functionality, my hope is that players will want to pay for scarcity, aesthetics, and nostalgia. I suspect that by allowing, encouraging, and facilitating this kind of flavoring, we can create a game that ensures anyone can sit at the table and play competitively and still be routinely surprised and awed by the physical cards that show up at the table.

Inherent to all of this, I am assuming that card DNA is public knowledge and is unowned. Once you see a card, you see its DNA, and you become legally allowed (game-legal) to play one copy of it. For strictly lawful reasons, the branding obviously still depends on paying for licensing, which could mean buying the physical card from the owner.

So, I think we can get started.

Thinking through this "aloud" for this article, I have at least enough clarity to build something that is probably free of obvious self-contradictions. To start with, I'll run with the following tentative high level decisions.

  • Card generation will be blind.
    Mining searches DNA space. You find what is found; not what you seek.
  • Card DNA will identity high level macro-attributes.
    Micro-attributes will be derived from the macros.
  • Cards will be generated by shared entropy events.
    Event entropy defines card legality. Event hosts can limit or expand that scope.
  • Card DNA is intentionally public for all to play.
    Though pre-publishing may not be required, playing a card enables cloning β€” excluding artwork obviously.
  • Card DNA can come in many flavors.
    The game will explicitly support and encourage personal and/or licensed card variations.

I'm still busier than I'd like to be, but within the next few months I'll aim to publish a website and/or app with an alpha card miner, validator, and a printable format. I'll generate an initial catalogue of card macros and their micro-feature mappings, and I'll figure out some primitive artwork. (Or at least emojis.) If possible, I'll see if I can integrate wth an on-demand card printing service for high quality prints.

I'll enumerate the long list of features and open questions in GH issues once we have a foundation and POC to react to. I'll refine and be more deliberate about RFC and open source contribution processes once there's an alpha to play with.

If you haven't already, subscribe to the repository. Tell me what you think on Github or any other way you know how to reach me.

If you enjoyed anything about this article, subscribe so you don't miss out!

* indicates required

Intuit Mailchimp

Published: 10/23/2026.
Topics: computer science, crypto, crypto mining, games, mtg, open mint tcg, trading card games