[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)