A No With Numbers Behind It
Blog post #61
A while back I got curious about whether you could make money buying and selling used board games. I had seen someone do it with clothes from flea markets, buying cheap and selling a lot and coming out ahead, and I wanted to know if the same thing worked for a category I actually care about.
Today I paused the project. The answer is no. I am happier about that than I expected to be, because a no with numbers behind it is a real answer, and I did not have one before.
What shipped
A price index for the Swedish second hand board game market. 34,246 listings, of which 10,992 are completed sales with a buyer, 9,591 are listings that expired without one, and 13,663 are live right now. That clusters into 23,229 distinct games, though only 506 have enough sales behind them to say anything with a straight face.
The part I am most pleased with is that it tracks three states instead of one. Most price guides only know what people are asking. This one knows what things actually sold for, what failed to sell and at what price, and what is on the market today. The gap between those is where the information lives. Unsold listings ask a median of 1.14 times what the game actually goes for, and only about half of everything listed finds a buyer at all.
One genuine finding came out of it. Fixed price beats auction by a factor of 1.32 for the same game, measured across 115 games that had sales in both formats. The effect gets stronger as the evidence gets thicker, not weaker, which is the direction you want. I checked the obvious objections. Condition distribution is identical between the two formats. Fixed price sellers do not get stuck more often, they sell at 55 percent against auction’s 53. Shops are excluded by construction, since Tradera gives shop listings their own type and they show up in zero completed sales.
That one is useful even without the rest of the project, because it applies when you sell your own things.
Why the answer is no
The median completed sale is 130 kronor. After shipping and fees there is no business in that.
But the number that actually closed the question came from a different angle. I asked Claude to check four games I would personally want to flip, the kind of thing that gets talked about after Essen. Speakeasy, Weather Machine, Echoes of Time, Everdell Farshore.
Speakeasy had one hit, for 40 kronor, and it turned out to be a mismatch on a different item entirely. Weather Machine had two sales. Echoes of Time had none. Everdell Farshore had none, just two listings sitting there at around a thousand kronor each.
So we widened it. Of the 506 games with at least three sales, 67 are in BoardGameGeek’s top 500, and only 38 were published in 2020 or later. Seven percent.
Tradera is a market for games between five and twenty years old. Ticket to Ride, Carcassonne, Pandemic, 7 Wonders. The fresh hobby titles are not changing hands there at any volume, which means there is nothing to arbitrage even if the margins were good. That is not a disappointing result. It is a clean one, and it took about ten minutes to establish once I asked the right question.
What’s working: measure it before it becomes true
The best thing that came out of this project is a habit, and it came out of a mistake.
At one point I had two Claude sessions running against the same folder, which I will come back to. One of them fixed a clustering bug, watched a game drop off the bargain list, and explained it: cheap listings with sloppy titles end up in their own fragments more often, so uncleaned clusters must be biased upward. Reasonable. The other session read that, agreed, generalized it from one example to the whole index, and told me about it as a fact.
Two steps from guess to documented truth, and nobody had counted anything.
Then one of them actually measured it. Reconstruct the old code, run both against the same input. Of 725 sold rows that changed cluster, the comparable 83 split 43 cheaper and 40 more expensive, ratio 0.96, p of 0.83. No effect. The index median sat still at 145 kronor before and after.
The lesson is not “AI hallucinates.” The lesson is more specific and more useful than that. Two sessions reasoning the same way will construct the same explanation independently, and then take each other’s version as support. Agreement between them is not evidence. They confirm each other exactly as readily as they correct each other.
So now there is a rule written into the project: separate “this could be caused by X” from “this is caused by X” in writing. The second one requires a number. It applies to me too, and honestly it applies more to me than to the machine, because I am the one who repeats things at dinner.
The two sessions
I got carried away and ran two Claude threads against the same folder at the same time, which is exactly as smart as it sounds. Within half an hour they were both editing the same three files without knowing the other existed.
Then they found each other and wrote a protocol, unprompted. One file per session, named after the session id, owned by that session alone. Claim a file before you touch it, and write down why, not just what. Release it when you are done. Read everyone else’s file before you answer me.
That is roughly what OpenAI’s agents did during the Hugging Face incident in July, where separate model runs found a shared file store, started leaving notes for each other, and developed conventions for addressing one another and not overwriting each other’s work. When the channel was shut down they encoded messages in directory names instead. The comparison sounds alarming, and the useful part of it is duller: this is what falls out when agents with a filesystem need to coordinate. It is a cheap solution to find, so arriving at it independently proves nothing about it being right.
The protocol earned its keep once. One session found a real bug in a file the other had claimed, and instead of fixing it, wrote up the reasoning and handed it over. The other session verified it independently, found 44 auctions and 7 auction-with-buy-now listings under two kronor and zero true fixed price ones, and then fixed it. The claim turned a plausible fix into a checked fix, because two parties had to agree.
It also cost something. A stale number in the README went unfixed for days because the polite thing was to defer to whoever held the file, and then nobody owned the follow up.
What’s unclear or broken
I did not start this to make money on board games. I started it because I have never built a loop. I wanted to learn how event driven agent systems actually work, and board games were just the domain I picked to learn in. A user filing a bug report and someone posting a new listing have the same shape, and I wanted to build the thing that sits in the middle.
I never got there. Nothing in this project is a loop. It is all batch, run by hand: crawl, normalize, index, build. The one piece that would have been a loop, a notification within minutes when someone posts a game below index, is the exact piece that never got built.
I picked a domain where the entire difficulty sits on the input side. Facebook deliberately destroys timestamps in the DOM, character by character, in reversed order, with padding. BoardGameGeek put its API behind a token in 2025 and my application is still pending. Tradera’s pagination looks like it works and silently isn’t: one regex was locked to the wrong offset marker and fetched 80 listings out of 7,072 while reporting zero duplicates and zero empty pages. Adding a page parameter to a Tradera URL returns page one again, so a naive crawler gets 6,880 rows that are actually 80 rows copied 86 times, and nothing breaks.
Every one of those is a good war story. None of them taught me anything about loops. I spent the whole project fighting to get data in the door and never reached the state machine on the other side.
Tooling & process
The thing I would do differently is not technical. Pick the domain to match the lesson.
If what you want to learn is how to build a loop, choose an input that wants to be read. A webhook, an API you are allowed to use, an inbox. Then the work lands in the state machine, which is the part you are trying to learn, instead of in a fight with a counterparty that does not want to be read.
Which is convenient, because there is a real version of this waiting for me at home. We have a pile of things from the toddler years that need to go, and generally too much stuff, and getting better at selling what we own but don’t use would actually help. That is not arbitrage. I already own the things, so anything I get is upside and pricing precision barely matters. The bottleneck is friction. Photograph it, write it, list it, answer, agree, hand it over.
And that has the shape I was after all along. States, events arriving from outside, a queue, items that go stale if nobody touches them. Drop the price after ten days with no interest.
The board game index was the wrong project for the thing I wanted to learn. It was a good project for finding that out.
— Stefan