Sunday, March 20, 2022

Impasse and need for help!

More bug squashing! This included three entirely distinct lake-related bugs that all coincided in a single regional map. I really hate lakes. I've also made a few more refinements along the way that are too minor to detail.

A couple of recent screenshots:

Anyway, what this means is that I've pretty much finished this stage of Undiscovered Worlds. As I said a million years ago, I envisaged a long-term project in three stages:

  1. terrain generation
  2. flora and fauna generation
  3. civilisation generation

I don't know whether I'll ever get to (3) - and really it's the one that interests me the least right now, especially as so many other people have done it so well - but I do think that (1) is pretty much done now. It's certainly not perfect but it's as good as I can plausibly get it, at least in the foreseeable future.

So I'd like to release this now. I'm planning on putting the source code up on GitHub so that anyone can tinker with it and make it better. I'd also like to make executable versions available so that less technically minded people can use it too. However, there are a couple of problems with this:

  1. The project uses several external libraries: NanoGUISFML, and stb_image. Somehow I've installed these in some eccentric way that allows my code to work fine on my computer, but I can't build an executable that will run anywhere else, because it won't incorporate at least some of these libraries. The fact that I can't manage what ought to be a fairly elementary part of development should indicate my skill level at this sort of thing.
  2. This project is written in C++ using Xcode on a Mac. Even if I manage to solve problem 1, I'll only be able to create an app that runs on Mac. It would be nice to be able to make it for Windows and Linux too, but I don't know how to do that.
So I need some help! - from either somebody who can walk me through solving these problems, or, perhaps more plausibly, somebody who can build the executables themselves if I make the source code available. Is there anyone who might be willing to help?

[EDIT] I've put the source code on GitHub - you can see it in all its ghastly glory here.

Sunday, January 30, 2022

Small update

I've been doing a fair bit of unglamorous bug squashing and general tinkering. Much of this is behind-the-scenes stuff that just makes the code work a bit better and hopefully crash less often, but there are also some visible effects, mostly at regional level:

  • Some river-related bugs have been removed. Plenty remain, naturally.
  • I made some additional tweaks to the climate simulation, to reduce the amount of desert slightly.
  • A long time ago I implemented canyons, which work by creating wide areas of the map where the land is raised up higher than usual around the river valleys. Somehow the effect of these was much reduced when I ported the project over to its current form. I've now made it much stronger and more noticeable.
  • In addition, some of the smoothing routines applied to the regional terrain tended to widen canyons in an unpredictable way which made them look weird. I've stopped that, so now river valleys really look like river valleys.
  • I worked out why - as noted in the previous post - some coastlines had acquired extravagant islands (it was to do with changes to how the sea bed is generated), and toned it down so it only happens sometimes.
  • I also removed a tendency to create lakes right by coastlines, noticeable in (among others) the last image here.
Here are some pictures, in which you can see the river valleys more clearly in some areas, as well as varied coastlines. I think the texture of the land is looking pretty nice now:

And as a bonus, here's an epic river system:

Tuesday, January 4, 2022

Grids revisited

A while ago I posted about a problem with grid-like artefacts cropping up. These are an unavoidable side-effect of relying so heavily on the diamond-square algorithm for generating detail on the regional map: that algorithm is known for a tendency to look a bit grid-like.

Back then I came up with a rather elaborate solution for this problem which involve blending the terrain with a warped fractal. However, while this did eliminate the artefacts, I found that it tended to flatten the terrain too much and remove much of its texture, so I turned it off. That still leaves the artefacts problem.

Here's an uncommonly severe example:

While it doesn't usually look quite this bad, even occasional examples as horrible as this are unacceptable. I've found that this problem usually occurs in coastal areas where there are lots of rivers and a few ranges of hills or low mountains, so this is a typical sort of map to have this problem.

It occurred to me that rather than messing about with adding interference to the terrain to try to mask the grids, there could be a much simpler method. For each tile, I take a random point on each side. I then mark out a circle (with a radius equal to the width of a tile) centred on each point. Then I simply rotate that circle by a random amount. The rotated circle is progressively blended into the original (the closer to the centre it is, the more strongly it's the rotated version; the closer to the edge, the more strongly it's the original). And that's pretty much it. This is done after the basic land elevation is generated, but before the hills and mountains are added, so they aren't affected. Also, for obvious reasons we don't alter any points that are on - or bordering - rivers or lakes, or sea.

