HNHacker News
TopNewBestAskShowJobs

amitp

934 karma · joined January 14, 2012

I try to write better explanations of algorithms. I'm in the Silicon Valley area (south bay) and am happy to meet for coffee or lunch. See my interactive tutorials at https://www.redblobgames.com/

twitter:@redblobgames

submissionscomments
amitp··on Draggable objects
Thanks! One of the big changes when I went from Java applets and Flash applets to HTML5 (around 2011–2012) was that I wasn't limited to only the diagrams being interactive, but I could make the rest of the page interactive too. I can change text and sample code. I can also embed widgets into text and sample code. An example is [1] where you can see the draggable numbers in the text and in the sample code, and those will change the diagram.

[1] https://www.redblobgames.com/articles/probability/damage-rol...

amitp··on Draggable objects
The way this code works, the drag motion updates some state. I can apply constraints when setting the state. Then the state drives the redisplay.

I wanted to separate the constraint system from the event handling system. Libraries like jquery-ui tie them together, so the event handling system has to know all the possible constraints. In jquery-ui, they support bounding box, axis, square grid, snapping to dom elements. But what if I wanted snapping to a hex grid, or a logarithmic scale grid, or a bounding circle? It's not supported.

In the code you'll see "state.pos = …". That's where the state is set. For constraints, I put "pos" behind a setter. Then the setter can apply the constraint, without the drag event handling code having to know what type of constraints are needed.

I should update the page to show some examples of constraints. I completely forgot to mention this aspect of the code recipe. (Thanks!)

I have some older examples of constraints at https://www.redblobgames.com/articles/curved-paths/making-of... and a prevent-collision example at https://redblobgames.github.io/circular-obstacle-pathfinding... . However I haven't tried drag-to-reorder or animated drop targets.

amitp··on Draggable objects
I don't know how to do that with the built-in drag-and-drop API. With mouse or pointer events:

1. When I get the event, I update the underlying state, but leave the DOM element alone.

2. I can apply constraints to that state. To restrict dragging to the x-axis, I would never change y.

3. I use the state to drive the redisplay of the DOM element.

Some examples of constraints I want: https://www.redblobgames.com/articles/curved-paths/making-of...

I think jQuery's drag and drop API is using the mouse events directly and not using the built-in dragstart/etc., and that's why they can apply constraints.

amitp··on Draggable objects
I don't worry about it. I usually wait a few years before using some browser feature. I'm not writing a production app and I have no customers. If I had customers, then I'd be looking at what browsers they use and making a decision based on that.

This page is not prescriptive: I'm not trying to tell everyone else what to do. This page is descriptive: I'm trying to document what works for me. For the use cases I need on my pages, pointer events cleared up a lot of glitches and edge cases I previously had with mouse+touch events. There are some that remain. I'm happy with the switch. This isn't a luxury everyone has. Not all use cases are as well supported as the things I want to do.

amitp··on Draggable objects
Oh wow, FidoNet, that brings back memories. :-) I still miss Usenet of old.
amitp··on Draggable objects
I agree, more should be written about Perlin Noise range. You might find this useful: https://digitalfreepen.com/2017/06/20/range-perlin-noise.htm...

In addition to range I'd like to see the distribution, especially with multiple octaves of noises added together. I haven't found a good page about that.

amitp··on Draggable objects
Thanks! The short answer is: no.

The longer answer is: I'm not actually sure how to solve this problem. The second site, simblob.blogspot.com, is an actual blog. It's time ordered. It has posts. But the main site, redblobgames.com, is structured as a "living document" site, not as a blog. Things are not posted in order.

I could try an automated feed that looks for any changes on pages. But I make small changes all the time. For example on [1] I changed "So far we’ve made step have the same" to "So far we’ve made steps have the same". I've been fixing a lot of broken links and typos this week, so there are lots of pages that have changed, but not in meaningful ways. I don't want those showing up on the RSS feed.

The second problem with an automated feed is that I have pages that aren't meant for publication. I collect notes for myself before I write an article, sometimes for years. For example [2] is something I may never get around to publishing. I don't want new pages to show up on the RSS feed, because most of them aren't ready yet, and some may never be.

So an alternative is for me to manually add entries to an RSS feed when they're "meaningful". I'm trying to do this by posting to the simblob.blogspot.com blog. An example is [3] where I describe the changes I'm making to the mapgen4 page. These wouldn't have been picked up by an automated feed because the HTML didn't change, but the interactive part did, so I wrote about it. Another example is [4] which is about changes to the hexagon page. I'll also go into a lot more details about why I made those changes [5].

But manually writing blog posts means there will be changes that won't show up in the RSS. Ideally I'd have some kind of automated way to flag meaningful changes to the site, but until then I am trying to write meaningful changes on the blog.

[1] https://www.redblobgames.com/pathfinding/a-star/introduction...

[2] https://www.redblobgames.com/articles/probability/loot-drops...

[3] https://simblob.blogspot.com/2023/04/improving-mapgen4s-boun...

[4] https://simblob.blogspot.com/2023/04/explaining-hexagon-layo...

[5] https://simblob.blogspot.com/2022/11/introduction-to-hexagon...

amitp··on Draggable objects
Many of the interactions I'm working on aren't about dragging elements, but instead using the drag motion to do some action. I also had trouble getting the drag-and-drop API to work inside SVG elements. I think it's solving a different problem than what I'm trying to use it for.
amitp··on Draggable objects
Thank you! I treat them as documents, with some interactive elements. I tend to avoid traditional animations because they're outside the reader's control. I want the reader to be able to pause, slow down, speed up, rewind, etc. One thing I'm going for but haven't completely achieved is that I want the diagrams to be useful even before the interaction.

I am collecting some of the design elements here: https://www.redblobgames.com/making-of/little-things/

amitp··on Draggable objects
That's great to hear — thank you!
amitp··on Draggable objects
1. I use words for variable names instead of single letters like the textbooks do. I use "priority" instead of "F", "cost_so_far" instead of "G", "heuristic" instead of "H", "cost" instead of "w", "frontier" instead of "OPEN" or "O", "visited" instead of "CLOSED" or "C", "current" instead of "u", "next" or "neighbor" instead of "v".

2. The textbooks use an "open" and "closed" set. But in code, these aren't explicitly stored in set data structures. Instead, they're implicit. The cost_so_far dict(map) contains as keys both the open and closed sets, and the frontier (priority queue) contains the open set. So in my explanation of A* I focus on these data structures (priority queue and dict) instead of the open/closed sets. And when I do talk about the sets, I talk about the combined open and closed sets, calling it "visited" or "reached", because it's the combined set that is actually in the data structures.

3. The textbooks use a priority queue with reprioritization. When you visit a node that has a lower cost than the previously found cost, you go into the priority queue and adjust the cost. In my presentation I don't use reprioritization. Instead, I insert another entry into the priority queue with the lower cost. This makes the priority queue simpler (reprioritization is complicated). And in practice, I think it's faster too.

amitp··on Draggable objects
This year I've mostly been updating existing pages in small ways (examples: [1] [2]). This week I've been fixing broken links, which isn't a good HN submission.

I think the best candidate is https://www.redblobgames.com/making-of/draggable/ . It's from earlier this year and hasn't been posted to HN yet (I think).

[1] https://simblob.blogspot.com/2023/04/explaining-hexagon-layo...

[2] https://simblob.blogspot.com/2023/04/improving-mapgen4s-boun...

amitp··on Draggable objects
Thank you everyone! What a surprise to be on HN today. Happy to answer questions!
amitp··on Draggable objects
BTW the newer RotMG maps are based on this http://www-cs-students.stanford.edu/~amitp/game-programming/...
amitp··on The Kakhovka Dam Disaster Revealed an Archaeological ‘Goldmine’
During the ice ages there were huge ice dams along the Columbia River, and when they broke it was crazy. There are lots of neat formations in central WA resulting from the floods [1].

I second the recommendation for Geology Nick but some of his videos are introductory and some are meant for his geology students. Take a look at [2] for some introductory ones.

[1] https://www.parks.wa.gov/225/Ice-Age-floods-in-Washington

[2] https://www.nickzentner.com/2-minute-geology

amitp··on Draggable objects
Tarjan's Algorithm can be used to find choke points, although I haven't tried it myself [1]. I think what I would try is Breadth First Search with multiple start points to calculate various metrics for the map [2] and maybe All-Pairs if you need more [3]. For example, you might use Tarjan's or All-Pairs to find the most commonly used corridors, and then use Breadth First Search from those "central" points to find the "farthest from central corridor" points.

[1] https://old.reddit.com/r/roguelikedev/comments/dc4orn/identi...

[2] https://www.redblobgames.com/pathfinding/distance-to-any/

[3] https://www.redblobgames.com/pathfinding/all-pairs/

amitp··on Client-side proxies – a better way to individualise the Internet? (2000)
Client-side proxies were a great deal of fun. I started in 1997 with the idea that I could intercept java applets and inspect/modify the byte code. For example I scanned for "new Sound()" and created a gui frame with play/stop buttons for each sound object created. I also blocked some URLs from loading (e.g. ads).

By 1998 I realized that the ad blocking part was much more interesting to me than modifying java applet bytecode, and I started modifying HTML and other content. Instead of just blocking the ads, I removed that HTML so that the layout would change. But I also experimented with altering images, so for example I changed Slashdot's color from green to blue by changing the bytes in the GIFs. I altered headers (e.g. blocking cookies), and also used the Referer header to change the page (e.g. highlighting search words if the Referer was a search engine url). Seeing that I could make the web much faster, I started doing other things, like caching and DNS prefetching (long before Chrome existed). DNS lookup was really slow, in part because Netscape used a single thread implementation (if I remember right).

By 2000 I was using the proxy to implement parallel DNS lookup, chunked encoding, gzip encoding, keep-alive, request reuse. Most of these weren't yet available in browsers, but I implemented them in the proxy and presented a regular HTTP/1.0 connection to the browser. For example if the browser saw three GIFs to the same URL, it'd request that three times. The proxy would intercept these, make one request with gzip, and then feed that data to the three connections the browser made. Web surfing was so much faster with this proxy.

