Where's Walter?
A procedurally generated hidden-object game — find Walter, mid-wave, in a crowd of hundreds, solo or in a real-time multiplayer race.
Where's Walter? is a procedurally generated hidden-object game: find Walter — a yellow-and-blue striped sweater, green pompom beanie and a raised, waving arm — hidden in a crowd of hundreds. You can play solo on an endless supply of fresh maps, create and share custom challenges, or race friends in real-time multiplayer. Every character and background is original, procedurally generated SVG built from primitive shapes — no copied or licensed art anywhere.
The engine#
A scene is fully determined by its settings: { seed, theme, mapSize, difficulty }. The same settings always produce a pixel-identical crowd, which
is what lets the client and server agree without shipping the whole scene over
the wire. It's a TypeScript monorepo (npm workspaces) with a @walter/shared
package holding the seeded generator, RNG, hit detection, hint/score logic and
SVG renderer — imported by both client and server so maps render identically
on each side.
The part I'm proudest of: exclusivity by construction#
The hard problem in a find-Walter game is guaranteeing he's actually findable
and that no decoy is accidentally indistinguishable from him. Rather than
generate crowds and reject bad ones, I build every decoy to provably satisfy a
set of invariants: no decoy ever waves, none wears Walter's yellow+blue stripe
combo, none shares more than one of his four signature attributes, and none
renders at his 1.15× scale. These are enforced by construction, with a single
source of truth (sharedAttributeCount()), and verified by an invariant test
over 50 randomized scenes. A separate decoyTrickiness knob clusters
one-attribute near-misses around Walter to tune difficulty without ever
loosening the invariants.
Multiplayer and anti-cheat#
The server is Node + Express + Socket.IO with SQLite (better-sqlite3) for
persistence. In multiplayer, all clients get the same seed but the server
holds the authoritative Walter positions and resolves claims — first claimer
wins by server timestamp, wrong clicks earn a 2-second lockout, and timing is
owned server-side so results can't be faked by editing the client clock.
Challenges apply the same principle: coordinates are never returned by the
metadata endpoint, Walter is delivered as an opaque pre-rendered SVG fragment,
and every click is validated server-side. A hidden-object game can't be truly
zero-knowledge — the target has to be drawn to be found — but the server stays
the sole source of truth for every result.
Next, have a look at
Weft
A local-first, self-hostable Notion alternative — nested-page block editor, real-time co-editing over Yjs, Git-style version history and a graph view, all in one command.

TuneVote
Real-time music voting platform I designed, built, and operate end to end — from the Socket.io backend to production architecture, database, and deployment.