Play Snake in the URL Address Bar
Posted3 months agoActive3 months ago
demian.ferrei.roTechstoryHigh profile
excitedpositive
Debate
20/100
Creative CodingBrowser HacksGame Development
Key topics
Creative Coding
Browser Hacks
Game Development
A user shared a link to a snake game that can be played in the URL address bar, sparking excitement and creativity in the HN community, with many praising its ingenuity and playability.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
22m
Peak period
67
0-12h
Avg / period
23
Comment distribution92 data points
Loading chart...
Based on 92 loaded comments
Key moments
- 01Story posted
Sep 28, 2025 at 5:08 PM EDT
3 months ago
Step 01 - 02First comment
Sep 28, 2025 at 5:30 PM EDT
22m after posting
Step 02 - 03Peak activity
67 comments in 0-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Oct 4, 2025 at 3:54 PM EDT
3 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45408021Type: storyLast synced: 11/23/2025, 1:00:33 AM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
Most browsers record every change in the global history regardless of whether `history.pushState` or `history.replaceState` is used. The HTML Spec[0] is explicit about session history but does not define how global history should behave.
I can understand why the spec makes no mention of this -- global history is a user-facing UI feature, similar to address bar autocomplete, and it makes sense for browsers to control this behavior. That said, I'm always annoyed when I look into my history tab after visiting a page like this (e.g. Vercel Domains[1]), and see my global history flooded with entries for each individual keystroke I've made, all in the name of "user experience".
In this particular case, it's just a fun gimmick, but for everyday websites I'd much prefer if they just debounced the updates to the URL to avoid cluttering the global history.
[0]: https://html.spec.whatwg.org/#navigation-and-session-history
[1]: https://vercel.com/domains
Is there a way to update the URL (ie: keeping it reactive in the address bar) without creating those history entries, or to ask the browser to squash the last entry it created into the previous one?
[1] https://nuqs.dev
Since there's no spec for global history and it's unlikely one will be introduced, the most practical solution to avoid flooding the browser history would be to debounce the changes.
This is the approach taken by Google Maps -- with maps being a well-known case where URL updates would clutter the history, as noted in the Bugzilla report.
[0] https://bugzilla.mozilla.org/show_bug.cgi?id=753264
https://vidferris.github.io/FaviconDoom/favicondoom.html
IDK about the AI claim tho. The game has been there for like 10 years, so it's probably in the training data of these things. The bots might be able to replicate it, but they surely won't be able to enjoy it! (for now at least)
This is too confusing to play on firefox.
If you're brave enough to try on a mobile device, there's a way to see the current URL without escaping on the page: clicking on that "?". The mobile controls are clunky, but you'll be rewarded with the ability to share your highscores with friends! :P
⣿⣿⣛⣛⣛⣛⣛⣩⣽⣿⣯⣿⣿⣿
This would ensure uniform spacing and is just as legible.
The game gets faster as you progress, so it's definitely not a good idea to make it jankyer when you're try-harding it :P
I'd love to know of a way of "fixing" this jankyness issue properly. Without admitting defeat and rendering to some other text-admitting output, like the page <title>, as this oher snake game that was recently posted on Reddit does: https://old.reddit.com/r/webdev/comments/1n9z77e/snake_in_th...
But, for now, if you're actually trying to get a high score, i think the best approach is rendering the URL on page, by clicking on the "?"
And in MacOS Safari, I see the game, but no clue how to play it... no matter what I do, it appears to reset to 0 points with the snake coming from the left?
https://franciscouzo.github.io/favisnake/
https://aquova.net/games/2048/
Update: amazing game-over effect!
I must say, if you're experiencing any issues playing this, it's probably because it was designed to be played on the browsers of 10 years ago hehe. Here's how the game used to look and play in its former days of glory: https://github.com/epidemian/snake/blob/master/gameplay.gif?...
Since then, browsers have made some so-called "security" "improvements" that heavily hindered the capabilities of addressbar-based videogames. You can see traces of this on the game source code, and on the commit history.
At some point, pushing things to `history.replaceState()` got super rate-limited on Chrome, to something like tens of updates per minute IIRC, which totally wrecked the playing experience. I think i got around this by falling back to using `location.hash` directly. I think Chrome later rose this throttling to something more sensible. IDK if enough to play Crysis at 60fps on the addressbar, but enough for a snake game. And if not, sorry for messing up your Back button!
The worst of these security-excused changes was Firefox and Chrome starting to escape all whitespace characters (and others) on URLs. The game uses Braille characters to "render" its grid world, and blank Braille characters are abundant, especially on the early game. I think i made some comments on the browsers' issue trackers, and even received some sympathy from the developers (or maybe this was on the throttling of history, i don't remember). But of course, and as usual, "security" trumps over fun.
I ended up trying to counteract this URL escaping mechanisms with some horrible, really really horrible, indefensible, shameful, canvas-based font-measuring hack to replace blank Braille characters with some other character that doesn't get escaped and is more or less the same width, and as blank as possible. See https://github.com/epidemian/snake/blob/e9d5591a613afabc7e11.... If you have any idea of how to do this in a less soul-damning way, please let me know!
I think the game never worked properly on Safari. I know the browser used to hide the URL fragment, or maybe everything other than the domain name. I've no idea what it does now; does it even allow users to visit random webpages or does it mandate a separate app for everything? /s
In case my pile of hacks fails thoroughly, i resignedly added a way of showing the intended URL on the actual page content, by clicking on the "?"
Anyways, i should probably write a blog post about this little silly thing. Thanks for playing! :)
that looks a lot better. i am seeing the address bar filled with black and white pixelated block characters (U+2591 light shade). it still works though.
(Looks like a missed opportunity for adtech.)
Actually, i don't remember! Sorry, it's been a while (a decade, it seems... oh well)
This is probably my mind retro-creating a story, but i think this started with me wondering about how the Braille system worked. Like, did each Braille symbol map to a single letter, or to a whole syllable, or even a concept? Or, were more than one Braille symbol needed for some letters, like Morse?
Turns out each Braille symbol fits within a 2x4 grid of points. That's 2 possible states (point is on or off) for each of those 8 points. So 2^8 = 256 possible values. That's a byte! And luckily, Unicode encodes all those 256 possible values, and maps them to codepoints in a very systematic way.
So obviously, i started to wonder what kind of things could be represented on these Braille grids. The snake game was a natural fit, and a fun programming experience. But i also considered other things, like a horizontal Tetris. Or a Game of Life rendered on the URL, which i actually implemented(1), but i didn't find as entertaining as snake, because the 4-tile height restriction impeded any interesting patterns, like gliders (even with wrap-around logic). I think i even made some brute-force searching for horizontal or diagonal gliders trying out different born/survive rules(2), but couldn't find any interesting patterns, other than still life, blinkers, and some "moving walls" kind of things.
Anyways, that's for the Braille part. The idea of using the address bar to render the game, i have no idea where that came from TBH. Maybe i stole the idea from some other animated or pretty thing on URLs? I wish i remembered.
(1): https://github.com/epidemian/URLife
(2): See https://en.wikipedia.org/wiki/Life-like_cellular_automaton. The Game of Life rabbit hole goes deep.
Scoping it down and making a side scroller where the characters runs on the floor and only has to jump iver obstacles made it more mearable!
Does it solve world hunger? No, not at all. But it is indeed still useful to some people.
Edit: https://raw.githubusercontent.com/epidemian/snake/refs/heads...
Btw small suggestion: might make the game more playable if the snake could loop-back around if it went out of bounds. It would make up for some responsiveness issues. Then just have failure being if you eat yourself.
https://github.com/epidemian/snake/blob/master/snake.js
I created a snake game like this on the Tandy Pocket Computer. [0]
I even managed to create a 20 room sub-set of Zork.
Desperately primitive times, required desperate game compression measures.
[0] https://en.wikipedia.org/wiki/Tandy_Pocket_Computer
> Use the arrow keys or WASD to control the snake on the URL. Click here if you can't see the page URL or if it looks messed up with some weird slashes
Additionally: you need a browser window where you're address bar is long enough to see the world ;).
Love the concept, it works quite well!