Day two ran from a dependency bump at 13:10 to an assisted-typing mode at 23:26, twelve commits, all straight to main. By midnight the game had a leaderboard page, a unified toolbar, a subtle engine fix, full Norwegian bokmål support, and fuzzy word suggestions. The Norwegian support and the suggestions would both be ripped out within weeks. This is the post about a day spent building what was exciting rather than what the game was ready for.

The morning went to security alerts, and to learning what a pnpm override actually does. The path traversal advisory against vite was easy to patch in the direct dependency, but vitest 2 depends on vite 5, which resolved to a version inside the vulnerable range, so an override pinned every vite resolution to the patched line. That worked. It also triggered a full re-resolution of the lockfile, which deduped esbuild to 0.27.7 everywhere, including inside vite's production bundler, and esbuild 0.27.7 could not transform destructured for-of loops for the configured browser targets. The deploy failed. The fix was narrowing the esbuild override to a range that satisfies the security advisory while staying below the regression. An override is not a patch to one package; it is permission for the resolver to rethink everything, and the production build joined the pre-push verification checklist that afternoon.

Midday brought the leaderboard its own page, with day-by-day navigation, and a route swap: the daily challenge moved to the root URL and free play moved aside to its own path. The reasoning was that the daily is the product, so the URL should say so, and that arrangement held for three months until a main menu took the root back. The afternoon replaced the per-page nav pills with a single fixed toolbar, taught the navigation guard to catch mode switches mid-animation, and gave free play a weekly leaderboard of its own. One mobile bug from that batch is worth recording: the hamburger menu was hidden by a base display:none that a media query was supposed to override, and in the production CSS bundle the ordering flipped, so the menu never appeared on phones. The rewrite went mobile-first, visible by default and hidden at desktop widths, which does not depend on rule order at all.

At 17:54 came the quietest and most consequential fix of the day. Apples were spawning in a pattern players could see: same row, opposite side, game after game. The cause was that the PRNG state was frozen at game init, so every replacement apple re-created the generator from the same seed, drew the identical float, and picked the same fractional rank in the row-sorted list of empty cells. The fix threads the PRNG state through word submission and saves the advanced state back into the game state, so the sequence moves on with every spawn. At the time this was a cosmetic fix. It later became load-bearing: the daily challenge depends on server and client running the same PRNG sequence to agree on where fruit lands, and that only works because the state advances deterministically through every call.

Then, at 18:59, Norwegian. Two commits, one evening: a language config module as the single source of truth for direction letters, keyboard layouts, UI strings and valid-character rules per language; Norwegian direction keys o, n, v and h; keyboard rows with å, æ and ø; the database schema rekeyed so dictionaries, daily challenges and scores are scoped per language; a Hunspell dictionary parsed into 318,777 Norwegian words; and roughly 80 UI strings translated across 17 components. As engineering it was a respectable evening. As product it answered a question nobody had asked: the game was one day old, its English core still had bugs from that morning, and the Norwegian word list was an unfiltered spell-check dictionary, not a curated set anyone had play-tested. It got built because building it was fun.

The day closed with two more things. A license attribution file forced an honest look at the data sources, and one of them, the SOWPODS word list, turned out to be proprietary; that discovery set up the next day's work. And assisted mode: when a word missed the dictionary, a Levenshtein search offered the nearest match, the player could accept it, and any session that did was flagged as assisted on the leaderboard. A complete little feature, fully translated into both languages, solving a problem no player had reported.

The scoreboard for day two, written with hindsight: the leaderboard page, the toolbar and the PRNG fix are all still here. Assisted mode was deleted nine days later. The entire translation layer was deleted three weeks later, and Norwegian did not properly return for three months, rebuilt from a real lexical database with per-language letter scoring and its own design decisions. The direction letters o, n, v and h survived into that version unchanged, which is a thin but real thread from this evening to the game that exists now. The lesson is not that the Norwegian evening was wasted; it is that "can be built in an evening" and "should exist yet" are different questions, and on a one-day-old game the second one should decide.

The next day the prototype became a project: the first pull requests, CI, and a licensing-driven word list swap. That is its own post.