• entries
5
3
• views
2913

This journal is dedicated to my auto formation and my experimentations.

## Zone division

A friend and I are making a rogue-lite retro procedural game. As in many procedural rogue-lite games, it will have rooms to complete but also the notion of zones. The difference between a zone and a room is that a zone is open air whilst a room is not. Rooms are connected mainly by corridors while zones are mostly naturally connected / separated by rivers and mountains.

Because we want levels with zones to be generated, we need to tame the beast that is procedural generation. How can we generate each zone itself and also clearly divide them? Until now, I had only been using the Java noise library called Joise, which is the Java community port of JTippetts' Accidental Noise Library. I needed the zone data to be generated with basis function modules, i.e. Perlin noise, but in contrast I needed a more structured approach for the zone division. Joise library does have a cell noise module that is a Worley noise. It looks like this depending on its 4 parameters (1, 0, 0, 0) :

Using math modules, I was able to morph that noise into something that looks like a Voronoi diagram. Here's what a Voronoi diagram should look like (never mind the colors, the important parts are the cell edges and the cell centers) :

A more aesthetic version :

The Worley noise that I had morphed into a Voronoi-like diagram did not include the cell centers, did not include metadata about the edges and was not enough deterministic in a sense that sometimes, the edges would around 60 pixels large. I then searched for a Java Voronoi library and found this one called Voronoi-Java. With this, I was able to generate simple Voronoi diagrams :

Relaxed : 1 iteration

Relaxed : 2 iterations

The relaxation concept is actually the Lloyd's algorithm fortunately included within the library.

Now how can I make that diagram respect my level generation mechanics? Well, if we can limit an approximated number of cells within a certain resolution, that would be a good start. The biggest problem here, is that the relaxation reduces the number of cells within a restricted resolution (contrary to the global resolution) and so we need to keep that in mind.

To do that, I define a constant for the total number of sites / cells. Here's my code :

private Voronoi createVoronoiDiagram(int resolution) {
Random random = new Random();
Stream<Point> gen = Stream.generate(() -> new Point(random.nextDouble() * resolution, random.nextDouble() * resolution));
return new Voronoi(gen.limit(VORONOI_SITE_COUNT).collect(Collectors.toList())).relax().relax().relax();
}

A brief pseudo-code of the algorithm would be the following :

1. Create the Voronoi diagram
2. Find the centermost zone
3. Selects X number of zones while there are zones that respect the selection criteria
4. Draw the border map
5. Draw the smoothed border map

The selection criteria is applied for each edge that is connected only to one selected zone. Here's the selection criteria :

• Is connected to a closed zone, i.e. that all its edges form a polygon
• Does have two vertices
• Is inclusively in the resolution's boundaries

Here's the result of a drawn border map!

In this graph, I have a restricted number of cells that follow multiple criteria and I know each edge and each cell center point.

To draw the smoothed border map, the following actions must be taken : emit colors from already drawn pixels and then apply a gaussian blur. Personally, I use the JH Labs Java Image Filters library for the gaussian blur.

With color emission only :

With color emission and a gaussian blur :

You may ask yourself why have we created a smoothed border map? There's a simple reason for this, which is that we want the borders to be gradual instead of abrupt. Let's say we want rivers or streams between zones. This gradual border will allow us to progressively increase the depth of the river and making it look more natural in contrast with the adjacent zones.

All that's left is to flood each selected cell and apply that to a zone map.

## Marching cubes

I have had difficulties recently with the Marching Cubes algorithm, mainly because the principal source of information on the subject was kinda vague and incomplete to me. I need a lot of precision to understand something complicated  Anyhow, after a lot of struggles, I have been able to code in Java a less hardcoded program than the given source because who doesn't like the cuteness of Java compared to the mean looking C++?

Oh and by hardcoding, I mean something like this :

cubeindex = 0;
if (grid.val[0] < isolevel) cubeindex |= 1;
if (grid.val[1] < isolevel) cubeindex |= 2;
if (grid.val[2] < isolevel) cubeindex |= 4;
if (grid.val[3] < isolevel) cubeindex |= 8;
if (grid.val[4] < isolevel) cubeindex |= 16;
if (grid.val[5] < isolevel) cubeindex |= 32;
if (grid.val[6] < isolevel) cubeindex |= 64;
if (grid.val[7] < isolevel) cubeindex |= 128;

By no mean I am saying that my code is better or more performant. It's actually ugly. However, I absolutely loathe hardcoding.

Here's the result with a scalar field generated using the coherent noise library joise :

## Low poly terrain

Recently I've been tackling with more organic low poly terrains. The default way of creating indices for a 3D geometry is the following (credits) :

A way to create simple differences that makes the geometry slightly more complicated and thus more organic is to vertically swap the indices of each adjacent quad. In other words, each adjacent quad to a centered quad is its vertical mirror.

Finally, by not sharing the vertices and hence by creating two triangles per quad, this is the result with a coherent noise generator (joise) :

## Voxels

Voxels! Unlike my old Xna application, this one's code is way more beautiful to the eye. Zero "switch" or "if and else" for cube faces, as I did with my cubic planet faces.

My only problem with voxels is that it's a 3D grid. A 3D grid take a lot longer to compute than six 2D grids.
250 * 6 = 1500 quads to compute and draw.
2503 = 15,625,000 voxels to compute and maybe draw.

As I use more and more complex objects to abstract the computation and the drawing part, the code slows.

Following this entry, I'll make another one but with two videos:
1) Spherical planet made of voxels
2) Cubic planet made of voxels

## Grouping of my [new] work so far

I'm an amateur and hobbyist video game developer. I've been programming for 9 years now even though I'm almost 21. When I started, it was rough being extremely bad with the english language and a noob programmer. Instead of helping me, people over multiple forums were only degrading my lack of skills and so I stopped being an active user. I have now finished what we call in Quebec a "technique". A technique is an academic degree of 3 years that is the equivalent of college degree. The technique I've done was called "Technique de l'informatique de gestion", which is a computer science technique applied to management softwares. As I finished college, I noticed I've improved my programming competencies and so I started again to research and program for fun, which I did 4 years ago. See

I'm currently working on planet generation. Everything was done using the jMonkey Engine 3, Java 8, Eclipse Mars and Joise (a java adaptation of the accidental noise library from JTippetts). The following videos sum up what I've done so far: