Game Verdict

A crowdsourced answer to an argument PC gamers have been having forever: is this game better with a controller, or with a keyboard and mouse?

Verdicts cast
2,906live · /api/stats
Games tracked
1,918live · /api/stats
Commits
1,08013 Oct 2026 snapshot · private repo
Per browse page
50 KBwas 1.8 MB
The problem

Everyone has an opinion, nobody has data

TL;DR

Game Verdict is a community-built database where PC players cast verdicts on the best way to play their favorite games. Every data point is a real opinion from a real player, with no algorithms, no review farming, and no editorial bias.

Steam will tell you a game has “full controller support.” It won’t tell you whether anyone actually prefers playing it that way. Game Verdict asks players directly, dedupes anonymous votes with a browser fingerprint, and surfaces the leading input method as a community badge.

Games are searched across Steam and IGDB in parallel, deduped and relevance-ranked, with metadata, cover art, and Steam library hero images pulled in automatically when a game is added.

A Game Verdict game page for The Binding of Isaac: Rebirth, showing cover art, a green Controller verdict badge, developer, release year, and genre tags.
A game page: verdict badge, metadata pulled from Steam and IGDB
The core loop

Free to vote, hard to fake

TL;DR

Voting takes one click and no account, but each browser only counts once; easy to vote, but hard to spam.

The whole thing only works if voting is nearly free, and it only means anything if the votes can be trusted. Those pull against each other, and almost every decision in the app is an answer to that tension.

Quick Vote takes the friction out: no account, one game at a time, skip anything you don’t recognize. A browser fingerprint keeps it honest without putting the friction back, counting each voter once whether or not they ever sign up. Sign in later and the votes you already cast are claimed rather than lost.

Game Verdict's Quick Vote screen: a queue counter, a session counter, and a single large game card showing Counter-Strike 2.
Quick Vote: one game at a time, no account required

A quarter of the traffic is on a phone, and the one-card-at-a-time shape was built for exactly that. Nothing about the loop changes on a small screen.

Quick Vote on a phone: the same single-card layout, sized to a narrow screen.
The same loop, thumb-sized
How do you count a vote from someone who refuses to identify themselves, without letting them vote a hundred times?
The design constraint

You can also vote from the game page itself, and the breakdown updates in place rather than sending you somewhere to see what you just did.

The verdict casting card on a game page, offering Keyboard & Mouse, Controller, Both, and a smaller Other option.
Casting a verdict without leaving the page
The results card showing a proportional tricolor bar with percentages for keyboard and mouse, controller, and both.
The breakdown, right after you vote
A small thing I like

The queue knows what you have played

TL;DR

It offers you games you have probably played, and stops offering ones you already answered, even if you never signed up.

Asking someone to judge a control scheme only works if they have actually played the game, so the queue is ordered by Steam review count rather than by how many verdicts a game already has. Review count is a proxy for “have you actually played this?”. Verdict count would surface the games that are already well answered, which is backwards.

On top of that it subtracts what you have voted on, skipped, watched, and owned — all resolved in a single parallel round trip — then promotes your own unplayed library games to the front while keeping them in popularity order. A stable partition, not a re-sort.

The fingerprint does double duty here. Because the exclusion set is fingerprint-aware, an anonymous voter’s queue shrinks as they vote. The queue gets personal for someone who never made an account.

StateQueue order
Signed in, library syncedYour unplayed games, then popular ones
Signed in, no libraryPopular games, minus voted and skipped
AnonymousPopular games, minus what your fingerprint already voted
Quick Vote with a synced Steam library: the top card is TUNIC, tagged 'In your library', with a queue of 378 and 535 skipped.
Library synced: your own games surface first, tagged in place
One sentence, two audiences

Prose generated from data, not from a model

TL;DR

The plain-English verdict on each game page is assembled from the actual vote counts, not written by AI, so it can never invent a number.

Every game page ends with a plain-language verdict: how many people voted, which way they leaned, and which controller they tend to use. It’s written by a buildVerdictSummary() function, not by a language model. Four branches on the leading choice, an extra clause when the top two land within ten points of each other, and a controller-subtype sentence that only appears once at least two people have reported one.

The Verdict card for Cyberpunk 2077, reading: based on 28 community verdicts, Cyberpunk 2077 works well either way, 53% of players say both inputs feel good, 11% lean controller, and 36% lean keyboard and mouse. Among controller players, Xbox is the most common setup.
Deterministic prose: same data in, same sentence out

The same string is also emitted as the FAQPage answer in structured data. So roughly 1,600 pages that would otherwise be near-identical templates each carry unique text answering the literal thing people search for, and the reader and the crawler are served by one sentence rather than two systems.

No latency, no per-call cost, no hallucinated percentages, and the same input always produces the same output. A model would have done this worse, slower, and for money.
Why not an LLM
Then scale arrived

The bug that froze the front page

TL;DR

The homepage counts quietly stopped rising after a thousand votes. Nothing broke or errored, but the number just lingered at 1,000 while it stopped being true. Believable at first, but quickly stood out as time passed.

Home page stats stopped moving. Not wrong — frozen, at a number that looked perfectly plausible. The cause was that getAllGames() ran an unbounded SELECT * against the verdicts table, and PostgREST silently caps responses at 1,000 rows. Everything worked exactly right until the site crossed its thousandth verdict, and then it quietly stopped counting.

The failure mode was not an error. It was a number that stayed believable while it stopped being true.
Why it took a while to spot

The fix was a game_vote_summary aggregate view doing the counting in Postgres. Which raised the more interesting question: why was the browse page shipping the entire games table to the client at all?

What it cost

1.8 MB → 50 KB per pageview

TL;DR

The browse page used to download the entire game list on every single visit. Now it loads only the games you can actually see and fetches more as you scroll, which costs about a thirtieth as much.

Browse was slicing a full table read. It became a games_browse Postgres view with filtering, sorting, and counting pushed into SQL behind LIMIT/OFFSET, fed by a route handler driving infinite scroll. A 24-row page costs about 50 KB. The old one cost about 1.8 MB — every single pageview, and worst during crawler bursts, when concurrent requests each independently pulled the whole list.

Game Verdict's browse page with platform and sort filters applied, showing a grid of games with verdict badges and vote counts.
Browse: filtering, sorting and counting all happen in SQL
Beyond the vote

Reasons to come back, and somewhere else to be

TL;DR

Twenty badges to earn, public profiles, and comment threads on every game where the best replies get voted to the top. A Discord bot covers the rest, so an argument in a group chat gets settled without anyone opening the site.

Twenty badges across six categories are evaluated after every verdict, reaction, and library change, with the first unlock arriving as a toast. Profiles are public, with a verdict history and an input-method tendency bar you can click to filter.

A public Game Verdict profile showing a shelf of earned achievement badges.
The badge shelf on a public profile

The Discord bot is the part that leaves the site entirely. Five slash commands run on a Cloudflare Worker that verifies Discord’s Ed25519 signatures, returning rich embeds with cover art, the verdict color, and the bar breakdown, so an argument in a group chat can be settled without anyone opening a browser.

A Discord embed from the Game Verdict bot showing the verdict for Hades II, with cover art thumbnail and a vote breakdown.
/verdict in Discord
A Discord embed comparing two games side by side with their vote breakdowns.
/compare, side by side

And the home page keeps the most contested games up front, because a game the community can’t agree on is a better invitation to vote than one that is already settled.

The Most Contested section of the Game Verdict home page, showing Steam hero art with the game logo composited on top, a tricolor vote bar, and inline vote buttons.
Most Contested, with Steam hero art and the logo composited on top
The Most Contested card on a phone, with the hero art, vote bar and buttons stacked.
The same card, narrow
Game Verdict's compare view: Counter-Strike 2 against ELDEN RING, with mirrored bars showing 97 percent keyboard and mouse against 80 percent controller.
Compare: Counter-Strike 2 against ELDEN RING
The empty room

Invite-only, on purpose

TL;DR

A forum with boards, markdown posts, direct messages, reporting and a moderation queue, opened to a handful of people first so it would have something in it before anyone was invited to look.

Comment threads on game pages were the small version of this. The community hub is the large one: four boards, markdown posts with a real formatting toolbar, threaded replies, reactions on both, emoji with shortcode typeahead, GIFs, friend requests, and direct messages. Replies are voted Reddit-style, so the best answer to “is this one better on a pad?” rises to the top of the game it is about instead of sitting wherever it landed chronologically.

The Game Verdict community index: four boards down the left with unread badges, and a 'Hot right now' feed showing a pinned welcome post and a thread with an embedded game verdict.
Four boards, with unread counts and whatever is busiest on the right

A post can attach a game, which embeds its cover and its live verdict split into the thread. That is what makes this the site’s forum rather than a forum bolted onto it. An argument about Oblivion carries the current breakdown for Oblivion, moving as people vote, so the discussion and the data it is arguing about can’t drift apart. Author names carry the badges you earned voting, so the identity you build casting verdicts is the one you turn up with.

A Game Verdict community thread titled 'Oblivion remastered is such a nostalgia vibe', with the game's cover art and a live KBM verdict bar embedded under the title, moderator actions reading Delete, Pin, Lock and Report, and two replies below, one of them an animated GIF.
A thread carries the live verdict for the game it is arguing about

It is invite-only, and that was the plan rather than a limitation. A forum nobody has posted in is worse than no forum, so early access went to the most active voters to seed real threads before the doors opened. Everyone else gets a warming-up animation and an honest note about what it is. Making something feel worth getting into is a nicer problem to have than making an empty room look busy.

Game Verdict's community teaser: a chat icon inside a slowly rotating tricolor ring, headed 'The community hub is warming up', with buttons to cast verdicts or sign in, and a note that early access invites go to top voters.
What everyone else sees, until an invite arrives

Every post and comment carries a report button with four reasons, alerting mods and admins into a queue that gets worked by hand. Moderators pin and lock inline. Deletes are soft, so a removed post is still there to look at when someone asks why it went. Blocking is mutual and filters the feed rather than just hiding replies. None of that was asked for by the fifteen or so accounts currently in there. It exists because the first person who needs reporting shows up before the first moderator does, and that is not something you can add in a hurry.

Writing a post in Game Verdict: a title field, Write and Preview tabs, a markdown formatting toolbar, a body field, and an attached game showing that its live verdict breakdown will be embedded.
Markdown, a formatting toolbar, and a game attached to the post

The GIF picker got a harder problem than it deserved. Google shut off the Tenor API on 30 June 2026, taking GIF support out of Discord, X, WhatsApp and Bluesky with it, and Giphy had already moved off free access. GIFs landed here two weeks later on Klipy, built by ex-Tenor engineers as a deliberate near-clone of the thing everyone had just lost. Rendering is restricted to an allowlist of CDN hosts rather than trusting whatever URL ends up in a post, and Tenor’s CDN stayed on that list, because its servers outlived its API.

Undocumented

An easter egg you get to keep

TL;DR

Type the old Konami cheat code and controllers rain down the page. It also unlocks a retro CRT screen effect that’s yours to keep, to turn on whenever you want it.

Type ↑ ↑ ↓ ↓ ← → ← → B A and hit Enter or Space. Keyboards, mice, and controllers rain down the page, which is a nice five seconds and then it’s over.

Game Verdict's Quick Vote page with keyboard, mouse and controller icons falling down the screen after entering the Konami code.
The icons that fall are the three things you are voting between

What’s actually interesting is what survives the five seconds. The code unlocks CRT mode, and CRT mode isn’t a moment: it’s a real setting, saved to your profile and hydrated on the server, that you can turn back on whenever you like. Three fixed layers do the work, all of them pointer-events: none so nothing underneath stops being clickable.

The browse page with CRT mode toggled on: scanlines, a vignette, and a subtle red and blue channel shift over the game grid.
Browse, with and without CRT. Flip the production state to compare

It also lives in Settings, next to the Steam library import, which is where an easter egg stops being a joke and becomes a feature somebody might actually prefer.

Game Verdict's settings page showing the Steam library import panel and the CRT mode toggle.
Settings: Steam import, and CRT sitting there like it always belonged

There’s a second code. Finish the sequence, tap Tab for Select, then hit Enter, and you get the Contra two-player variant. It greets you differently, keeps greeting you on every entry rather than only the first, and offers the most secret badge on the site.

The first-time Konami dialog, titled with the arrow sequence, reading: the debate is settled.
1P: the debate is settled
The two-player Konami dialog, titled with the sequence plus Select and Start, reading: 30 lives. Player 2 has entered the game. You remembered the Contra 2-player code. Respect.
2P: 30 lives, and the most secret badge on the site

All of it works signed out. The rain falls, the CRT turns on, and the badge waits until you feel like claiming it. Which is the same idea as the voting, arrived at from a completely different direction: the good part should never be behind the account.

The code works here too. This page has been listening the whole time.
Try it on this page