[HN Gopher] Play snake in the URL address bar
       ___________________________________________________________________
        
       Play snake in the URL address bar
        
       Author : macote
       Score  : 811 points
       Date   : 2025-09-28 21:08 UTC (1 days ago)
        
 (HTM) web link (demian.ferrei.ro)
 (TXT) w3m dump (demian.ferrei.ro)
        
       | iamjackg wrote:
       | I was pleasantly surprised by how responsive it was, and
       | overjoyed when I clicked back and immediately came back to HN: no
       | messy history. Genius idea!
        
         | dhsysusbsjsi wrote:
         | reading the source it looks like for some browsers that rate
         | limit url updates, it has to use a different way that nukes
         | your back button ability.
        
           | senfiaj wrote:
           | function drawWorld() { var hash = '#|' + gridString() +
           | '|[score:' + currentScore() + ']';                 if
           | (urlRevealed) {         // Use the original game
           | representation on the on-DOM view, as there are no         //
           | escaping issues there.         $('#url').textContent =
           | location.href.replace(/#.*$/, '') + hash;       }
           | // Modern browsers escape whitespace characters on the
           | address bar URL for       // security reasons. In case this
           | browser does that, replace the empty Braille       //
           | character with a non-whitespace (and hopefully non-intrusive)
           | symbol.       if (whitespaceReplacementChar) {         hash =
           | hash.replace(/\u2800/g, whitespaceReplacementChar);       }
           | history.replaceState(null, null, hash);            // Some
           | browsers have a rate limit on history.replaceState() calls,
           | resulting       // in the URL not updating at all for a
           | couple of seconds. In those cases,       // location.hash is
           | updated directly, which is unfortunate, as it causes a new
           | // navigation entry to be created each time, effectively
           | hijacking the user's       // back button.       if
           | (decodeURIComponent(location.hash) !== hash) {
           | console.warn(           'history.replaceState() throttling
           | detected. Using location.hash fallback'         );
           | location.hash = hash;       }     }
        
         | mjmas wrote:
         | history.pushState vs history.replaceState
        
           | zaidhaan wrote:
           | One thing to note about these two APIs is that they affect
           | how the _session history_ (the back /forward stack) behaves,
           | but the _global browser history_ (entries shown in the
           | History tab) is separate.
           | 
           | 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
        
             | franky47 wrote:
             | Thanks for the feedback, Vercel domain uses nuqs [1] (I'm
             | the author) for URL state, and I agree flooding the browser
             | history is a bad experience.
             | 
             | 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
        
               | zaidhaan wrote:
               | I am not aware of any approaches that work consistently
               | across all major browsers. This matter is nothing new --
               | there's a Bugzilla report[0] from 13 years ago about this
               | behavior that remains open.
               | 
               | 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
        
       | Velocifyer wrote:
       | This is cool
        
       | pards wrote:
       | Such a unique, innovative idea. Well played.
        
       | foresterre wrote:
       | For those that missed it initially, and didn't quite got how it
       | works the first time, there is a small cyan question mark at the
       | top left, which states:
       | 
       | > 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!
        
       | arguflow wrote:
       | Harder than I expected, the extra blank dots all around the snake
       | are kind of distracting, how does it look when they aren't on the
       | page?
        
         | epidemian wrote:
         | This is how it used to look in olden days, before browsers
         | plundered our fun in the name of security:
         | https://raw.githubusercontent.com/epidemian/snake/refs/heads...
        
       | akarki15 wrote:
       | This is why i come to hackernews. :) made my day
        
         | cutemonster wrote:
         | I got 23 points but I got distracted!
        
       | mr_tox wrote:
       | next time doom please :)
        
         | epidemian wrote:
         | I've actually thought about rendering DOOM on the favicon. I
         | don't see why it shouldn't be possible. Maybe @Franciscouzo
         | could tackle that challenge!
         | https://news.ycombinator.com/item?id=45408825
        
           | tombert wrote:
           | I am pretty sure this already exists.
           | 
           | https://vidferris.github.io/FaviconDoom/favicondoom.html
        
         | amelius wrote:
         | ffmpeg
        
       | zikero wrote:
       | this is the most cursed thing i've seen
        
         | epidemian wrote:
         | Thanks, that's one of the best compliments i've read :D
        
       | kwar13 wrote:
       | What a neat little idea lol. It's using the Braille patterns to
       | update the URL with the dots. Love it.
       | 
       | https://github.com/epidemian/snake/blob/master/snake.js
        
       | 650 wrote:
       | Very cool, would love to see source code. For what its worth no
       | AI was able to replicate this.
        
         | dorfsmay wrote:
         | There's a link to "code" at the bottom of the page.
        
         | epidemian wrote:
         | The source code is not minified or anything, ctrl+u is your
         | friend :)
         | 
         | 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)
        
       | charcircuit wrote:
       | >demian.ferrei.ro/snake#|%E2%96%91%E2%96%91%E2%96%91%E2%96%91%E2%
       | A0%88%E2%96%91%E2%96%91%E2%A0%A4%E2%A0%A4%E2%96%91%E2%96%91%E2%96
       | %91%E2%96%91%E2%96%91%E2%96%91%E2%96%91%E2%96%91%E2%96%91%E2%96%9
       | 1%E2%96%91|[score:0]
       | 
       | This is too confusing to play on firefox.
        
         | BoppreH wrote:
         | Worked just fine on version 143.
        
           | bmicraft wrote:
           | Not for me on Android (same version)
        
             | epidemian wrote:
             | Yeah, sorry for that. The game actually used to work
             | decently well on mobile browsers.
             | 
             | 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
        
       | ai_viewz wrote:
       | nice i enjoyed it
        
       | roggenbuck wrote:
       | This is really creative! Very well done. Surprisingly fast too.
        
       | MontyCarloHall wrote:
       | This is awesome. My only issue is that the character used for
       | whitespace looks janky in my browser, like a bunch of non-
       | monospaced squares. A potential remedy: because Unicode contains
       | all 256 possible 4x2 Braille patterns, why not use [d12345678] as
       | the background and carve out the snake/food as negative space,
       | e.g.
       | 
       | [d12345678][d12345678][d124578][d124578][d124578][d124578][d12457
       | 8][d14678][d1345678][d12345678][d1234678][d12345678][d12345678][d
       | 12345678]
       | 
       | This would ensure uniform spacing and is just as legible.
        
         | epidemian wrote:
         | Yes, i thought of doing that. The problem is that, while it
         | would definitely help on the early game, it would also mess
         | things badly on the late game. As you snake grows, it'll take
         | more and more space on the grid, and you'll start seeing more
         | and more janky whitespace-replacement characters.
         | 
         | 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 "?"
        
           | worldsayshi wrote:
           | You could also flip the palette at half point.
        
       | samixg wrote:
       | it took me a while to understand how to play it, but holy shit
       | this is impressive! nice work
        
       | alistairSH wrote:
       | I just see the address? Safari on iOS.
        
         | ashu1461 wrote:
         | See closely there should be snake in the bar as well, which
         | responds if you use the arrows.
        
           | alistairSH wrote:
           | Definitely nothing there on iOS Safari.
           | 
           | 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?
        
       | Franciscouzo wrote:
       | I made a similar thing some time ago, but with the favicon.
       | 
       | https://franciscouzo.github.io/favisnake/
        
         | aquova wrote:
         | Likewise, I did 2048 with the favicon years ago
         | 
         | https://aquova.net/games/2048/
        
           | shreddit wrote:
           | It is surprisingly playable, i got up to 1500
        
           | thehyperflux wrote:
           | I love it. Scored 2144. A reference for the colours might be
           | nice but not essential
        
           | BeFlatXIII wrote:
           | Safari doesn't like to update the favicon, SAD!
        
           | larodi wrote:
           | Guys, you legend. There isnt perhaps an even smaller real
           | estate for a snake game.
        
         | epidemian wrote:
         | Oh, this is lovely. The more retina, the less playable it gets
         | :D
         | 
         | Update: amazing game-over effect!
        
         | darajava wrote:
         | Amazing idea. I don't see any food though.
        
           | jihadjihad wrote:
           | You can be forgiven, it's only one tiny edible pixel after
           | all.
        
       | drbig wrote:
       | Very clever, and playable! Thanks.
        
       | rabbitlord wrote:
       | Bro the game is intense!
        
       | epidemian wrote:
       | Wow! It's such a surprise to see this old project of mine here on
       | HN front page!
       | 
       | 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! :)
        
         | em-bee wrote:
         | _https://github.com/epidemian/snake/blob/master/gameplay.gif?..
         | ._
         | 
         | 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.
        
         | antisol wrote:
         | This is very very cool. And also the second worst abuse of the
         | browser I've ever seen ;) I doff my hat to you!
        
       | system2 wrote:
       | To an average Joe, this might not look like anything but to me
       | this is wild. How do you people even come up with these things...
        
         | Dban1 wrote:
         | Organic Intelligence
        
       | jspann wrote:
       | This is fun!
        
       | Nevermark wrote:
       | Very cool!
       | 
       | 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
        
       | boguscoder wrote:
       | Mind it, mobile browsers seem to be having hard time with this,
       | which is probably expected
        
       | tbolt wrote:
       | 10/10
        
       | pratikstemkar wrote:
       | made my day. didn't know this was even possible.
        
       | Uptrenda wrote:
       | Incredibly out-of-the box, whoever made this. Gives me severe eye
       | strain but I am impressed at the creativity here! Awesome.
       | 
       | 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.
        
       | nenenejej wrote:
       | Now make it multiplayer!
        
         | Dban1 wrote:
         | and blockchain
        
           | jumperabg wrote:
           | and AI snakes
        
       | usaphp wrote:
       | RIP to your history log in the browser.
        
         | amelius wrote:
         | Wait, this means that any website can turn my browser history
         | into garbage?
         | 
         | (Looks like a missed opportunity for adtech.)
        
           | zparky wrote:
           | yes. look up 'ruin my search history' or similar - it floods
           | your history with questionable searches.
        
           | chneu wrote:
           | ads have been abusing browser history for a long time
        
         | fouronnes3 wrote:
         | In firefox: history -> snake game -> forget about website
        
       | dasefx wrote:
       | Warning, if you actually use your browser history, play this in
       | incognito mode or equivalent.
        
         | rob74 wrote:
         | Thanks for the heads up, I just cleared the history for the
         | last hour, that works too (but using incognito mode is
         | definitely better).
        
       | Danilka wrote:
       | What the hack, this is absolutely awesome! Pun intended.
        
       | terribleperson wrote:
       | This actually sent me into a fit of laughter at the sheer
       | absurdity. This is incredibly cool.
        
       | MangoToupe wrote:
       | Is there a demo somewhere for those of us without the intended
       | browser/os combo?
       | 
       | Edit:
       | https://raw.githubusercontent.com/epidemian/snake/refs/heads...
        
       | CobrastanJorji wrote:
       | Fantastic. I love people finding really creative ways to make
       | things interactive in weird ways. 100% hacker spirit. Good job.
        
       | liqilin1567 wrote:
       | Very interesting. What inspired you to build this, I'd love to
       | hear the story behind this.
        
         | epidemian wrote:
         | > What inspired you to build this, I'd love to hear the story
         | behind this.
         | 
         | 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.
        
       | nicman23 wrote:
       | .... time to port doom ?
        
       | masteruvpuppetz wrote:
       | HAHAHA looool!! this is awesome
        
       | cwsx wrote:
       | This is so fucking cool - took me a bit to figure out how the
       | rendering/movement worked but fun after that.
        
       | dankle wrote:
       | Not on mobile you dont
        
       | pbd wrote:
       | ChatGPT can't invent this :-) . Love the creativity.
        
       | throwmeaway222 wrote:
       | wow- do doom next
        
         | jslakro wrote:
         | It's not Doom but it allows to walk in a 3d world environment
         | https://matthew.rayfield.world/articles/games-and-graphics-i...
        
       | amelius wrote:
       | I'm looking for snake that can be played with voice commands.
        
         | fouronnes3 wrote:
         | duolingo x snake
        
         | pnt12 wrote:
         | I tried to program flappy bird on that, back then the delay on
         | Android made it impossible, as you need quick feedback.
         | 
         | 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!
        
       | heroku wrote:
       | Why do people don't work on useful things. Stop mis-using the
       | internet.
        
         | detaro wrote:
         | Very useful thing you are working on here
        
           | heroku wrote:
           | Why would you turn the discussion on me. I am simply
           | informing citizens.
        
             | detaro wrote:
             | But you could be working on something useful instead.
             | "Informing citizens" that you hate fun isn't useful.
        
               | heroku wrote:
               | If more people simply didn't promote this kind of
               | nonsense, and worked on proper educational content, world
               | would be a more useful place. But here we are. I simply
               | don't attend. I am more useful than the rest of these
               | people.
        
         | joemi wrote:
         | A learning experience (by making this game) is useful to the
         | person making it. Honing one's skills (by making this game) is
         | useful to the person making it. Taking breaks from work (by
         | playing this game) is useful to those who need a break.
         | Learning (by looking at how this was made) is useful to those
         | who wish to learn.
         | 
         | Does it solve world hunger? No, not at all. But it is indeed
         | still useful to some people.
        
       ___________________________________________________________________
       (page generated 2025-09-29 23:01 UTC)