I REMEMBER THIS! Oh man, I haven't read this in forever. It was one of the blog posts that kicked off what became Iron Arachne, my own procgen project.
Thank you for writing it! I'm going to re-read this.
I think pass two is intended to introduce additional regions of concavity (mostly by replacing straight lines), which in effect introduces a bunch of inflection points, helping creating the organic "spiny" feel, as opposed a "bubbly" feel.
Nothing in the description refers to individual neighbouring cells. All those numbers are counts -- if 0 to 2 of the neighbouring cells are rock, do this, etc.
You're talking about the post, or something in the source code?
In the post, it just counts how many of the 8 tiles are floor (which means 9 possibilities, including none of them). They aren't assigned index numbers.
Edit: ha, we all jumped on you. So now this is explained three different ways.
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy.
Cool, the interactive visualisation is a great way to explain it.
Maybe a similar-ish idea could be done in a continuous 2d space, without a grid, using 2D computational geometry operations (e.g. GEOS's [1] buffer operation to grow shapes by a given radius & so on).
Each component is a point-set -- a subset of points in the 2d space we're working in.
1. sample a bunch of seed points from some distribution. these define initial connected components
2a. grow each component by radius r. union any components that touch.
2b. shrink each component by radius r + delta. delete components that contain no points
3. delete any components that are 'too small': shrink each component by r_min, delete any components that now contain no points, then grow each surviving component by r_min again
4. link the surviving connected components somehow:
4a. identify pairs of components that are adjacent (e.g. compute voronoi 'triangulation' using components as seeds instead of points, if two resulting triangles border then their components are neighbours)
4b. propose candidate corridors linking the nearest points between each pair of adjacent components
4c. find a minimal/interesting spanning tree on component-corridoor graph using corridor lengths as edge weights
4d. carve selected corridors by growing each coridoor line by some radius
4e. everything should be some big connected component
5. sanity check that we got something playable (maybe based on area). if it's too small/uninteresting, reject & try again from step 1
I'm not sure of an efficient/reasonable way to do step 4a in the plane - it'd be simple & efficient to do this on a graph (Voronoi-triangulating a graph has similar computational cost to finding all shortest paths from some source).
Nethack's cellular automata gnomish mine algorithm on a small grid is of course going to be massively faster than stuffing about with masses of GEOS Buffer & Union calls, but it's fun to think through how much of this extends.
I love NetHack dearly, but I am waiting with great anticipation for a roguelike whose procedural level generation is AI-driven. Imagine NetHack where every level is like the hand-built special levels! I know it's coming.
20 comments
[ 4.4 ms ] story [ 29.9 ms ] threadhttps://journal.stuffwithstuff.com/2014/12/21/rooms-and-maze...
Thank you for writing it! I'm going to re-read this.
https://tnnt.org/
A diagram would help
In the post, it just counts how many of the 8 tiles are floor (which means 9 possibilities, including none of them). They aren't assigned index numbers.
Edit: ha, we all jumped on you. So now this is explained three different ways.
https://www.roguebasin.com/index.php/Cellular_Automata_Metho...
Maybe a similar-ish idea could be done in a continuous 2d space, without a grid, using 2D computational geometry operations (e.g. GEOS's [1] buffer operation to grow shapes by a given radius & so on).
Each component is a point-set -- a subset of points in the 2d space we're working in.
I'm not sure of an efficient/reasonable way to do step 4a in the plane - it'd be simple & efficient to do this on a graph (Voronoi-triangulating a graph has similar computational cost to finding all shortest paths from some source).Nethack's cellular automata gnomish mine algorithm on a small grid is of course going to be massively faster than stuffing about with masses of GEOS Buffer & Union calls, but it's fun to think through how much of this extends.
[1] https://libgeos.org/