We're got two things to highlight today that will interest anyone who's worked on or thought about build a "generator" in your next game or project (cough... No Man's Sky... cough)
The first is an great essay from Kate Compton.
So you want to build a generator…
This is a beginner-level advice essay for people just getting started with building generators. It’s also for practiced experts who want a way to organize their knowledge. The advice is meant for any kind of generators: humorous twitterbots, fanciful art-making bots, level generators, planet builders, makers of music, architecture, poetry, and cocktails. (edit: it turned out to be 4000 words long, so enjoy the ride!)
With so many possible kinds of generators, what advice can I give? Any advice will depend on what kind of generator you want to build. I’ll give you a list of questions to ask yourself, and advice to match the possible answers.
The first question is: What are you making?
Write down the thing that your generator will make. We’ll refer to this as your “artifact” but it could be anything: procedural birds, generated stories, animated dance choreography, gazpacho recipes, RPG quests, chess variants.
Now the hard part. Inhale, exhale, and start writing down everything you know about what makes one of those successful. What qualities does a good one of those artifacts have? “Funny”, “Harmonic”, “Playable”? Now go deeper: the more specific the kind of thing you are making, the more specific and detailed you can get with these requirements. What does a “fun” level mean? “Fun” will mean very different things for Super Mario or Civilization or Bejeweled. I can come up with more properties of a good paranormal regency romance novel than I can come up with rules for a good novel. The easiest generators to make are the ones where you can describe “good” artifacts as sets concrete properties.
...
Now we have the guidance we need to start building methods that make artifacts.
...
Building Your Artist-in-a-Box
When the Spore editors were being designed, the engineers, designers worked closely with the art team to understand how an artist or an animator would go about sculpting and texturing a creature. If they could understand the process and design an algorithm that could follow that process on demand, they would have an “Artist-in-a-box” that could make procedurally generated creatures that would be nearly as good as the original animator would have made. Designer Chaim Gingold explained this process in his 2007 GDC talk audio slides and Art Director Ocean Quigley used a similar process to experiment with what kinds of building blocks he would want for building cities
...
From rules to generative methods
...
After you generate…
You’ve browsed this list of generative methods, you’ve got your list of constraints and properties in hand, and you’ve built your generator!
Now what?
Ways that generators fail
...
Conclusions:
Oh, my, this turned into a monster of a blog post. It’s probably full of errors and omissions, but I hope it will be of use to you.
The next project is from Martin O'Leary. The cool part of this is that the page is interactive and lets you play with creating your own maps.
Generating fantasy maps
These are some notes on how I generate the maps for my Twitter bot @unchartedatlas, which is based on a generator I originally produced during NaNoGenMo 2015. There's JavaScript code for the generator on Github here, and the original messy Python generator code can be seen here.
You may also be interested in this companion piece, which describes the placename generation.
Inspiration
I wanted to make maps that look like something you'd find at the back of one of the cheap paperback fantasy novels of my youth. I always had a fascination with these imagined worlds, which were often much more interesting than whatever luke-warm sub-Tolkien tale they were attached to.
At the same time, I wanted to play with terrain generation with a physical basis. There are loads of articles on the internet which describe terrain generation, and they almost all use some variation on a fractal noise approach, either directly (by adding layers of noise functions), or indirectly (e.g. through midpoint displacement). These methods produce lots of fine detail, but the large-scale structure always looks a bit off. Features are attached in random ways, with no thought to the processes which form landscapes. I wanted to try something a little bit different.
There are a few different stages to the generator. First we build up a height-map of the terrain, and do things like routing water flow over the surface. Then we can render the 'physical' portion of the map. Finally we can place cities and 'regions' on the map, and place their labels.
Grids
To represent the heightmap, first we need a grid of points. Although it can be simpler to work on a regular square grid, I much prefer to work on an irregular set of points for something like this. With a regular grid, it's very easy to run into weird artifacts, and you often have to do a lot of postprocessing to hide the effects of the grid. If you use an irregular grid, then there are a few things which are more complicated, but the structure of the grid helps to give the map a rough, organic feel, and you never have to worry about nasty linear artifacts in the finished product.
...
Rough outlines
One of the difficulties of creating landscapes in a realistic way is that real landscapes aren't created all at once. Instead, they evolve from earlier landscapes, which in turn evolved from even earlier landscapes, and so on back for billions of years. There's no good way to simulate this process in a reasonable amount of time, so we need to cheat slightly.
...
Erosion
The results of this process can be a little bit on the blobby side, which means they rarely look good on their own. We want to scuff them up a bit, so they look more like real landscapes. We do this by applying an erosion operation.
...
Rendering terrain
Now comes the question of drawing the map (at least the physical portion). The easy part is the coastline - we've been doing this already. It's just a matter of drawing line segments where the heightmap crosses zero. There's not a lot extra to do about this.
...
Cities, borders
Now that we have the 'physical' portion of the map sorted, we can move to looking at the 'political'. We want to place cities and towns on the map in feasible-looking locations. At the same time, we want the cities to be spread out enough that we can put labels on them without worrying too much about overlap.
To place a city, I generate a score for each point, which is a combination of three things:
- Water flux - we want cities to be preferentially located on rivers, so high water flux gets a bonus
- Distance from other cities - we want cities to be spread out, so penalize locations which are too close to an existing city
- Distance from the edge of the map - the other two criteria alone tend to push cities to the map edge, which isn't ideal, so penalize locations too close to the edge
...
Placing labels
At this point we can start naming things, using the process described in these notes. I generate names for cities, towns and regions, using a consistent language for the whole map.
...
So that's the algorithm, at least in rough outline. The actual code running on the bot has a few other little bits and pieces, which honestly don't do much, but removing them is more trouble than it's worth when the code is working as it stands. The JavaScript code behind this page is available on GitHub, and if you're really really brave you can look at the original Python code which was written while I was figuring all this out.
There's obviously lots that could be done to improve this. Erosion is just one process, and the next obvious thing to add would be fluvial deposition, which would allow for flood plains, river deltas, etc to form. If you wanted more realistic mountains, then glacial processes would be worth looking at. Volcanic stuff could also be fun.
On the graphical side, it could be fun to try to sketch more interesting textures on the map, such as forests or fields. Or you could fill the oceans with sea monsters and lost ships. If you're really brave, you could even look at labelling more features, like mountain ranges and rivers.
As always, if you do any of these things, or make anything else interesting with this code or these ideas, please get in touch and let me know.
That's a good bit of reading that should keep you busy for a bit and help jumpstart your next generation project...
Follow @CH9
Follow @coding4fun
Follow @gduncan411
