Hello everyone! My name is Loren and I am one of our engineers. One of the two things I have been working on recently is adding support for rivers on the overland map and while they are not 100% complete, I figured I would throw together a write up showing how they work. What follows are screen shots of the various stages of development for these as well as technical descriptions for what I am doing.
BEWARE, TECHNICAL THINGS FOLLOW!
So to start we have a picture of the current lower right corner of the map and this will be the area I focus on. The fog of war is hidden to help with the screen shots.
The first phase of adding rivers was getting the data graphed for where rivers flow. In our map system rivers follow the edges of tiles as opposed to roads which move through the middle. As you can see by the coloring we have two different river systems that empty out into the bay to the south. The graph was traversed from the ocean inwards to compute how far each segment is from the ocean and we darken them to represent this distance.
Now that the graphs are ready the next step was to create a system where the nodes of the river are slightly more smoothed out. I knew that eventually I would need to use some kind of spline to create the organic shape of the river so I needed to get a base set of control points to work with. At this stage you can see the control points splitting at branches and that they follow a smoothed path as opposed to the jagged structure of the hexes.
After looking at a couple of the commonly used spline systems for games I settled on using Bezier splines for the rivers. They provide the control we need and are simple to implement. At this point I added randomization to the control point locations since the original positions were too sterile and am now drawing each spline as it follows the river flow. For those familiar with Bezier splines (or paths) in art software you know that they have control handles for each node (or knot). I compute these handles in a downstream fashion to ensure the water follows a more natural erosion pattern.
The next step was computing a mesh off of the spline. I am only showing the left mesh for the moment to help contrast how the original source data looks. This mesh will be used in the computation of the composite height maps used for each terrain render tile. At this point though the tributaries do not start small, nor does the river empty out into the ocean. That said, you can see how they merge and I feel that they look fairly organic while still informing the player about the location of the hex edges.
There we go. As you can see the rivers now properly start small and grow and there is also now a small river delta reaching out into the ocean. I did some more twiddling with the start, mid-point, and exit sizes to get a feel for how big the river should be in the scale of our world.
It was then time to write a shader to output the height map data necessary for creating the composite maps. Using data I embedded in the mesh I use the cos function to compute an approximate height map with some tapering in the tributary sources. The rivers are currently the only elements in the overland using procedural height maps and have a few variables exposed to tweak how they affect the world. Importantly, as you get closer to the edge of a river it begins to defer to the height maps it is overlaying so we don’t just wash out their detail.
And rivers! The final work phase was to add the rivers to the registered data for the render system and to use them when creating the render tiles. There was a ton of tweaking at this point to the size of the created mesh, the depths the river worked at, and in how its height map played with the others. At this point I am pretty happy with the results but there are a few things left to do such as cleaning up the tributary starts, making it so that vegetation does not spawn on the rivers, and adding some customization to the water flowing in the river.
I hope you enjoyed this write up even though it is technical. We are having fun making this game and are happy to have you guys be a part of it!