CardCore
Back to Blog

Building CardCore - June 4, 2026 - The Bigger Room: Magic, Three Stores, and a 3 A.M. Disaster

June 4, 202613 min readBy Dan Vohasek
building-in-publicmagic-the-gatheringstar-wars-unlimitedinfrastructurepostmortemmulti-storepartnerships

Seven weeks of quiet

The last time I sat down to write one of these, it was the night before the Sector Qualifier. April 17. Same kitchen table, same wrong-temperature coffee, same dog who had given up and gone to bed. I told you it was a make-or-break window. I told you the only reward for surviving it was a bigger mountain.

Then I did the one thing a guy with a "building in public" blog is absolutely not supposed to do.

I went quiet for seven weeks.

Not because nothing happened. Because too much did. Since that post, more than six hundred changes have landed in the platform. We launched an entire second game. We brought two more stores online. We survived an outage that I am going to tell you about in detail because it was genuinely the worst night of this whole project. And, this very afternoon, I moved the blog you are reading right now onto new infrastructure.

The blog about building the thing went dark because I was buried inside the thing. That is the honest reason. Let me catch you up. This is the long one. Again. Sorry. Not sorry.

The Sector Qualifier worked

First, the cliffhanger I left you on. How did Saturday go?

It worked.

Over the two days at Gas South Arena we ran the CardCore booth for a room of more than four hundred players. The booth moved one hundred and ninety-two orders and fifty-seven trade-ins. The platform, which one week earlier had only ever seen a seventy-person soft launch, took roughly ten times that load and stayed standing. Cards got bought, cards got sold, credit changed hands, and the lights stayed on. I have run a lot of versions of "will this hold under real pressure" in my head, and the real answer came back: yes.

And, because this blog does not do victory laps without the receipts, here is what broke.

It took too many clicks. Specifically, it took my own staff too many clicks to push an order from "ready" to "the player has it, we are done." At four-hundred-player volume those clicks add up, and thirteen orders timed out in the pickup window and had to be finished by hand after the event. Nobody lost anything, but it was slower than it should have been at exactly the moment speed mattered most.

The QR check-in system I had so proudly built for the booth? Used zero times. My staff took one look at the chaos and worked a flat order queue instead, which is a very polite way of the universe telling me I had built the feature I imagined needing instead of the one anyone actually wanted under fire.

And the search bar humbled me completely. Real players, at the counter, in a hurry, typed things like "Palestin" and "luthern" and "anik" into the search, got zero results, and looked up at me. That is how I learned that a card search which only matches correct spelling is a card search that fails at the precise second a human being needs it. I spent a good chunk of the following week teaching it to read typos.

That is the texture of a real launch. It works, and it teaches you ten things it should have done better, and a lot of those fixes were in production by the following week.

Monday morning, the bigger mountain

In the April post I wrote a line I then had to go live up to: the prize for surviving the Sector Qualifier was getting to start the actual hard thing on Monday morning, which was making CardCore work for Magic: The Gathering.

So on Monday morning, I started Magic.

Magic is a different universe. Thirty years of sets. Tens of thousands of cards. Price data that moves faster than Star Wars Unlimited, a buylist market many times larger, and a player base that has had good software for a decade and will tell you in about four seconds when yours is bad. Everything we built for one game now had to work for a game with an order of magnitude more surface area.

In late May, over a focused week, we launched the Magic vertical. You can browse the catalog. You can trade cards in, and the system finally understands condition, because a near-mint card and a beat-to-hell card are not the same offer and pretending otherwise is how you go broke. There is a buylist. There is per-game pricing with its own tiers and its own rules.

The real win was underneath, where you cannot see it. I did not bolt Magic onto the side of the Star Wars code. I rebuilt the core of the platform to be game-aware, so that adding a game is now a playbook I can run instead of a rewrite I have to survive. That single decision is the reason the rest of the roadmap is possible.

And here is the honest part, the part that every card-store owner reading this already knows in their bones. Magic went live with zero cards in stock. The software shipped. The inventory is me, a label printer, a scale, and a truly unreasonable amount of sorting. The hard part of running a card store was never the code. It never is.

You can poke at all of it over at store.cardcore.gg.

Three stores

When I started this whole thing, CardCore ran exactly one store. Mine.

As of this week it runs three.

The original is mine. The second came online earlier in the spring and became the test that proved the whole multi-store idea actually works. The third went live at the end of May, and here is the part that got me a little: it is the exact same shop that hosted our very first event back in April, the seventy-player soft launch where this all started feeling real. The store that gave us our first weekend is now a storefront on the platform.

The number I have written on the wall is twenty stores. To have any hope of getting there, I had to stop running a separate private copy of the entire app for each store, which is how it worked at the start, and build a single shared brain that figures out which store you are visiting based on the web address you walked in through. It is invisible, it is unglamorous, and it is the only reason "twenty stores" is a sentence I am allowed to say out loud.

The night a 3 A.M. robot bricked production

Okay. This one I have to tell you properly, because this blog has been honest from the first post and I am not going to stop now just because the story makes me look bad.

Earlier in the spring I finally moved CardCore off the duct-taped Windows machines it grew up on and onto a real Linux server cluster. Proper containers. Proper separation. A grown-up setup that I was, frankly, proud of. I had graduated from "a couple of computers in the house" to "infrastructure."

Then, at three o'clock in the morning on a Thursday, the server updated itself and did not come back.