I continued using my client-side proxy for many years after that but over time it became less appealing and I no longer use them today.

I have my proxies written up at http://theory.stanford.edu/~amitp/proxy.html ; also see WebCleaner, a proxy based on mine https://webcleaner.sourceforge.net/

amitp··on Alt-F4 #65 – Factorio visualizer in Unreal Engine 5
There are some bits of Factorio source code on github — https://gist.github.com/Rseding91

and https://old.reddit.com/r/factorio/comments/13bsf3s/technical... is fascinating reading (things like: they used doubly linked lists, and multiple inheritance)

amitp··on Mastodon provides the highest (over 12%) engagement under posts
Agreed, having control over what you see makes a big difference. I've been using Twitter this way for several years and it's been nice ("Lists" feature and TweetDeck).
amitp··on Twenty years of blogging
It's interesting to see many people here post about their blog being 20 years old. Was that the golden age of RSS?

It turns out my blogs are also 20 years old (although my web site is older). My first posts[1][2] were not so interesting though. It took a while to figure out what I really wanted to do with the blogs. At first they were all over the place, but my work-related one ended up being a "making of" my work projects. My non-work blog ended up a mix of solutions to problems I ran across, and random ideas I wanted to share.

[1] https://simblob.blogspot.com/2003/02/simblob-2.html [2] https://amitp.blogspot.com/2003/04/playing-games-vs-programm...

amitp··on Mac Keyboard with Hidutil
It's a blog post from yesterday.
amitp··on Mac Keyboard with Hidutil
I haven't tried this yet but the configuration on https://www.digihunch.com/2022/11/key-mapping-on-external-pc... looks like it will run when the keyboard is connected.
amitp··on Mac Keyboard with Hidutil
Agreed. I do have that, but I also want to use the same keyboard with Mac, Linux, Windows. So far I've been switching keyboard configurations on the keyboard every time I use a different OS, but I'd like to move that to the OS so that it's automatic.
amitp··on Mac Keyboard with Hidutil
Thank you! That looks great.
amitp··on Communicating with Interactive Articles
I loved Distill! My own experience with interactive content (not through Distill) was that it was so much extra work that it was hard to justify, except as a passion project, so I wasn't surprised by their (permanent) hiatus.
amitp··on Will Wright on designing user interfaces to simulation games (1996)
Braitenberg vehicles are fascinating.

The doll story reminded me that there's tech out there that is expensive and hard in a way that makes engineers happy, but there could be some other much simpler tech that makes the end users happier.

Example: AT&T kept advertising about how they're working on video phones (hard tech: latency, bandwidth, cameras, screens) but all I really wanted was SMS (easy tech by comparison)

Example: Twitter is using some fancy statistical or machine learning model (hard tech) to guess that I'm interested in peru, deadpool, university of alabama. And I have to guess that it thinks that I'm interested in peru because I was reading about the guano war (I'm not particularly interested in peru in general), and that I'm intersted in deadpool because a friend of mine wanted to watch a deadpool video on my tablet (I'm not interested in deadpool myself), and that I'm interested in the university of alabama because I was reading about alabama's role in the Apollo missions (but I'm not particularly interested in the university of alabama). They're doing something hard that frustrates me, when they could've done something easy like ask me, and I would've been happier with the results.

I like that in games, we can do something simple and let the player's imagination/apophenia invent the rest. I enjoyed a recent paper[1] about Caves of Qud generating a plausible history to fit the events the player has seen so far.

[1] https://www.freeholdgames.com/papers/Generation_of_Mythic_Bi...

amitp··on Will Wright on designing user interfaces to simulation games (1996)
Wow, thank you for this!

I got to see Dollhouse in late 1996(). Having loved SimCity, SimEarth, etc., I admit I didn't "get it" when I saw Dollhouse.

I had plans this morning but I'm going to watch these videos instead :-)

() in part because of my gamedev web site, and in part because I was working on a sim game and Maxis lawyers didn't want me calling it SimAnything

amitp··on Ask HN: Those making $0/month or less on side projects – Show and tell
Thank you! I love the site. And also thank you for not having ads.
amitp··on Dijkstra Maps Visualized
It's calculating the graph distance from start node(s) to all other nodes. Although in theory it's Dijkstra's Algorithm, in practice I see people use Breadth First Search in roguelike grid worlds. The algorithm isn't limited to a grid but the visualizations look cool on a grid, which is why I use a grid in my examples [1].

Related: the gradient operation (∇ in vector calculus) on the distance field (called "dijkstra map" on that page) gives you a vector field (called "flow field" in pathfinding).

[1] https://www.redblobgames.com/pathfinding/distance-to-any/

amitp··on Ask HN: How relevant is cross-browser testing anymore?
It's around 3% of my pageviews as measured by javascript (e.g. statcounter) but it's 15-20% of my pageviews as seen in my server logs. Now, we might say that the server stats are wrong. But it could also be that the javascript stats are wrong, since firefox comes with tracker blocking. I don't know how to tell.
← PreviousPage 3 of 7Next →