# Mapmaking Discussion & Philosophy (WIP/Critique) > Software Discussion >  My own custom world generating heightmap software

## JosMetadi

For my own enjoyment, I've been writing a piece of software to procedurally generate worlds.

The features so far:
Very loosely simulates tectonic faults
Generates fractal terrain (diamond square algorithm) that combines with the faults
Generates random island/continents (fractal radius)
Loosely Simulates river erosion (still needs improvement)
Simulates climate (based on latitude, earth-type prevailing winds, altitude, humidity, and proximity to ocean)

The project is written entirely from scratch in VB6 (no plugins, libraries, etc). It hasn't been optimized at all yet, so it takes a couple of minutes to run through the whole generation process. I have been very inspired by the Shamus Young's Terrain and Project Frontier blog entries (http://www.shamusyoung.com/twentysidedtale/?cat=66)

My wishlist
3D viewing (I have no experience with 3D programming or textures)
Zooming (generating a deterministic closeup of a particular region of a world map on the fly)
Near instantaneous world generation (probably impossible)

I'd like to hear your input on how the results looks so far, on what would be the most beneficial things to add to the simulation, etc.

Thanks,
Tim

----------


## JosMetadi

Two more generated worlds

----------


## cantab

Visually they're fairly nice, if standard.

The maps won't work on a sphere, which is a problem for world maps. Since you're coding from scratch, if you can figure out how to generate your terrain on a sphere that would be an advantage. An alternative approach may to generate a continent at a time then place it on the world map reprojecting as appropriate.

I can see some arc-like artefacts in the topography.

A known issue of most random terrain generators is mountains being too central. If you can reproduce situations like the Andes where appropriate that would be great.

Regarding zooming in - I reckon if you basically use the world-scale elevation data to "seed" the fractal algorithm for generating more detailed stuff, that lets you add the detail deterministically without having to generate everything straight away.

----------


## JosMetadi

I don't know how to make it wrap onto a sphere without transitioning the whole project to 3D. Which is something I'd like to do, but will require a steep learning curve first.

The arc-like artifacts are intentional (which doesn't mean they're correct). I designed the fault lines to follow a sine curve with amplitude that varies from straight to about a half of an "S" shape. If this is wrong, what would be a more plausible shape to use?

I can definitely do offset mountains as I am calculating the slope on each side of the fault separately. Any idea on how often this feature should appear?

I'm working on improving the fractal seeding with a scaling factor and depth.

Thank you for your great comments!

----------


## eViLe_eAgLe

I could imagine using this! Maybe you should make it be able to export a wilbur MDR file?  :Wink:  Just  thought.

----------


## cantab

The first thing for making the map make sense on a sphere is to remember that for a rectangular map, the top and bottom lines are actually points (the North and South poles). Therefore, the _entire_ top and bottom edges of the map need to be either all continent or all ocean.

Faults are usually great circles on a globe. They do indeed become sine waves on the map. I think it's rather that they're not normally so "crisp" on continents.

Major transform boundaries - where one side moves sideways with respect to the other - are not too common on continents. The San Andreas is the best known; others include some around Turkey and one through New Zealand.

----------


## JosMetadi

eVile_eAgLe, I might consider it if there was really good documentation on the MDR file format. For now the project can save BMPs (and import them too, if you wanted to use it for the climate calcs and erosion simulation).

----------


## JosMetadi

Taking a break from features in order to refactor the code and data to make it object oriented. I read a bunch about map projection equations, so hopefully I'll be able to address the wrapping issue soon.

----------


## eViLe_eAgLe

I eagerly await the return of this!

----------


## waldronate

The MDR file format is a simple format that consists of a 1024-byte header followed by a raster block of 32-bit floating-point samples. Byte order of all fields and data is Intel order (LSB first). The VC++ structure definition for the file header is shown below:



```


// make sure we're aligned on 2-byte boundaries for this declaration
#pragma pack(push)
#pragma pack(2)

// map structure definitions
struct MDRHeader
{

	union
	{

		struct
		{

			char   Chunk[4];    // name of chunk - should be "WLBR"
			int    Next;        // offset in file to next data (unused)

			char   Name[256];   // name associated with the data (unused)

			double Left;        // min longitude
			double Right;       // max longitude
			double Top;         // max latitude
			double Bottom;      // min latitude

			double Min;         // lowest point on surface
			double Max;         // highest point on surface

			double XRes;        // distance between X points (right - left) / XSize
			double YRes;        // distance between Y points (top - bottom) / YSize

			int    Version;     // version number (unused, should be 0)
			int    TypeInfo;    // type information (should always be 0)
			char   SurfName[8]; // name of data block (unused)
			void** SurfData;    // pointer to surface data (unused)

			char   PicName[8];  // name of picture block (unused)
			void** PicData;     // pointer to image data (unused)

			int    XSize;       // width of blocks
			int    YSize;       // height of blocks

		}; // struct

		struct
		{
			char Padding[1024]; // make the structure 1024 bytes long
		};

	}; // union

}; // MDRHeader

#pragma pack(pop)
```

There is a problem with 32-bit MDR vs. 64-bit MDR files embodied in the pointers in the structure. There will likely be an offset from 32-bit vs 64-bit files.

----------


## JosMetadi

Ok, so I made the globe data structure object oriented, re-wrote the plate/tectonic code (I still need to tweak some of the equations), and turned it into a shape that should wrap relatively well onto a globe with a mollweide projection.
I still need to adjust the erosion calcs for the new map shape.

evile eagle, thanks for the encouragement!

waldronate, thanks, that should be enough info to write/read MDR files from my program.

----------


## Master TMO

Subscribing to this thread, as this is something I've been tempted to try my hand at as well occasionally.  I look forward to seeing what you come up with!

----------


## JosMetadi

I made the program able to display the map as a more standard plate-carree view in addition to the 2/1 oval. Here is the same globe displayed both ways.

----------


## JosMetadi

I have it exporting the heightmap in an MDR file now. I have to think about some scaling issues before I let it import MDR files too.

----------


## Erior

Hi JosMetadi (and hi to the full Guild community too, since this is my first post)  :Smile: 

your work is really interesting.
From the last images is clearly visible where the plates collisions are placed. Could you please explain a bit the algorithm you are using?
Thanks and keep up the good work!

----------


## JosMetadi

I start with a modified worley generator combined with a fractal factor applied to the radius to determine the shapes of the continents. Each continent is then given a random vector and an average height. By comparing the difference in the vectors for the two nearest continents, the fault line between them is given a type:
Convergent (they are moving towards each other), in which case the side of the continent with the lower height is assumed to be sliding underneath, and so a trench is created on that side, and a mountain range on the other side of the fault.
Divergent (they are moving away from each other), in which case it creates mountain ridges on both sides of the fault, but doesn't thrust up the base of the ranges as much.
Transform (they are moving along each other), right now I don't know have it doing anything for this type, but I obviously need to come up with some idea of how to do some offset displacements to simulate this kind of fault .(http://upload.wikimedia.org/wikipedi...ault-1.svg.png)
Other (they are moving in the same direction), in which case it doesn't do anything with the fault as there should be miminal tectonic forces.

Each fault has other random factors applying to it's height, ridge formations and offsets. The goal of these is create some of the linear mountain range and ridge shapes that you don't get out of regular fractal generators.

----------


## Master TMO

Question: When you have a Convergent fault, and it is land/sea, the sea is shoved down, making it a trench/mountain range scenario, like the Rockies and the Andes.  But when two landmasses collide, don't both get pushed upward, in a Himalaya scenario (and the Appalachians, long long ago)?  And I'm not sure what happens when two sea plates collide.

----------


## JosMetadi

You're probably right as far as realism goes. I could turn off the trenching if both continents heights are above sea level, but that sea level is likely to change later in the generation process. Right now I'm generating all the tectonics first and letting sea level be adjusted later (after the diamond square fractals have been applied) since even a small change in sea level can have significant impact on the overall appearance of the world.

Given the fluctuation of sea levels during ice ages (which are frequent on a geologic timescale), I wonder how much sea level actually drives the formation of the subduction trenches.

----------


## Erior

I have to point out that I know next to nothing at programming, so my idea here could be to difficult/impossible/ not practical to implement but i know a bit of geology/geomorphology so...
Master TMO has a point: convergent boundaries have different "effects" depending on the type of plates colliding. Do you think it's possible to implement 2 different types of surface in your model? If you consider continental crust (mainly emerged and "light") and oceanic crust (mainly submerged and "heavier", that is more dense) you could probably solve the problem. If oceanic crust collides with continental, oceanic goes down, it creates a trench and continental goes up (Andes style). If continental collides with continental, they crush and go up (Himalaya style). Two oceanic colliding is, as far as I know, not present on Earth but in that case it would be similar to continental to continental I think.
Another question: how do you implement the continental drift? By moving plates themselves on the surface or by applying a vector to the points on a plate, leaving the boundaries more or less stable?

----------


## Hai-Etlik

> Two oceanic colliding is, as far as I know, not present on Earth but in that case it would be similar to continental to continental I think.
> Another question: how do you implement the continental drift? By moving plates themselves on the surface or by applying a vector to the points on a plate, leaving the boundaries more or less stable?


Converging oceanic produces subduction and a trench as with oceanic-continental, the corresponding volcanic arc tends to form a chain of islands.  There's a lot of it in the western Pacific: Japan, the Philippines, the Marianas, the Aleutians, etc.  The first two are complicated by involving triple junctions rather than just simple faults.

----------


## Erior

> Converging oceanic produces subduction and a trench as with oceanic-continental, the corresponding volcanic arc tends to form a chain of islands.  There's a lot of it in the western Pacific: Japan, the Philippines, the Marianas, the Aleutians, etc.  The first two are complicated by involving triple junctions rather than just simple faults.


Yep, thanks for reminding me that ;-). Was too lazy/otherwise occupied to perform a real research in my brain  :Wink:

