This month we shipped four games every single one of you already knows how to play: Sudoku, Klondike Solitaire, Snake, and Mines. That's the easy sentence. Here's the part nobody warns you about — "everybody already knows the rules" is exactly what makes these games merciless to build.

There's nowhere to hide. If a Sudoku has two solutions, someone notices. If the first Mines click detonates, someone quits and never comes back. You can't paper over a sloppy build with novelty when the player has been keeping score against the platonic version of this game since childhood.

So instead of a changelog, here's the one design decision we made behind each one, and why it was the one that mattered.

Sudoku: every puzzle has exactly one solution

A real Sudoku has a single solution. A puzzle with two valid answers isn't a harder Sudoku — it's a broken one. The whole game is a chain of deductions ("this cell must be a 4, because nothing else fits"), and that chain snaps the instant a cell can legitimately hold two different numbers. You're no longer solving. You're guessing, and the game lied to you about which one you were doing.

Sudoku on PlayEye showing a partially filled 9 by 9 grid with given clues and a number pad below
Sudoku: a uniqueness check runs after every clue removal, so every level is solvable by logic alone.

Guaranteeing that one-and-only solution is more work than it looks. Our generator fills a complete board by backtracking, then strips clues out one at a time — but after every single removal it runs a counting solver that short-circuits the instant it spots a second solution. If pulling a clue would crack the puzzle open into ambiguity, we put the clue right back:

const backup = puzzle[pos]
puzzle[pos] = 0
if (!hasUniqueSolution(puzzle)) {
  puzzle[pos] = backup // restore — removing this breaks uniqueness
}

Difficulty, then, is just where we stop stripping: 38 givens for Easy, 32 for Medium, 26 for Hard, 22 for Expert. Fewer clues, longer deductive chains, more staring. But every puzzle at every level stays solvable by logic alone — no guessing required, not once, not even on Expert. We wrote a whole post on the generator if you want the guts, or just go play it: Sudoku.

Solitaire: only deals you can actually win

Roughly one in five randomly shuffled Klondike deals is mathematically impossible to win. Not hard. Impossible — no sequence of legal moves clears it, no matter how perfectly you play. We refused to ship that coin flip.

So before any deal reaches you, it's been beaten by a full-information solver that plays the board with every card face-up — and only the deals it can prove winnable inside a five-second budget make the cut. About 70% of random shuffles pass. The rest get quietly discarded before you ever see them.

The payoff: when you lose, there was a winning line you missed — not a rigged deal you were handed. That's a better loss. We wrote a separate post on the solver and the real generation numbers — the live pool is 1,067 verified deals — but the short version waits for you on the Klondike Solitaire page.

Snake: a two-deep input queue so fast turns register

Snake's signature heartbreak is death by dropped input. You swipe up, then instantly right to hook around a piece of food — but the game only processes one direction per tick, so your second swipe evaporates and you sail proudly into the wall. You did everything right. The game just wasn't listening yet.

Snake on PlayEye showing the snake winding across the grid toward a piece of food, with the current score above
Snake buffers up to two turns, so a fast up-then-right corner doesn't drop an input and kill you unfairly.

We fixed it with a small input queue. Up to two directions buffer, and each new input is checked against the last queued direction rather than your current heading — so two fast swipes inside a single tick both land instead of fighting each other:

enqueueDirection(dir: Direction) {
  if (this.inputQueue.length >= 2) return
  const ref = this.pendingDirection
  if (dir === ref || dir === OPPOSITE[ref]) return // no-ops & 180° reversals
  this.inputQueue.push(dir)
}

It also quietly blocks the instant-death 180° reversal — you can't whip directly back into your own neck, because that was never a turn you meant to make. And the three speeds aren't decoration; the gap between them is real: 180 ms per tick on Slow, 120 ms on Normal, 75 ms on Fast. That Fast tick is under a tenth of a second between moves. It's not "Snake but quicker." It's a different game. Play Snake.

Mines: the name, and why your first click is always safe

Two decisions here.

First, the name. The genre's most famous title is a trademark that isn't ours, so we kept ours plainly, almost boringly descriptive: Mines. That's a deliberate, conservative call. We'd rather wear a slightly generic name than borrow one we have no right to.

Second — and this is the one you'll actually feelyour first click can never hit a mine. In a lot of minesweeper clones you can lose on move one, which is pure bad luck wearing the costume of a game, and a miserable first impression. So we don't place any mines until after your opening reveal. And we don't just spare the clicked cell — we exclude all eight of its neighbors too, so your first tap always cracks open a usable region instead of revealing a single lonely 1 and stranding you:

const safe = new Set<number>()
safe.add(safeR * cols + safeC)
forEachNeighbour(state, safeR, safeC, (nr, nc) => safe.add(nr * cols + nc))
// ...mines are then placed only on cells NOT in `safe`.

Three boards ship at the standard sizes: Beginner (9×9, 10 mines), Intermediate (16×16, 40 mines), and Expert (16×30, 99 mines). Chording — clicking a satisfied number to sweep its neighbors — works too. Play Mines. And if you want to actually get good rather than just lucky, we worked the three patterns that crack most boards — 1-1, 1-2-1, and 1-2-2-1 — cell by cell in Minesweeper patterns explained.

The thread running through all four

Look closely and these four decisions are secretly the same decision wearing four costumes: remove the unfair loss.

The unwinnable Solitaire deal. The ambiguous Sudoku. The dropped Snake turn. The first-click mine. Every one of them is a way for a player to lose to the game's plumbing rather than to the game itself — and losing to plumbing is the worst feeling a game can hand you, because there's nothing to learn from it and no rematch that feels fair. Killing those losses is the entire job.

It's also the kind of work that only happens when the people shipping the game wrote the engine themselves. You can't strip an unfair loss out of a black box you licensed from someone else; you can only find it, swear at it, and fix it when the source is yours. That's the whole reason these four are on PlayEye and not bought in from a catalog.

More classics are in the pipeline. We'll hold the standard exactly where it is.