I wanted to play Sudoku at breakfast without sitting through a video ad. So I built that, and then I kept building. Thirty-five games later, the constraint that shaped everything is that there is no backend: thirty-four of the thirty-five never make a network call at all, and the thirty-fifth falls back to authored content when the network is gone.
The Problem
Daily games (Sudoku, Connections, Spelling Bee) are good. The ads wrapped around them are not. The New York Times charges a subscription. The free alternatives are ad-ridden. The mobile versions track you.
So the bar was low and specific: the same puzzle every morning, no video, no account, and no reason to look at a store page.
What It Is
A curated hub of ad-free games at games.wanessalabs.com. Every game is either built from scratch or forked from an open-source project with full asset replacement and rebrand. No ads. No tracking. Every puzzle and every rule ships inside the bundle, so there is almost nothing to be offline from.
35 games live. The home grid is grouped into eight sections rather than one long scroll. One of them, Casino Trainer, holds the three games whose point is learning the odds rather than winning: craps, blackjack and a poker trainer, each with a coach that explains what the right play is and why.
Classic games
- Sudoku: Ad-free daily puzzle, same seed for all players, streak tracking.
- Linked (Connections): Daily word grouping game with 40+ curated puzzles. Sideloaded as Android APK via Capacitor.
- Anagram Daily: Spelling Bee variant with inline hints always visible on the board.
- Mini Crossword: A daily 5x5 grid of intersecting words.
Card games
- Poker Friday: Texas Hold’em against bots, with a coach showing live win odds, outs, and pot odds.
- Big Two (鋤大D): Single-player Big Two against three AI, on an engine written before any interface existed.
- Last Card: House-rules Uno built around one family draw-up-to-two rule, with a call-and-catch window tuned as a human-factors number rather than a guess.
- 13张 (Chinese Poker): Split thirteen cards into rows of 3, 5 and 5. One category ladder lets a three-card row be compared against a five-card row, and an exhaustive 72,072-partition solver picks the best split in about four milliseconds.
Pass and Play
Two humans, one device, taking turns. Three of the card games above have a pass-and-play mode too, but for these two it is the whole point.
- Low Roller: Dice game where the lowest score wins. Solo or pass-and-play.
- Drop4: Drop discs down a seven-by-six grid and get four in a row, against the person next to you or against Evie, a search bot whose depth was picked by benchmark rather than by guess. Her first build took 596ms a move, which is a freeze, so the search was rewritten onto a make/unmake scratch board and shipped at 19.7ms.
3D
The only two games here that render in three dimensions, and they get there by opposite routes.
- Paper Squadron: A low-poly, flat-shaded on-rails shooter in the spirit of early Star Fox, hand-rolled on a canvas software rasterizer with zero 3D libraries: its own matrix math, backface culling, and a painter’s-algorithm depth sort. Fly a folded paper plane through daily seeded waves of origami, roll to deflect, and take down one of 30 distinct origami bosses. A Bestiary tracks every boss you have beaten, all time.
- 2x2 Cube Trainer: A pocket cube that knows the optimal solution and tells you how close you got. An exhaustive solver runs in a Web Worker so the answer is provably shortest rather than merely good, and the geometry sits behind a swappable seam, so the cube is one puzzle shape among possible others rather than the hardcoded assumption. This is the one game that uses a 3D library.
Fun and addictive
- Honey, I Loaded the Dishwasher: Isometric drag-and-drop puzzle with a wife AI. First 10 levels free; chapters open via Stripe.
- The Monkey Paw: Negotiate a wish you cannot un-word. Twenty-one scenarios, and the ending is written on the spot by a language model when the network is there. It plays offline through authored endings when it is not. This is the only server call in the whole hub.
- Snack Pop: Match food emojis into combos against a daily seeded board.
- 2048: Open-source port with score persistence and share card.
- Critter Blocks: A daily 8x8 polyomino puzzle on a three-minute clock, where every piece is an animal. Shape, silhouette and colour all carry the same information, so it is playable with no colour vision at all.
Every one of the seventeen home cards carries its own illustration, so the hub reads as one catalog rather than a folder.
The kids tab collects eighteen kid-friendly games in two groups: nine to play, including a gentler 6x6 Sudoku that lives only there, and nine to practise with, being spelling, math drill, word search, typing, a paint-by-math game, and the four maths games built for the trail below.
A Trail Instead of a Wall
Thirty-five games is a menu to an adult and a wall to a seven-year-old. So the kids side has a maths trail: eight worlds, eighteen steps, and one thing to play next. Adding up, taking away, tens and ones, times tables, sharing out, fractions, clocks and coins, and a deduction track that ends on a full Sudoku grid.
It is a shell over games that already existed, not a new app. A step opens when the one before it is finished, at 60% accuracy or after three tries at any accuracy, so it can never become a wall of its own.
What it does not do is the point. No paywall, no streak, no timers, no notifications, no accounts, and no claims about what practice will do for your child. Some of that is policy and some of it is tested. The tested part: the progress module has a spec that reads its own source text and fails if purchase, entitle, payment, streak, notification or timer appear in the code, a second spec asserts the saved state never matches /streak/i, and a third rejects any step description that promises an outcome.
Full write-up on the Kids Game Hub page.
One Character Across Every Game
Every game in the hub feeds one collectible dress-up avatar. Play anything and you earn coins and new items for it: win a Sudoku, dress your character; hit a streak in 2048, add a new hat. The same character greets you on the home screen, sits in your profile, and headlines the kids tab. You outfit it in the wardrobe.
It is cosmetic only. You earn coins by playing, never by paying, and nothing you win changes how a game plays. No account, and it all lives on your device. It is the one thread running through a folder of otherwise separate games.
One Name, Every Game
Set your name once in the profile and the hub greets you by it each morning. Low Roller then seats you under that name instead of “Player 1”, so a pass-and-play game starts with the right person in seat one. Everyone else stays “Player 2” and up, because in pass-and-play those are other people.
The profile is also where your record lives. Every streak you are holding, ranked highest first, sits above the per-game numbers: Sudoku solves by difficulty, 2048 best score, Linked and Crossword wins, the Snack Pop high score, Dishwasher levels cleared, Anagram Genius finishes, Poker bankroll, and your lowest Low Roller total.
How It Works
Every game implements the same GameProps contract, and it is deliberately small: a seed, the list of cosmetic unlocks the player owns, and two callbacks for finishing and sharing. That is the entire shared surface. It buys uniform wiring, not uniform features.
What each game offers is recorded per game in the registry, and the spread is wider than a hub page usually admits:
| Feature | Games |
|---|---|
| Works offline | 26 of 26 |
| Daily seeded puzzle | 9 of 26 |
| Streak tracking | 6 of 26 |
| Emoji share grid | 3 of 26 |
Keeping those per game rather than per hub is what lets the kids surface ban streaks outright while Sudoku keeps one. A streak is a property of a game, never of the shell.
Revenue Model
The hub is free, and today it is free in the boring sense that almost nothing is finished enough to charge for. The tip jar is a live Stripe Payment Link. Everything else is designed and part-built.
| Upgrade | Scope | Price | State |
|---|---|---|---|
| Tip jar | Hub | Any | Live |
| Coin actions | 13 games | 0 to 25 coins | 18 live, 13 wired, on staging |
| Persistent unlocks | 2 games | 250 or 400 coins | 7 live, all 7 wired |
| Passes | Cross-game | 400 to 900 coins | 9 live, honoured everywhere |
| Supporter Pack | Hub | $5 one time | Both shop pages built, checkout not wired |
| Dishwasher chapters | Dishwasher | $0.99 to 250 coins on web | Coin path wired, native IAP still unwired |
Those counts went down between the first draft and this one. Seven priced rows were deleted after opening each game and finding the thing being sold was already on screen and free.
The interesting part is not the price list, it is what the list refuses to contain. Full write-up on the Coin Economy page, including the rule that a purchase may never make a scored run easier, which cost more features than it kept.
The old Dishwasher unlock token was computed via HMAC and verified client-side, which made the lock a speed bump rather than a vault: anyone willing to read the bundle could mint their own. Checking it properly would have cost a backend, a session and a login, which is a worse product for every honest player on a hub that deliberately has no accounts. Moving the web price to coins retires that trade rather than solving it, because a coin balance lives in the same browser the player controls. The lock is still a speed bump. It is simply now a speed bump on something with no cash value.
What Is Not Verified
The hub has 1,010 passing tests across 103 files, and that number is doing less work than it looks like it is doing.
Offline has never been watched working. Every game is flagged offline and nothing calls the network at runtime, so the architecture gives it away almost for free. But that conclusion comes from reading the precache manifest and grepping for fetch, not from a human turning the network off and playing all thirty-five. Until someone does that, offline is a well-supported inference and not an observation.
A green suite proves the code runs, not that anything appeared on screen. This project has now hit that wall three separate times: a profile modal that was mounted, tested and unreachable because its callback was never wired; a set of celebration coins parented to a button that unmounts the instant you collect, so they died on their first frame; and a text overflow in a sibling project that survived three green reviews. Tests and typecheck passed in every case. It took a browser to find each one.
The newest work is the least seen. Drop4 and the daily difficulty tiers shipped on the strength of unit tests and a written-but-unrun browser harness. Evie’s 19.7ms worst case is desktop Node; the slow-phone figure is an assumption carried forward, not a measurement.
Stack
| Tool | Role |
|---|---|
| Vite + React + TypeScript | SPA frontend, no database |
| Tailwind | Utility-first styling |
| Cloudflare Pages | Hosting |
| Cloudflare Pages Function | Exactly one endpoint, for The Monkey Paw’s endings. Everything else is static |
| localStorage | All game state, streaks, and unlock tokens via storage.ts. Avatars and trail progress sit under their own separate keys, so a bug in one cannot corrupt the others |
| Capacitor | Android APK wrapper for Linked game |
| Stripe Payment Links | Cosmetic and chapter access |