----------


## JosMetadi

Erior,

Actually, it would be easier to just have it set each plates type at the beginning and use that to calculate the collision types rather than a varying sea level. Thanks for the suggestion!

I'm not actually moving the continents right now (although the program has the data to do so). My goal is to generate very plausible worlds at a single moment in time rather than modelling the life cycle of a planet over millennia. I envision these worlds being used for games and stories by people who are enthusiastic about the gameplay or plot and characters, and want the kind of background realism that Tolkien created for Middle-Earth, but don't have years to devote to creating it.

On a global scale, I think that realism comes largely from tectonics and climate. In the zoomed in regions I hope to be able to create, I picture erosion and rivers, vegetation, and fractal randomness playing a much larger role. I've looked at a lot of purely fractal terrains and they never seem to feel completely real at larger scales without some additional underlying structure, which mostly seems to be created manually by artists.

----------


## Erior

> Erior,
> On a global scale, I think that realism comes largely from tectonics and climate. In the zoomed in regions I hope to be able to create, I picture erosion and rivers, vegetation, and fractal randomness playing a much larger role. I've looked at a lot of purely fractal terrains and they never seem to feel completely real at larger scales without some additional underlying structure, which mostly seems to be created manually by artists.


I completely agree with you on that point.
Still... it's a pity (mainly because the program can do that, as you say) that the future user must stick with a single state of the world. It would be interesting to watch at the steps and chose one fitting our needs.
That said, I'm already grateful that someone with programming skills actually works on generating a fictive world following more or less the rules of tectonics movements  :Wink: . So thanks for your work and please keep us updated!

----------


## JosMetadi

Been doing a lot of tweaking this week. Not sure how visible the changes even are.

----------


## Erior

That's nice. I think that you're getting pretty interesting shapes there. I especially like the elongated continent on the right (second image). Lots of fjord-looking spots.
Keep us updated!  :Smile:

----------


## Erior

Hi JosMetadi, are you still working on this project?
It looked (and still looks  :Wink:  )quite interesting...

----------


## JosMetadi

Still working on it, although not quite as much cause of visiting family and another work project.

I've switched the user interface to a menu system (replacing the growing number of temporary buttons), made the view window scalable (separate from the resolution of the map), and did some speed optimization (the tectonics are down from 90 seconds to around 12-15).

On paper, I'm working out how to handle continental shelves because without them, erosion seems to produce too many fjords and not enough river deltas.

----------


## waldronate

http://www.ridgenet.net/~jslayton/cshelf/index.html shows the results that a simple split exponential will give as far as continental shelves go (the program used to create the results was Wilbur, but the concept is what's important here). It's certainly not physically "accurate" in any way, but it will get a shelf at a particular altitude with pointier mountains and flatter ocean basins. The basic idea is to pick an altitude, then everything below that point get raised to a fractional power, while everything above that point gets raised to a power greater than one. Normalizing altitudes to +/-1 first helps, too. For example, if you know the max altitude, min altitude and shelf level, and use a simple exponent of 2, then the output will be ((altitude-shelflevel)/minaltitude)^(1/2) if altitude is less than shelflevel or ((altitude-shelflevel)/maxaltitude)^2 if altitude is greater than or equal to shelflevel.

This visual approximation looks best if you run a few erosion passes afterward to get some filled-out basins and incised canyons.

----------


## Naeddyr

This is excellent, excellent, excellent. Keep up the good work!

----------


## JosMetadi

Still working on this as I have time. Refining and debugging.



Waldonrate, I tried using that formula, but found it too inflexible with a varying sea level. Thanks anyway!

My next steps will be the zooming in, and turning the erosion processing into a fractal design so that it will work as the scale changes.

----------


## tg_harris

JosMetadi --

Your work so far is genius!   :Exclamation: 

Will you be releasing this software as Open Source?

----------


## JosMetadi

Thanks, harris.

I'm considering it. Ideally, I'd like to be available for use and modification free for personal use, and get paid if it's used commercially. Whatever I go with, there definitely won't be any form of DRM.

-------------------------------

Forgot to mention in the last update that I also made the program capable of displaying/saving just the heightmap, just the temperatures, just the humidity, or the combination view of all (which is what the posted pictures are). This is for people who want to use the climate data to determine which plants inhabit each area, calculate the probability of rain, or use the images as layers in photoshop to change how the climate looks.

----------


## Zard

Pretty cool. My random coastlines are generated by spilling coffee on newsprint and taking the shapes I like into Illustrator.

----------


## Dracontes

Overall loving the results so far. If you'd like a beta tester, while I'm as strapped for time as anyone else, I'd surely enjoy playing with the program. Now for a number of comments...

One thing is sorely lacking: rifts. Zones where plate vectors pull apart should have linear rises with an overall shallow dome cross-section and a somewhat clear middle valley with occasional volcanoes/islands peppered in their vicinity. Continental rifts are generally smoother than oceanic ones due to the different interaction of volcanism with air/water. The shape of oceanic rifts should influence that of the coastlines in their vicinity to a moderate extent. Continental ones originate lakes and long shallow seas.

There are actually oceanic plate collisions that don't involve subduction (see Bird, P. (2003) An updated digital model of plate boundaries, Geochemistry Geophysics Geosystems, 4(3), 1027 for examples). The thing that decides which plate plunges into the mantle is its density: usually older oceanic plate material is colder therefore denser. As such a good metric for who knuckles under is their distance from a rift which gives one a good idea of its age. When that fails they collide much like continental plates.

Otherwise I think you could take inspiration from Ron Blakey, Colorado Plateau Stratigraphy and Geology and Global and Regional Paleogeography, especially  Hypothetical Orogeny: An Illustration of Tectonic Cycles and Mountain Building.

I do hope this wasn't too overwhelming and that it helps  :Smile:

----------


## loogie

this reminds me of a (much more advanced version) program i stumbled on when i first started using the internet.. it was a program that was a fairly simple verison of a world builder... it went through the steps of world creation, volcanic activity, creation of oceans, tectonic shifting, temperatires, planlife biomes and processes... it was pay so i only ever used the demo.. but from what i remember it was amazing (this was like.. 10 years ago) but i don't remember the name and i've never seen anything like it since... It was a very simple map.. the tiles were cm sized not pixels.. but it was fairly organic feeling.. and it was amazing to watch it go through all the steps and see how stuff was created.

this has great potential. great work!

----------