Much to my surprise, this not only worked exactly as planned the very first time I tried it but yields what I think are really nice textures for the maps. Here's what the area above looks like with this technique in place:

This is clearly a big improvement - the grid-like features of the original are almost entirely obliterated, but without making the terrain flatter and less interesting. Instead, the texture is more finely grained, while still keeping the general areas of high and low ground in place. (And don't ask me where all those islands have come from - I must have made some other change that caused those, but I can't think what.)

Here are a couple more maps to show off this general look:

As you can see, the new effect is most noticeable in the green areas with high rainfall and more rivers, but it shades nicely into the more arid regions and mountainous areas which are both sometimes associated with the more terraced look you can see in the last two images (and which is applied after the rotation effect). So we've got a bit of variety in the appearance of our maps, which is always good.

Sunday, December 26, 2021


In his very influential post on map generation, Martin O'Leary commented that one thing he'd like to see done was volcanoes. So I've added volcanoes.

There are lots of different kinds of volcanoes, but for our purposes we'll just distinguish between shield volcanoes - which are broad with shallow slopes (such as those on the islands of Hawaii) - and stratovolcanoes - which are tall with steep slopes (such as Vesuvius). Most volcanoes are stratovolcanoes.

We can also distinguish between volcanoes that occur at boundaries between tectonic plates - more specifically, where oceanic plates are pulling away from each other (e.g. the Mid-Atlantic Ridge), and where oceanic plates are subducting underneath continental plates (e.g. the Andes) - and hotspot volcanoes, which are much rarer and occur just about anywhere.

It's easy to add volcanoes in mountain ranges that are drawn along the edges of continents. They don't stand out, because they're part of mountain ranges, but they're there. Hotspot volcanoes take a little extra work. For one thing, hotspot volcanoes often have extinct volcanoes nearby, because of the movement of the tectonic plate over the hotspot beneath. So UW creates those too. There isn't any functional difference between an active volcano and an extinct one other than that if you click on the crater of an active volcano it will tell you it's a volcano.

Stratovolcanoes appear as isolated peaks, with perhaps a subsidiary peak or two with their own craters. Here's a line of them - the one to the southeast is active, while the others are extinct volcanoes formed by the same hotspot in earlier ages:

They look pretty small on the regional map, as you can see, but bear in mind that this map is at a scale of one pixel per kilometre. Compare the scale and general shape of Vesuvius, and I think these are about right:

Shield volcanoes, meanwhile, are done by raising the land round about to create a wide, gradual slope, surmounted by a relatively low peak with a system of nice buttresses around it. These are much rarer than stratovolcanoes but can be quite impressive features when they do appear:

And here is a chain of shield volcanoes. The one furthest to the east is the active one, and the others are extinct. I like how lakes have unexpectedly formed on the slopes of this volcanic range (the active crater is just to the east of that lake in the centre of the last volcano):

(I know it looks like that river is going over the flank of the volcano to the west - it isn't really, it's running through a canyon between the volcano and the hills just to the west.)

Submarine volcanoes are also important, and we create them in a similar way to stratovolcanoes on land, with solitary peaks rising from the seabed. Again, the ones around the oceanic ridges mostly blend into those ridges, but the ones in other areas are more noticeable, especially if they have chains of extinct seamounts associated with them. Hotspot volcanoes are more common in the oceans than on land - unsurprisingly as oceanic crust is thinner than continental - and they tend to clump in particular areas, so UW models that too. Sometimes these rise above sea level and create volcanic islands:

Here's a close-up shot of some islands I liked - the large island has a stratovolcano in the middle, with three active craters. The whole island is covered in tropical rainforest. Clearly a good place to bury some pirate gold.

And of course the import feature now lets you import volcano maps, so you can add them to your custom worlds. This means that Mount Doom and the Lonely Mountain can be added properly to Middle Earth, which is clearly a major step forward.

Gondor came out a bit nicer this time too!

Tuesday, November 23, 2021

Tinkering and tweaking

I've been doing some unglamorous tinkering with the app, mostly to do with trying to make the regional relief maps prettier. In addition to bug-squashing, I've added the following refinements:

  • The roughness levels of most terrain have been raised, sometimes fairly drastically. I think the rougher terrain simply looks better, as the texture of the ground appears much more interesting (I'm not sure how realistic it actually is, but still, I like the look). But of course smoother terrain still occurs as well, as we want variety above all.
  • I've made seabeds smoother, which makes for a much nicer appearance with fewer undesirable artefacts. (Deep sea trenches look especially ominous now.)
  • Polar coastlines had a tendency to be very straight and dull-looking, for some reason which I've been unable to track down. I've bodged the issue by simply creating new routines to make them more fragmented and interesting. (This is quite apart from the much more crinkly fjords, of course, which appear where mountain ranges meet the coasts in colder areas.)
  • In areas where land is removed by applying a fractal, there's now a (small) chance of small islands being scattered over the area. The islands are made by building short mountain ranges, or isolated peaks (like extinct volcanos), in the water. This makes for a nice Aegean sort of appearance, with archipelagos of small mountainous islands, which adds more variety to the global maps.
  • Previously, the transition between arctic and subarctic areas was drawn gradually in the relief maps, with a smooth shift from tundra colours to white. I've added two new ways of showing this transition - one with a sharp change from tundra colours to white, and one with a speckled intermediate zone. The sharp change is the new default, as I think it looks best, but the others can be chosen in the visual settings menu.
Here are some sample images.

Rougher terrain:


Polar coastlines:

Small, mountainous islands:

Snow transition zones:

More tinkering and checking to come, then I will hopefully be in a position to release something.

Tuesday, October 5, 2021

We have but slept for five million years

 I've made a few small tweaks to the program to improve the appearance of regional maps:

(1) Low mountains and hills are more likely to use wider peaks, giving them a more rounded and gentle appearance compared to higher ridges and peaks.

(2) Transform faults in mid-ocean ridges have been turned off, at least for now - they look too messy most of the time.

(3) Shading on ocean seabeds has been reduced for small differences in elevation, to avoid the kind of artifacts seen in the second map here.

(4) Semi-arid areas are depicted as slightly greener.

The main addition, though, is one I was considering for a while: custom worlds. It is now possible to import your own maps into Undiscovered Worlds and have it calculate the climates, rivers, and so on. You can then explore it, and export maps, just as if it were a world generated from scratch.

Here's what the new import screen looks like:

You can import three kinds of maps. Each needs to be a png image file the size of the global map. A land map is a heightmap for the land and a sea map is a depthmap for the sea (only needed if you want to specify sea depths - you don't have to import one), which are both pretty self-explanatory. The mountains map is needed because of how the program handles mountains: they are not simply high areas on the global map, but store ridge direction information as well. Luckily I managed to make it fairly simple to do. The user need only create another global-scale image with lines indicating the heights of the central ridges of the main mountain ranges. UW then draws more complicated ranges running along and around these, including working out how the ridges intersect.

So, for example, if the user draws a single line on their mountains image and imports it into UW, it creates mountains that look like this at the regional scale:

And I think these look reasonable.

As you can see, the import screen also allows you to generate various features on your map once you've imported the heightmaps. You can remove straight coastlines, generate continental shelves and mid-ocean ridges, add random variation to both sea beds and the land if desired (this means that you could import just flat heightmaps for the land or sea and have UW create variation in elevation, if you don't want to do it yourself). Finally, you can add smaller mountain ranges, hills, and also island chains, all randomly placed.

When you press the big button at the bottom, UW does a few additional processes such as removing depressions and adding gentle slopes to the land, and then calculates all the climates, as well as the river courses, lakes, and so on. Once that's done the world is finished and you can explore it at the regional level, and of course export maps with your preferred colour schemes, to do with as you will.

With luck, this should provide enough control for hopeful Slartibartfasts to sketch out the outlines of a world in whatever paint program they like, and then have UW fill in all the details.

I thought I'd test it out myself. I adapted this map of the Third Age of Arda to import into Undiscovered Worlds. I only did basic land outlines, and mountain ridges - the scale probably isn't quite right but I tried to get it as close as possible. I had to pretty much guess the heights of the mountains. Importing these two sets of data into UW, I added random elevation, and also random hills scattered about, so it won't exactly match Tolkien's physical terrain (to the extent that he ever specifies it precisely at all). Also, I cheated a bit by making the two large salt lakes in Tolkien's map into patches of actual sea, to ensure they appeared in the right locations.

I tried running this through UW a number of times and found that the results could vary quite a lot, depending on how the winds were generated (it's pretty random), as well as depending on where random hills get plonked down, plus all kinds of other small differences that can translate into quite significant variation. In some versions, Gondor was a huge desert. In some, the River Anduin swerved west and flowed out through the Gap of Rohan.

Here's a version that seemed to me quite pleasant-looking:

Obviously the only bit we really care about is the northwestern part of Middle Earth, so this is what that area looks like:

Here are the climates of that same region (using this colour scheme):

Some of the differences here, compared to Tolkien's maps, are purely physical. The Misty Mountains don't represent such an unbroken barrier as they should - Frodo and company could have found their way through any number of accommodating passes on this version of the map. The same applies to the Ash Mountains, to the north of Mordor. This is a result of how the program translates simple lines in the imported mountains image into tolerably believable mountain ranges - it has to mess about with them to some extent, and I can't remove that without making them look generally worse.

In addition, of course, there are various ranges of hills that aren't on the original maps, which I had UW add randomly. You need a good scattering of these to give the terrain a bit of texture, but it might mean that the watercourses aren't quite as you'd expect.

Instead of one major river running south, to the east of and parallel to the Misty Mountains, we have a number of rivers heading more or less due east. More significant rivers are found to the west, where you'd expect more rainfall - and indeed, to the west of the mountains UW places humid continental climates, giving way to temperate oceanic closer to the coast. The Shire straddles these two climatic zones, which also makes more sense than having it all temperate oceanic (as I assume it is for Tolkien, as it's meant to resemble England). It is, after all, further inland than England is in real life.

Gondor turns out to be quite arid again, but the main surprise here for me is Mordor, which looks a lot pleasanter than one might expect. The climate is mostly humid continental, giving way to subtropical in the south. I think this is because I made the mountains to the south fairly low, which is how I imagined them, and they didn't provide much of a barrier to the moisture blowing in from the southwest.

Obviously it's hard to say how many of the discrepancies are down to Tolkien's errors as a world builder, or down to UW's deficiencies as a world modeller, or down to my own errors in translating the maps to match the projection used here. Probably it's a combination of all of these factors.

Anyway, there's a quick demonstration of what you can do with the import feature. I hope people will find it useful who would like to sketch out a world and then have the computer calculate the climates and show roughly what it might look like.

Sunday, August 29, 2021

Tinkering with tools

Now that the actual terrain generation is mostly done (barring a few bugs, of course), I've been messing about with the UI, and I've added two new features that I've wanted to add for a while.

The first is the ability to change the colours and other settings used to generate the relief maps:

As you can see, you can change all the colours (thanks to the stylish colour wheel that comes with Nanogui), and also change the strength (and direction) of the shading, as well as the marbling effect and how many rivers will be shown. This allows the user to customise the look of their maps to quite a high degree from within the app. The settings stay with the world if you save it and load it later, and you can also save the settings themselves to apply to another world if you want to.

The second new feature is the ability to generate, and export, maps drawn to regional scale but of larger areas. The user can simply mark out an area on the global map that they'd like detailed maps of, and UW will draw the maps and save them to the hard drive. (You can't view them within UW, but you can of course open them in whatever other program you like.) So you can have maps like these:

That last image is pretty huge (3441x2017 pixels)! (It has the shading on land cranked up to maximum too.) As you can see, it's now possible to create detailed maps of entire continents if you so choose, as long as you don't mind waiting for them (the last one took a couple of minutes). It might in theory be possible to create a detailed map of the entire world, but I haven't tried...

The only feature left to add is the ability to import your own heightmap and have UW turn it into a complete world, including working out all the climates and rivers and so on. Some people have requested this, and I'd like to add it, but it would be a little complicated because I need to work out how to do mountains. (Remember, Undiscovered Worlds' mountains are not simply areas of high elevation on the heightmap - UW also stores ridge directions and connections, which are additional data. So I need to think of a way to create that data from raw heightmaps.) I want to avoid feature creep, so I may leave this to add at a later date, after I've released the first version. If I do that, then once I've squashed the more prominent of the remaining bugs and worked out how to actually create a standalone app, I'll be in a position to release it and let other people play with it.