I had set up an automatic weekly patch job, because keeping security holes closed is the responsible thing to do. That particular night the update swapped in a new system kernel and a new bootloader, and a small misconfiguration that had been sitting there silently for who knows how long meant the machine installed the new version, deleted the old version, and then could not find the new one when it tried to reboot. It just stopped. Every CardCore store went dark at once. Every address returned an error. The whole platform, asleep.

I woke up to it.

What followed was about eight and a half hours of the worst kind of troubleshooting there is, the kind where the patient is unconscious on the table and you are trying rescue tools at six in the morning on no sleep. And the cluster I had been so proud of turned out not to be the magic safety net I had assumed. The other machines did not have a copy of this machine's data. And the backups I had been absolutely meaning to set up were, naturally, not set up yet. You can put that on my headstone.

You want to know what finally fixed it? It was not clever. It was a screwdriver.

I shut everything down, opened up two computers, physically unscrewed the storage drive out of the dead machine, screwed it into a healthy one, and turned that machine on. The database woke up, replayed the last couple of seconds it had in memory, and came back exactly where it had left off. Zero committed transactions lost. Not one order. Not one trade. Not one account. Everything that had ever been saved was still there.

I rebuilt the dead machine from scratch the next day, moved everything back the safe way, and set up real backups that same afternoon, in the grand tradition of finally buying a fire extinguisher the morning after the small kitchen fire.

The lessons are not glamorous and I am going to say them out loud anyway, because somebody else running their own thing needs to hear them. A cluster is not a backup. An automatic reboot is dangerous if you do not also have automatic recovery. And the boring rescue plan you should have reached for in the first thirty minutes is worth more than the five hours of clever you reach for instead.

We were down for the better part of a workday and I hate that with my whole chest. But the platform came back with every single thing intact, and I walked out of it with a setup that is genuinely much harder to kill. I will take that trade. I did not enjoy paying for it.

A tier list you can run from a stage

Let me tell you about something fun, because we have earned it.

We built a tier-list maker for Star Wars Unlimited. Drag the entire card pool into S, A, B, C, D rows, share your take with the community, argue about it. Standard tier-list stuff, and it is a blast.

But here is the part I am proud of. It has a presentation mode. You put the board up on a projector, players in the room scan a QR code with their phones, and every phone in the room becomes a live second screen that follows along with whatever card you spotlight from the front of the room. Tap a card on stage, it lights up in everyone's hand within a couple of seconds.

We built that for a reason. We are partnered on the 2026 Galactics Bootcamp, where a competitive squad trains for a major event in late July, and a coach standing at the front of a room teaching deck evaluation to a team is exactly the human being that feature is for. It is the first CardCore tool designed to be used by someone holding a marker, not a mouse. Go make a board at store.cardcore.gg/swu/tierlists.

The people

None of this happens alone anymore, which is still strange to type.

Our deck tools now show "Powered by SWUStats," through a partnership with Nate Andre, the developer behind SWUStats and the Karabast play simulator that a huge slice of the Star Wars Unlimited community uses every week. We are working on getting CardCore deck links recognized natively inside Karabast, too. We are sponsoring a competitive squad that won a Sector Qualifier and treats our roadmap like it is partly theirs. And the crew from one of the bigger stores in the state sat down to dinner with me back in April and gave me the feedback that drove half of the pre-event sprint. The partnership that used to live on a spreadsheet now has faces and inside jokes attached to it.

Meanwhile, quietly, a hundred small things

Because it would not be one of these posts without the pile of things that do not get their own headline:

A deck page that used to take thirteen full seconds to load now comes back in under one, after I hunted down the single database lookup that was strangling it. Deck exports now go out cleanly to Melee, SWUDB, and Karabast, with all the variant and printing weirdness stripped so the other tools actually accept them. The Lab reached full filter parity, so anything you can filter in the builder you can now filter there too. We tore out the old thirteen-tab analytics monster and replaced it with a clean per-store daily view. We ran a security audit and fixed what it found. And we finished fixing up the newest Star Wars Unlimited set after its art and rarities got caught in the crossfire of all that infrastructure surgery.

Multiply that by seven weeks and you have a sense of the shape of it. Ship, test, ship, fix, ship.

One more thing

I told you at the top that I moved this blog this afternoon.

For its entire life, this marketing site, the one you are reading, ran on the last Windows box still standing in the old setup, off by itself while everything else had already moved on. As of today it is a proper container sitting right next to the rest of the platform, on the same Linux cluster from the war story above, with its own private tunnel out to the internet.

The blog about building CardCore now lives on CardCore's actual infrastructure. I cannot fully explain why that closes a loop so satisfyingly in my head, but it does. The site that documents the move finally made the move.

What is next

Twenty stores is still the number. The bootcamp is in July and I want the tools razor sharp before that squad gets on a plane. Now that the Magic playbook exists, the next games in the queue, Lorcana and Sorcery and Riftbound, get to ride the same rails instead of fighting for them.

And the unglamorous list keeps growing, the one full of things that are not fun to build but are the actual difference between "a cool tool a few enthusiasts love" and "software a shop owner will bet their livelihood on." Email. Mobile. Plugging into the bigger marketplaces. The whole quiet world of features that nobody tweets about and everybody requires. The window to be the platform stores move to is open right now, and it does not stay open forever, so that is where a lot of the next stretch goes.

The April post said the reward for surviving the Sector Qualifier would be a bigger room. Well, this was the bigger room. It had Magic in it. It had three stores. It had a tier list on a projector and a 3 A.M. disaster and a screwdriver. It was a hell of a room.

The room after this one is bigger still.

See you in it. I will be the guy who has not slept, who is unreasonably excited, and who has finally, finally set up the backups.