a quest for convenient magic: the gathering tokens. - shylie - jan 2026 - <-

Yeah. I play Magic

Sometime this past December, I made the unfortunate decision to start playing Magic: the Gathering again. Banter aside, it’s been pretty fun. Well, aside from when I need a token copy of a card. Which happens quite a bit more often than you’d think. I run Zinnia as my commander. This means that I can make a copy of just about any creature in my deck. Except it’s got different stats, which means I can’t just say “wow look at this funny copy”. Yeah, it kinda sucks to track. So, after a couple games of commander, I decided I need a better solution.

Brainstorm(ing)

We get it there's a card named brainstorm

Jokes aside, there was really only one answer I could think of: a digital card. In theory, it can be anything. So I did some looking around and found some 320x240 2.0 inch displays on Aliexpress for about $3 each.

here's the display

Doesn’t look so bad. As a reference, the original image looks like this (credit where it’s due for the image):

natalie from ebf5

Getting this uploaded over USB to the microcontroller wasn’t that bad. I just registered my device with the host computer as a vendor-specific USB device, and then wrote a simple program on my laptop to upload it. So, that was cool, but you had to re-upload the image on reboot. Not great.

Flash (memory)

stop making this joke it's not that funny

Obviously the answer to that is non-volatile storage. I soldered up an SPI flash chip to a breakout board. Then, I modified the firmware to program the uploaded image to flash instead of the display memory. Oh, and it loads from flash on boot. This works okay, but you’ve only got one card. At this point, it’s even worse than buying a physical copy of the card.

A file-system of sorts (and metadata)

Flash memory is writeable any time, but only by changing bits from 1 to 0. To reset it back to 1, you must erase a whole sector. Since flash is programmed in 256-byte pages and erased in 16-page sectors (4kb, for those who can’t do math), even if a card is only 27 bytes (it’s not), it would be very nice if it could be aligned on these boundaries. Another issue is that erasing can only be done so many times before the flash stops working. This means that you should take care to use the memory as evenly as possible. In turn, you’ve gotta track how many times each sector has been erased.

a slight problem

But wait, shylie, doesn’t that mean you need a dedicated spot to track this? Wouldn’t that make distributing the erases be pointless, since re-writing the metadata would require erasing that sector?

Yes. Yes, it does in fact make a central record not useful. Just don’t centralize it, and you’re fine– have each sector track its own erase count.

Since cards are uploaded to the device, and removed later when not needed, you have to track whether a “card slot” is in use or not.

another problem (wow)

But. But shylie, wouldn’t you then need to erase once to mark unused, and another time to upload the card image?

Nope. In fact, since flash can be programmed from 1 to 0 without erasing, marking a card as unused is as simple as updating just one bit. Then you can just reset it to used status when actually uploading the new card.

I just wanna see it working tho

Too bad. I’m not done with it yet.