Procedural terrain generation in cylindrical (2D) world

I'm fairly new to procedural terrain generation. I know that to generate terrain you would use different calculations with the x and y axis (also z if you have one).

But what if you want to generated random terrain on a 2D world that loops around itself? By that I mean a world in which you enter the right side upon leaving the left side (or the other way around). It should also be generated on the fly and not all at once.

One solution I can think of is to just generate ocean along the border, but that is not what I'm looking for. I also seem to remember that Civilization generated such types of worlds, but I'm not quite sure how that worked, it's been quite some time since I played that game.

So how exactly can one generate such a continuous world?

• Here: jgallant.com/… – jgallant Aug 31 '16 at 13:47
• @Jon: Seems like that is what I wanted. I t would be great if you could explain the relevant pieces in an answer. – Matthias Schreiber Sep 1 '16 at 6:26

As mentioned in the comment, I figured what you required was wrappable noise. With wrappable noise, you can generate seamless textures and game worlds. You are probably familiar with generating 2D noise already.

What you need to do is sample 3 dimensional noise instead. Instead of sampling a rectangular shaped noise pattern, you are going to sample a cylindrical shaped pattern in 3D space.

The image above is what we will be doing. The idea is that you can cut this cylinder lengthwise at any point, and unroll it, and then use this as your map data. This will effectively wrap your noise around on 1 axis.

In order to do this, sample your noise data like so:

for (var x = 0; x < Width; x++) {
for (var y = 0; y < Height; y++) {

// Sample noise at smaller intervals
float s = x / (float)Width;
float t = y / (float)Height;

// Calculate our 3D coordinates
float nx = Mathf.Cos (s * 2 * Mathf.PI) / (2 * Mathf.PI);
float ny = Mathf.Sin (s * 2 * Mathf.PI) / (2 * Mathf.PI);
float nz = t;

// sample noise at coordinate
float heightValue = (float)HeightMap.Get (nx, ny, nz);

// save noise value to a noise map
mapData.Data [x, y] = heightValue;
}
}


If you convert this map data into a texture it would wrap on the x-axis and would look something like: