Three arcade games with no backend. How Palette, Bloom and Sortl work.
No Supabase. No database. No API. No daily content to manage. Three games that live entirely in the browser.
DailyGuessr, FlagGuessr, and CocktailGuessr all have the same invisible infrastructure: a Supabase database holding the daily puzzles, an API route that serves today's puzzle without revealing the answer, and a content management problem — someone (me) has to keep adding new locations, flags, and cocktails before the queue runs out.
When I started planning the arcade games, I wanted to remove all of that.
No database. No API. No content queue. No "batch 3 locations due before July 4th" on the to-do list. Just games that generate their own content algorithmically, run entirely in the browser, and require zero server involvement after deployment.
Palette: the Delta-E problem
Palette's premise is simple: here's a colour, match it with sliders. The interesting question is how you score "closeness" for colours.
The naive approach — compare RGB values directly — doesn't work. Colours that look very similar to human eyes can have very different RGB values. RGB is a technical encoding, not a perceptual one.
Delta-E is a standard from colour science that measures perceived colour difference. A Delta-E of 1 is barely noticeable to a trained eye. A Delta-E of 3 is noticeable but not jarring. A Delta-E of 10 is obviously different.
The scoring works backwards from this: Delta-E 0–1 scores 10,000 (CHROMATIC GENIUS). Delta-E above 12 scores below 8,800 (COLOUR BLIND). Everything in between scales proportionally.
Claude suggested Delta-E when I described the problem. I hadn't heard of it before. The implementation converts RGB to the CIE Lab* colour space — where Delta-E calculations are done. It sounds complicated; the actual code is about 30 lines.
Bloom: flood-fill on a grid
Bloom is a flood-fill puzzle. You have a 14×14 grid of coloured cells. You pick a colour from a palette of six. Every cell adjacent to the top-left corner that matches gets flooded — filled with your colour, expanding your territory. Goal: fill the entire grid in as few moves as possible.
The daily puzzle uses a seeded random number generator — the same seed for everyone on the same day produces the same grid. No database needed. The seed is derived from the date. The grid is generated client-side, deterministically, on every load.
"Par" — the target number of moves — is calculated using a greedy approximation that picks the best colour at each step. The flood-fill itself is BFS — breadth-first search. Every adjacent matching cell gets added to a queue and processed outward. Fast, clean, about 15 lines of TypeScript.
Sortl: the puzzle generation problem
Sortl was the most complex of the three, and the one where AI design input was most significant.
The premise: tubes filled with coloured liquid layers. You pour layers between tubes — only the top layer, only into a tube that's empty or whose top layer matches. Solve by getting every tube to a single colour.
The hard part isn't the game logic — that's straightforward rules. The hard part is puzzle generation: you need puzzles that are solvable, have a specific difficulty, and can be verified as solvable before showing them to a player. An impossible puzzle is a broken game.
The solution uses BFS again — this time to verify solvability before a puzzle is stored. The generator creates a random configuration, verifies it's solvable via BFS, rejects and retries if not. For 4-tube puzzles this is fast. For 7-tube puzzles it gets slower — but still well within client-side limits.
Claude proposed the BFS verification approach when I described the problem: "I need to know if a given tube configuration is solvable before showing it to the player." The response was immediate and correct.
What "no backend" means in practice
For these three games:
- 300 levels per game, all generated deterministically from a seed array - Daily puzzle generated from the current date — no database lookup - All game state in localStorage — no user accounts, no server sync - Zero API routes — the app is entirely static HTML and JS
The tradeoff is no personalised experience: no leaderboards, no cross-device streak sync, no "your friend scored X." Everything is local.
For now that's fine. The games are free, frictionless, and load instantly. If there's ever a reason to add a backend, it can be added later. Starting without one keeps everything simple.
The compound effect
By the time Sortl launched, I had six games. The sixth was faster to build than the fifth, which was faster than the fourth. Each one inherits the decisions from every previous one: the design system, the sidebar layout, the cross-promo component, the footer, the SEO setup, the analytics integration.
The cost of a new game is now mostly just the cost of the novel thing it introduces. Sortl's novel thing was BFS puzzle verification. Everything else was already solved.
That's the real return on DailyGuessr v1 through v31.