3

A peek at cellular automata (2/2)

 2 years ago
source link: https://medium.com/nerd-for-tech/a-peek-at-cellular-automata-2-2-5abbcc461aa7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

A peek at cellular automata (2/2)

How to use a cellular automaton the make a RPG map generator

Yesterday, I talked about cellular automata, and more precisely Conway’s Game Of Life. To continue on this topic, I searched for small applications we can derive from the concept of cellular automaton and I eventually settled for one: a RPG-like top-view map generator.

1*2XdjNe6RrIfRtvavzxJO3Q.png?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7

As we saw previously, the idea behind cellular automata is to discretize space and time to model dynamic systems more easily. For this map generator, I decided to only focus on the space-discretization part.

My goal was to make a simple tool to create basic maps. Nothing fancy, just RPG-like top-view area-based maps with a few types of grounds (grass, forest, water…). For example, those maps could be used as a support for a role-playing session where you want the players to travel from city to city, and you present them with an image to help them understand what your fictional land looks like.

I looked at a few tutorials more dedicated to Dungeon or Cave Levels generation (like these three ones), but I adapted the ideas to create top-view maps like this one:

0*jKvF8esHERXziMpq.png?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7

Just like last time, the Python implementation of this project is available for free, right here.

An overview of the map generator

If we think in the cellular automaton paradigm, we can say that our map is a static automaton (we won’t iterate over time) cut in width * height cells (herein after referred to as “tiles”). Each tile is surrounded by neighbors; they are all alive but can be in various states, called “tile types”. This “type” is represented by a specific color.

0*uPmu9PPjcGe4JR60.png?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7

The maps are generated randomly but processed through a predefined set of steps:

  • random initialization: each tile is randomly assigned a type from the types list
  • smoothing (one or multiple passes): by counting the number of neighbors around each cell and applying smoothing rules, we gradually eliminate the noisiness and make for more “averaged” regions
  • “earthification”: it is a kind of “super-smoothing” that brutally spreads water into large pools and turns too-little ponds into ground, so there is less small water formations scattered across the map
  • clean-up: a final pass eliminates strange patterns

Note: the “size” of the smoothing (see below, in the Specific generation parameters section, for more detail) sets how many neighbor tiles should be considered. If the size is 1, the tile’s neighbors are the 8 tiles directly around it; then is size is 2, the tile’s neighbors are the 24 tiles around it; and so on…

To understand the process better, take a look at the following animation that shows the different steps:

0*1_-xkuoh-qyAc96N.gif?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7

The secret behind the various smoothing phases is to draw from the basics of cellular automata and to use the states of the neighbor tiles to determine your own.

Imagine you have a ‘plain’ tile that was randomly placed in the middle of eight ‘water’ tiles. It is a tiny dot lost in an ocean: best to transform it into another ‘water’ tile so you have a clean pond. This is one smoothing rule, but of course you can implement many and have them all fight each other over the generation of your map!

I dive into creating your own tile types a bit later in this article, but if you just want a quick feel of the default rules of the map generator, here is a schematic outline (transformation is applied if the percentage of neighbor tiles of the same type as the current one matches the given condition):

0*r__UXMKx_pJ4du50.png?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7

More details about map properties

In order for the generator to work, the maps are assumed to have the following properties:

  • a width and a height (the number of cells in a grid row and a grid column)
  • a set of tile types
  • optionally, specific generation parameters (see below for more details)

Defining tile types

I mentioned before our tiles can have one of several types. A type is defined by a tuple like this:

Smoothing transformations are of two types. We define single-test or double-test transformations when examining a tile T:

  • for single tests, we only look at one threshold X: if less than X% of neighbor tiles are of the same type as T, transformation is activated and T is changed
  • for double tests, there are 2 thresholds X and Y: if less than X% of neighbor tiles are of the same type as T, transformation is activated and T is changed; else if more than Y% of neighbor tiles are of the same type as T, transformation is activated and T’s neighbors are changed

For example, in the default transformations shown above, the ‘plain’ tile has a single-test transformation and the ‘mountain’ tile has a double-test transformation.

The map then has a list of tile types with a given probability of each appearing during the random initialization:

An important point is that the last tile type in the list is regarded as the ‘fluid’ type, i.e. water, lava, plasma or anything that is not ground. This has consequences during the “earthification” phase I mentioned above.

To give you an idea of how to set your own map tiles, here are some code examples:

The zone types (water, forest, rock, etc.) are just determined by color and therefore rely on the usual standard association we make on maps between a color and a type of ground.

These parameters give these kinds of maps (each matches the tile type in order):

0*yr3M4nwuO-S6uyo6.gif?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7
A map generated using usual RPG-like zone settings
0*7h9Ed6B_vJBQqhmu.gif?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7
A map generated with no forest, rocks and less water than the previous one
0*CFQ5pTKPjDKmXhx6.gif?q=20
a-peek-at-cellular-automata-2-2-5abbcc461aa7
A map generated with lava-and-rock terrain settings

As you can see, tweaking just a bit the parameters can already result in drastic changes — so if you’re playing around with the tool, don’t hesitate to test your modifications often! ;)

Specific generation parameters

When you launch a map generation process, you can also provide optional parameters to define the number of earthification and clean-up steps and to set the smoothing characteristics:

  1. smooth_size:
  • if it’s an integer, you can also set a smooth_amount option to specify how many times “smoothing” will be applied (all with the same size)
  • if it’s a list of integer, each one defines a “smoothing” step with given size

2. earthifications: the number of times “earthification” that will be applied (default: 2)

3. clean_up: the number of times “clean-up” that will be applied (default: 1)

Exporting your results

The basic map generator configuration will simply display the generated map at the end of the process. If you want, you can save the result to a PNG, JPEG (or JPG) file by adding the export_file option; you can also see (and optionally export) the complete generation process steps by using the with_animation parameter:

Warning: the GIF generation is done by stacking frames one after the other all throughout computation, and it eventually uses the imagemagick writer for the output — so make sure you have ImageMagick installed!

What now?

Of course, this map generator is quite basic and we can think of a lot of improvements (both in features and ease of use). In particular, generating maps that aren’t completely flat would be a lot cooler!

But remember this is just one (simple!) idea to generate maps: there are many other ways of creating much more realistic content. For example, Voronoi cells may give a more “organic” and “natural” result, like shown in this great article, by Amit Patel. Patel even has a nice HTML demo over here.

All in all, that is yet another example of procedural generation that shows how randomness and a set of predefined rules can result in endless creativity… or completely crazy stuff! ;)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK