[1] https://www.redblobgames.com/articles/probability/damage-rol...
934 karma · joined January 14, 2012
twitter:@redblobgames
[1] https://www.redblobgames.com/articles/probability/damage-rol...
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.
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.
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.
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.
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...
I am collecting some of the design elements here: https://www.redblobgames.com/making-of/little-things/
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.
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...
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
[1] https://old.reddit.com/r/roguelikedev/comments/dc4orn/identi...
[2] https://www.redblobgames.com/pathfinding/distance-to-any/
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/
and https://old.reddit.com/r/factorio/comments/13bsf3s/technical... is fascinating reading (things like: they used doubly linked lists, and multiple inheritance)
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...
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...
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
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/