Most of the Catalog Was Playing Blind
Chasing why one specific game could never be recommended led to a number that reframed the whole product: 48,222 games — more than a third of the catalog — had no review data, and 97% of those had no tags either.
It started with a small question. Someone asked what Rust combined with MORDHAU should give. The obvious answer is Renown: a medieval survival game with base-building and PvP, which is Rust's half and MORDHAU's half in one title.
Renown never appeared. Not low-ranked — impossible.
Why one game was invisible
Games need a review floor to be returned as an answer, which keeps genuine junk out. Renown's
stored review count was 0, so it failed. Asking Steam directly:
Renown, in our catalog: reviews = 0, tags = none
Renown, live on Steam: reviews = 1,573, Mixed
Not a scoring problem. A data problem. And Renown wasn't special:
| Zero-review rows | Reviewed rows | |
|---|---|---|
| Also have no tags | 7,741 / 8,000 sampled (97%) | 1 / 8,000 |
48,222 of 131,865 Steam games were in this state: excluded from ever being an answer by the review floor, and simultaneously starved of the strongest signal our embeddings use. Doubly crippled, silently.
The fix that didn't work
Our catalog comes from a bulk dataset that only carries tags for about 83,000 of its 137,000 rows. The obvious move was to re-download it — and conveniently, it had been refreshed that very morning.
games: 136,712 -> 137,808 (+1,096)
tags: 83,378 -> 83,378 (+0)
reviews: 82,981 -> 82,981 (+0)
Renown: still reviews=0, tags=0
A thousand new games and not one new tag. The upstream enrichment coverage is simply frozen. Running the full pipeline on that would have cost half a day, a GPU re-embed, and a deploy, and changed nothing about the actual problem. Checking the delta before running it was the only reason we found out cheaply.
Going to the source
Steam's public review endpoint returns real counts with no key and no meaningful rate limit. Sampling 25 random zero-review games, 21 had real reviews on Steam right now. So we asked for all of them:
37,740 games gained real review counts in 42 minutes
zero-review rows: 48,222 -> 10,366
Tags were harder. There's no clean API for Steam's user tags — SteamSpy returned empty
for anything recent. But the store page embeds them, with vote counts, in the same shape our
database already uses. robots.txt doesn't disallow /app/, so we scraped
politely:
36,971 games tagged in 157 minutes (99.1% success)
Steam tag coverage: 61% -> 94%
Renown went from tagless to Survival, Crafting, Multiplayer, Open World, Open World
Survival Craft, Medieval, PvP, Building. Rust's half and MORDHAU's half, exactly as
predicted.
It still didn't win
After a full re-embed on the richer text, Renown climbed from ineligible to #11 for Rust + MORDHAU. And lost, to Hurtworld.
That was the honest and useful outcome. Every data excuse was now gone — real reviews, real tags, fresh vector, eligible — so whatever remained had to be the scoring model, not the catalog. Sweeping the relevant weight confirmed it: Renown only wins at a setting that also degrades Factorio + Satisfactory into "Chocolate Factory: Prologue" and Among Us + Phasmophobia into "DON'T GET GOT."
Which reframes the question. We'd been treating one bad recommendation as a bug to fix. It's actually a preference: rank by broad similarity to both inputs, or by carrying each input's distinctive trait. Those disagree, and no weight satisfies both.
Worth it anyway
The headline case is unresolved and the work was still the highest-value thing we did. Nearly 37,000 games stopped competing half-blind — games that were previously unreachable as answers regardless of how good a match they were.
Two smaller things fell out of it. The eligibility rule demanded tags specifically, which made sense when tags were the only descriptor; it now accepts any descriptive signal, so 7,032 real games stopped being invisible. And the weekly job was rewired to enrich new games before embedding them — previously a new arrival got a vector built from an empty tag list, and the incremental embedder would then skip it forever as "already embedded."
That last one is the difference between fixing a problem and fixing it permanently. Without it, every number in this post would quietly decay, a few hundred games a week.