Gummyslav Posted Tuesday at 05:31 PM Report Posted Tuesday at 05:31 PM (edited) Hello there I am no expert when it comes to VS worldgen (or any worldgen for that matter), but I thought I might share my thoughts on how I would approach the issue of generating rivers (I just couldn’t sleep today and I’m quite obsessed with the game at the moment). My hope is that even if most of my ideas are not relevant, they will at least help the devs see their current system from a fresh perspective and push their thinking in the right direction. I would start with generating underground water bodies and springs. The size of an underground lake would determine the initial speed of a river. For a more realistic approach, I would wait with carving the landscape until a “head” of the future riverbed (I think of it as a snake) reaches an elevation drop. The head would move in one direction on the surface of the ground, creating a “path”. The head’s speed could be slightly reduced when moving on dirt, gravel, sand, etc. The path would branch after a certain distance (the greater the distance, the faster the head), if there aren’t any nearby obstacles along the possible new path. No more than two branches would be added on the sides of a path, and they would deviate from it at an angle depending on the head’s speed. The faster the head, the smaller the angle. Additionally, the current width of the river should reduce the likelihood of branching - the wider the river, the less likely it is to form new branches, reflecting increased stability of larger flows. Each new path would have its own head, which would be slightly slower than its parent. When a path X bumps into a path Y, it merges with it. The head of path X stops moving. The speed of path Y and its children’s heads increases. If any of the heads reaches an elevation drop, all the other heads stop. Now, if any of the other heads is in very close proximity to an elevation drop too, and its speed is higher than the speed of the first head to reach the drop, the riverbed should branch. The riverbed path is generated based on rounded path vectors that create the shortest way to the drop. The depth of the riverbed depends on the blocks forming the floor and the speed of the “victorious” head. The softer the floor and the faster the head, the deeper the riverbed. The riverbed’s width should be based on the number of branches of the main path, the floor blocks, and the average elevation difference between the last few sections of the riverbed. (If there are many large elevation drops in the recent sections, the width should increase more slowly—the harder the ground, the stronger this effect. Mountain streams would be narrower, while rivers on muddy plains would be wider.) A riverbed should influence nearby land and form banks. One new head continues in the same direction after the drop, and its speed is increased if the drop is small (and decreased accordingly). Lakes form when: the heads of the paths have low speed, struggle to reach a drop, and often merge with each other, riverbeds with opposite vectors meet, there is a big drop (small drops wouldn’t form lakes). Lakes may or may not be the end of a river. Let’s take a closer look at the three scenarios I listed above. If the conditions for a lake are met and the chances of any head reaching a drop are low, the river ends. When two riverbeds meet, river A could strengthen river B, or they could spawn a new head with a speed and direction based on their vectors. I’m too tired at this point to think about it any further xd Lakes formed by drops spawn a few heads in all directions. Their speed is lowered proportionally to the height of the drop, but increased based on the width of the riverbed before the drop. We should also consider the depth of the lake, depending on the speed of the head that reached the drop and the height of the drop. Once we have the riverbeds carved into the world structure, we fill them with still water and cover them with one layer of flowing water. The velocity of the top layer could be calculated based on the width of the river, the average velocity of the previous few “sections”, and local elevation drops. The top layer would have a pushing force based on its velocity and would transfer it to the still water below. I wonder if you are planning to go even deeper into the rabbit hole and introduce a mechanic allowing water from lakes and rivers to overflow the banks during heavy rains (floods!) and then slowly evaporate or sink into the soil and replenish groundwater resources (possibility of droughts and seasonal rivers!). Even if not, you are still awesome and I can’t wait to see what you’re cooking for us in the updates to come. Edited Tuesday at 05:34 PM by Gummyslav 3 1
Bruno Willis Posted Tuesday at 11:19 PM Report Posted Tuesday at 11:19 PM 4 hours ago, Gummyslav said: I am no expert when it comes to VS worldgen (or any worldgen for that matter), but I thought I might share my thoughts on how I would approach the issue of generating rivers (I just couldn’t sleep today and I’m quite obsessed with the game at the moment). Welcome to the forums! I've also had one of these sessions, and I like what you've got here. 4 hours ago, Gummyslav said: For a more realistic approach, I would wait with carving the landscape until a “head” of the future riverbed (I think of it as a snake) reaches an elevation drop. The way I read this section is that the game would essentially draw out an elevation map and then overlay a number of likely rivers, then choose the best of those rivers following realistic parameters (fastest flow, most direct route downhill etc.), and generate terrain, those rivers included. Is that right? 4 hours ago, Gummyslav said: The path would branch after a certain distance (the greater the distance, the faster the head), if there aren’t any nearby obstacles along the possible new path. No more than two branches would be added on the sides of a path, and they would deviate from it at an angle depending on the head’s speed. The faster the head, the smaller the angle. Additionally, the current width of the river should reduce the likelihood of branching - the wider the river, the less likely it is to form new branches, reflecting increased stability of larger flows. Each new path would have its own head, which would be slightly slower than its parent. When a path X bumps into a path Y, it merges with it. The head of path X stops moving. The speed of path Y and its children’s heads increases. If any of the heads reaches an elevation drop, all the other heads stop. Now, if any of the other heads is in very close proximity to an elevation drop too, and its speed is higher than the speed of the first head to reach the drop, the riverbed should branch. Reading this, I initially thought that rivers don't typically split again once they've met (the exception being braided rivers which are wonderful and not common). Reading it again though, are you suggesting that the game uses the branching mechanic to propose alternative paths, and then chooses the best of the three possible options and generates that one? I like that idea. 5 hours ago, Gummyslav said: I wonder if you are planning to go even deeper into the rabbit hole and introduce a mechanic allowing water from lakes and rivers to overflow the banks during heavy rains (floods!) and then slowly evaporate or sink into the soil and replenish groundwater resources (possibility of droughts and seasonal rivers!) I really like the idea of floods, but I've also been listening when people explain that a full meter of water rise would A: not be realistic and B: cause a lot of problems with terrain gen. But, your post gave me an idea about special river-flat blocks which might let us do flooding in a cool way: They'd essentially be dirt slabs, which would generate when a river ran through flat dirt land. They'd generate on either side of the river, out until they met an elevation change. They'd be able to have plants placed on them (I know, that'd be an issue but bear with me), which would grow extra bushy around the base (allowing the devs to use their normal plant models and then extend a half-block of tangled foliage filling the space below). The river-flats would be able to be tilled, and would have good fertility, but if dug up would just produce "silty earth" which would work like fertilizer rather than a placeable block. When rain fell for an extended amount of time though, all rivers with river flats would rise one block higher, and the river flats half blocks would flood, destroying any plants and crops (except rice?) which were planted on them. Any missing bits of river flat would re-generate if there were river flat blocks adjacent (simulating silt washing over the flats). It'd stay flooded for four days after the rain stopped, and then return to normal, except the river-flat blocks would be refreshed to full nutrient value, be un-tilled, and stripped of any grass which might have grown on them. 2 1
Gummyslav Posted 3 hours ago Author Report Posted 3 hours ago On 3/25/2026 at 12:19 AM, Bruno Willis said: Welcome to the forums! I've also had one of these sessions, and I like what you've got here. Thank you for the warm welcome. I didn’t expect such a quick and positive reaction On 3/25/2026 at 12:19 AM, Bruno Willis said: The way I read this section is that the game would essentially draw out an elevation map and then overlay a number of likely rivers, then choose the best of those rivers following realistic parameters (fastest flow, most direct route downhill etc.), and generate terrain, those rivers included. Is that right? My initial idea was that rivers would be generated in a second phase, after the terrain is already in place. This would allow the properties of the terrain to influence the rivers (for example, if a river flows over sand, it might have a lower potential to propagate due to drainage). But that might be overthinking it. On 3/25/2026 at 12:19 AM, Bruno Willis said: Reading this, I initially thought that rivers don't typically split again once they've met (the exception being braided rivers which are wonderful and not common). Reading it again though, are you suggesting that the game uses the branching mechanic to propose alternative paths, and then chooses the best of the three possible options and generates that one? I like that idea. I must admit, it’s a bit hard for me to fully grasp my own idea, but I think you understood it well. For the sake of explaining it, I made a simple simulation. While it deviates slightly from my initial vision, I personally think the results look convincing. I made two GIFs simulating river pathfinding on flat terrain. To simplify things, I assumed that the initial “potential” of a river is 5, and it decreases by 1 after each cycle. If no path to an elevation drop is found after 5 cycles, the river ends. When a path is found, the cycle count resets. If more than one path is found, the river branches, and each branch has its potential reduced by 1. On 3/25/2026 at 12:19 AM, Bruno Willis said: I really like the idea of floods, but I've also been listening when people explain that a full meter of water rise would A: not be realistic and B: cause a lot of problems with terrain gen. While I’m one of those slightly masochistic players who turn cave-ins and soil instability on, I assume floods would be a bit too much I love your idea of river-flat blocks. They promise a lot of fun and new possibilities while not being too punishing or unrealistic. I’m really glad this sparked such a discussion 2
jerjerje Posted 1 hour ago Report Posted 1 hour ago This generally seems like a sensible approach to generate rivers. But I don't think it would work well for a game like Vintage Story. (Assuming I understood your idea correctly. Please correct me if I misunderstood something) This is mainly, because Vintage Story doesn't generate the entire map at once, it only generates singular chunks at a time. More precisely: Your idea always starts generating the river from some "head". This may be fine, if the player first generates the chunk in which the head is located. But what if the player first loads a chunk in the middle or at the end of the river? How would the game know that there should be a river here? A naive solution to this would be to always generate chunks with rivers outside the normal render distance. However, this could very easily be a performance nightmare. The further rivers can flow, the further away the game would need to generate all rivers. I don't think this would be feasible performance wise (unless you only allow rivers to be very short). Figuring out how to generate large scale features like rivers is always a problem on these infinite open worlds. I'm definitely interested in seeing how the devs will solve this problem in Vintage Story. 1
Thorfinn Posted 22 minutes ago Report Posted 22 minutes ago 33 minutes ago, jerjerje said: This is mainly, because Vintage Story doesn't generate the entire map at once, it only generates singular chunks at a time. So much this. I've spent a lot of time fiddling with changing from chunk-based to landform-based generation, so that you generate all the "divides", but that rapidly gets insane. If you zoom way out on the map, you can see how huge some of these landforms are, yet they are still way too small to plot a river all the way to the sea. Moreover, you will almost always end up with some massive multi-tributary river draining into some tiny pond because that's the lowest point. In order to avoid this, you have to generate continent-sized regions all at once. Which is going to need a pretty massive change to landforms. Islands are pretty easy without much change. You only have to generate until you return to sea level. For continents, I think what you would be stuck with is flattening the world substantially and having landforms using elevation offsets. For example, instead of a plateau landform, you have a cliff landform with a plains landform sitting on top of it. Or maybe you use something more like a geomorph, where the next piece is selected based on the existing ones, kind of like dominos. In any event, flowing water is a serious hog. Granted, once generated, you could optimize it, but you still have to generate it, and at scale.
Recommended Posts