Monday, December 22, 2025

Springs and valleys

It's been quite a while since the last post - real life has unfortunately rather dominated things recently and will probably continue to do so for quite a while. But I'm still tinkering with the planets when I can.

I've been working on refining the river simulation at the regional level, in particular making springs a bit more realistic. These are little rivers that flow into the main rivers, delivering the additional flow that the main rivers pick up in each tile. Previously, they were just random. But I thought it would make more sense if I could space them out a little so they flow into the main rivers in a more realistic way. To do this, I create imaginary zones around the rivers and start streams at the edges of these zones, spaced a bit from each other. That looks something like this:


All the rivers and springs here are shown the same shade, so it looks a bit overwhelming, but you can see in the more isolated sections how the springs flows nicely into their rivers. (The pink bit is a river valley.)

I've also enhanced the way that all rivers, including springs, carve the land beneath them, especially around mountains. That gives us pleasingly rugged landscapes like this:


There is still a lot of ironing out to do with this. I am thinking of implementing a simple hydrolic erosion system so that the shapes of the mountains interact more meaningfully with the valleys carved out by the rivers. That might mean I can make the mountains themselves a bit simpler, as the rivers will be doing more of the work of making the highland areas crinklier.

Saturday, July 12, 2025

Rivers again

Just a quick update to show that things are moving. The process of converting all of the regional-level generation to the new spherical planets continues, though a lot more slowly than I'd like. This is partly because of dealing with the roundness, but also because I'm trying to improve the routines as I go and (crucially) speed them up wherever possible. Speed is more important than it was with the old version, because the engine needs to be able to generate and place regional areas on the globe in real-time as the user moves around.

Anyway, I've more or less got rivers and lakes working, which has been as difficult as ever. But I think the rivers are looking quite reasonable:


I've also found a way to do rift lakes a lot more simply than before. I've adapted my approach to non-rift large lakes. The idea is this: create an elevation map where all the seed heights (at the corners of the tiles) are above a certain elevation, and where all points where a large river runs through what will be rift lakes are well below that elevation. Diamond-square it, and then treat all areas that end up below that elevation as templates for rift lakes. That gives results like this:


As always, there are still lots of bugs to iron out. And I haven't been able to get deltas to work at all on the spherical maps, so I'm going to have to rethink those. But it's coming on!

Monday, April 14, 2025

Improving river simulation

I'm continuing with the process of converting the old region-drawing functions into the new globular context, and refactoring and improving them where possible.

While doing this I decided that the old way of tracking river flow wasn't accurate enough. At the moment, UW stores the January and July temperature and rainfall for every point on the global map. When needed, it can calculate the temperature and rainfall for other months by extrapolating them from that stored information (along with other relevant information such as the planet's obliquity, eccentricity, and so on). So far I've been doing the same thing with river flow: for every global cell, the program stores how much water is flowing in January and in July. The problem is that it's not possible to extrapolate the information for the other months from this information. This is because river flow is determined by more than just information about that point on the map. The water comes from elsewhere, and quite different climactic conditions might prevail in those other places. So we can't say (for example) that because there's less rain in March than in October there should be less river flow, because perhaps that isn't true of the place where most of the water is coming from.

So I've updated the program to track and store river flow for all twelve months. When the rivers are calculated, it goes through every cell on the globe and calculates how much water will be flowing for every month, and then adds that, month by month, to every downstream cell from that point. This means that the variation in flow can be shown quite accurately.

Here, for example, is a world with a very long river that travels through mostly desert and tundra:


(I've removed the clouds so it's easier to see.)

The information in the graphs to the top right are for a point on this river roughly in the middle of the image, where it passes through a pretty cold desert. There's significant variation in temperature, and no precipitation at all, but the river has a roughly constant flow throughout the year because its sources, far to the north, are in places with fairly even rainfall throughout the year.

Now compare this image:



You can see another large river which joins the first one near its southernmost point, in a darker area that indicates extensive wetlands. This river has its sources further south in the tundra and arctic mountains to the bottom right of the image. The graphs here are for a point on this new river near where it joins the first one. The temperatures and rainfall are similar to the previous one, but here you can see extreme variation in river flow: none at all for much of the year, and then a deluge in the brief summer as the snow melts in the sources of the river far to the southeast.

And, finally, we have this image:


This shows information for a point on the river near its mouth. Here, there is a bit more rainfall (not much!), but you can see that the variation in flow of the river follows an opposite pattern. For most of the year the river is moderately sized. This is the same flow that we saw in the first image. Then in the summer the river floods extensively, thanks to the meltwater coming from the second river that joined this one.

Since UW now displays variation in the seasons, the plan is that the sizes of rivers at the regional level will be shown dynamically, so you can see them swell and shrink as you move from month to month. Now that the program is storing flow information for every month, rivers like the one above should show this kind of variation in a way that adds a bit of believability to the simulation.

Thursday, February 13, 2025

Zoom!

It's been quite a while since the last update. This is partly because there has been even more RL than usual to deal with, and partly because creating regional-level detail on spherical planets is hard!

To recap, in the previous version of Undiscovered Worlds you could view a world map, and then click on a point on that map to bring up a regional map, in much higher detail. The program creates the regional map afresh every time you visit it, but procedurally, so it's always the same. This creates the illusion of a vast and highly detailed world. But of course only one regional map is displayed at any time.

With the new version, we want to display regional maps directly on the globe. So instead of having separate global and regional displays, we just have a single display that shows the global images if you're far away and the regional ones if you're zoomed in, fading neatly between them. This means displaying multiple regional images at a time, since the user might be only halfway zoomed in and therefore able to see several at once. It also means being able to dynamically create the regional images as the user moves around, ideally without any gaps or pauses.

Well, I've got the basics of the system up and running. Although the new regions are 2D, like the old ones, it's still quite a lot of work to translate the generation functions given that they're now extrapolating information from a 3D global map rather than a 2D one. Along the way I'm trying to refactor the functions to be as efficient as possible, since speed is now even more important than it was before. So far I've done just the basic elevation with mountains, and rainfall and temperature. No lakes  or rivers or anything else fancy yet, but it's enough to give a pretty good idea of how it all works:


That's several regional areas all being displayed at once. Here's a video of the zoom (though it's a bit blurry!):

There are still a lot of bugs, as well as all of the other features to add, so it will be a while before this is done, but progress is being made!


Sunday, September 8, 2024

Alpha update

Since the program is now running in a mostly stable way, I decided this might be a good time to update the code on github. It's definitely not ready for a proper release so I've not uploaded a built executable, but some people might like to have a look at how it's working. So consider this a sort of alpha preview.

It's uploaded here. The previous version of Undiscovered Worlds, with flat maps, is now Undiscovered Worlds Classic and can be found here, including the executable and instructions.

You don't get the jazzed-up GUI though, because those are changes I've made directly to the ImGui code, so I can't really upload them as part of this project.



Tuesday, September 3, 2024

Parrots everywhere

My spherical worlds are mostly working pretty well now (although for some reason I haven't been able to make river deltas work on them - I don't know why). So it's time to try to get regional-level maps working with these worlds.

As I've explained before, this will work differently from the original, flat-world version of UW. In that version you could view the global map, select a point on it, and zoom in to see the regional map of that part of the world, in a separate screen. But this wouldn't work very well for a spherical world, where we will instead display regional maps directly on the globe itself. As you zoom in, the details of the regional maps will become visible. So it should all operate seamlessly. That's the theory anyway!

This means we need the ability to generate and display multiple regional maps at once. It's not possible to store regional-scale information for the entire planet, since a large world has 16 x 16 regions on each face, making 1,536 regions in all. We can store only a fraction of these at once. So what we need is a system whereby the program can dynamically create new regions as the user moves around the world, deleting them when they're no longer visible.

After many false starts I've got the basics of this system up and running. We have a stable of threads dedicated to generating regions and drawing their maps. As the user views the globe, these threads work in the background to create regions roughly where the user is looking, with unused ones being discarded. Meanwhile, the main thread displays the regional textures where they exist, and the lower-resolution global textures where they do not. This way, if the user is zoomed in enough to make out details at the regional scale, they should be able to see only regional textures visible on the screen.

Now I haven't yet started translating the actual region creation functions so that they work with spherical worlds, because I wanted to get this system up and running first and then plug in the region creation functions as I convert them. So at the moment the region creating threads are just applying a placeholder texture (of parrots, because why not). But here is a pretty rough-and-ready (and somewhat nausea-inducing) video showing the system in action.


As you can see, as we move around the planet (or rotate the planet itself) the more distant regions are deleted and replaced with closer ones. If you zoom in closely, it creates the illusion that the entire world is covered with nothing but parrot images, because you can't see the edge of the patch of textures.

Now all I need to do is to convert the existing region-creation functions from the old version of UW. For the most part this should (I hope) involve changing them so they take their raw data from the spherical world object instead of a flat one. This will be tricky at the edges of faces, because the regions as generated are a bit larger than what you see. This is because some elements of the tiles that compose the regions overlap from tile to tile, so when we generate a region we need to generate the tiles along the edges of its neighbouring regions, in case anything from them overlaps onto our region. In a flat world this is fine, but here we're going to have regions along the edges of faces of the cubesphere, which means we have to take into account the fact that tiles from the next face along might be rotated relative to the active face, and that complicates matters.

That probably makes very little sense. Still, I'm glad to have the framework for regions set up now, so I can focus on getting back to map generation...

Thursday, July 4, 2024

Sprucing up

My plan to create, replace, and delete regional maps on the fly means I need to use multi-threading, where a program basically splits itself into multiple concurrent programs. This is so that Undiscovered Worlds can get on with generating regional terrain while the user is moving around and viewing the world. I've never done this before, so I've been learning how, and fortunately it's not too hard, at least in principle. To practise, I've added a progress bar for world creation - one thread creates the world while another updates the progress bar - and it works quite nicely.

Adding the progress bar made me think again about the GUI. I'm using Dear ImGui, which is a very widely used library, but mostly for internal use rather than user-facing interfaces, because it's pretty simple to incorporate into one's code but doesn't look very fancy. (Also it's easily recognisable!) I certainly don't want to change to a different GUI again, but I thought it would be nice to try to change the appearance of Dear ImGui a little to make it a bit more distinctive and attractive.

So I've had a go at tinkering with the code of Dear ImGui. I've been shamelessly copying the style of NanoGUI, another library that I was using for a while in an earlier version of UW, but abandoned as it proved too tricky to port to Windows. My very rough hacks can't really reproduce its appearance, but I think the results look quite nice:


Hopefully it doesn't look quite so generic now. There is still some tweaking to be done, of course, but the next focus is on getting some version of the regional detail up and running.