Unfortunately that would mean a lot of constant/regular updates to the water, so a huge number of water blocks would be updating at short intervals – in other words, massive memory sink.
A great comparison would be against the old memory drains created by un-solve-able pathfinding queries, and how they’d stack up until the game couldn’t run anymore. Imagine an equal or greater number of queries to check whether a water block should evaporate or not – even if the frequency is lower (say once per day), that’s still going to hurt whatever computer is trying to run it all.
It’s not just the direct cost for evaporation simulation either, there will be unintended side-effects. One which springs to mind is the fact that every block which is removed due to evaporation will cause all outstanding/paused pathfinding queries to try again (because the terrain is being updated), so that’s a carry-on/snowballing effect.
And on a more basic level, how can we be sure that a source in the lake will actually match its evaporation? What if the player decides they want a waterfall, so now there’s not just evaporation but also a direct drain (presumably much faster), which feeds into a new lake/pond that is itself subject to evaporation?
I’ve been thinking that one viable way to handle flooding and evaporation I’ve seen in other games is to have two different kinds of water – “permanent” and “temporary.” The permanent water is what makes up lakes, rivers and oceans, while temporary water is created by rain and probably some other sources.
But even with that idea, you still have the fundamental issue that either the temporary water collects + evaporates causing large water movements and therefore high processing costs; or else you have an infinite amount of water entering and it doesn’t evaporate, which means the whole map eventually fills up and turns your town into a mini Atlantis!
I suppose another option is to look at the ratio of water to non-water blocks nearby to determine evaporation – something like “evaporation chance = 1/no. water blocks within 3-block radius of block in question”, so a block surrounded by water wouldn’t evaporate (assuming there’s some rounding, e.g. <1% = 0%) However, that means your evaporation checks have to check a lot of blocks nearby, which is an even more massive processing sink.
One game which sort-of solved this issue was Towns, which used the “mix of permanent and temporary water” solution. Rivers, large lakes and oceans were generated using the permanent water (it was called “water_inf” in the game files), and this water also worked as a source block to spawn the other temporary kind of water. However, it only did so in tiles which were adjacent horizontally to itself, so it avoided the Atlantis scenario… unless you accidentally flooded your mine tunnels, or intentionally built a “fountain tower” to raise water high into the air. Because the water_inf didn’t evaporate, it only had to update when the terrain did; and since the game updated the entire map at once (which, AFAIK, is exactly what Stonehearth does) there was no perceptible difference in performance – unless, of course, you tried to intentionally mine out a massive number of blocks adjacent to water all at the same time… and that wasn’t easy to do anyway, so I doubt it’s a problem many players will run into hahaha! The regular/temporary water would evaporate at a consistent rate, with clearly defined levels – level 1 being a tiny puddle, and IIRC level 6 was a full block’s height. However, there was a 7th level, which looked identical to the 6th one, but at level 7 a block was no longer subject to evaporation. Effectively, that was saying “the source is replacing water at the same rate as evaporation is taking it out”, and once a body of water reached level 7 across all blocks it became static, i.e. a still/calm lake or river or whatever.
Unfortunately, Towns worked on a tile-based grid rather than a true voxel system, so the water blocks operated very differently to how Stonehearth’s water does. I do know that the Towns devs called their water volumetric, which I believe is the same term applied to Stonehearth’s water blocks, so there’s probably a fair bit which applies to both; I suspect however that Stonehearth’s water will end up being more complex and, hopefully, more robust and accurate (and prettier!) as a result.
That’s why I think there should be a way for the game to “ignore” water blocks with a suitably low chance/reason to evaporate, so it’s only small bodies of water and the edges of puddles which shrink. This leads to a reasonable approximation of a natural-looking process – large lakes with deep shores won’t shrink, or if they do it will be very slow, while wide and flat pools/flooded plains will start shrinking slowly and then the shrinkage will speed up (and of course the player can speed it along heaps more by draining the edges of the floodplain or pumping it to spread it out.) In Towns, the water was functional even if it looked janky because of its discrete levels. In Stonehearth, the greater level of detail offered by the voxel engine can hopefully avoid the same jankiness, and make it easier to move water over large distances since the change in height can be applied far far more gradually – rather than dealing with Towns’ limit of 7 visible steps between empty and full, in Stonehearth the water will be able to evenly occupy wide, shallow areas or deeper, smaller areas and behave appropriately.
I also think that evaporation should be paused on flowing water, partly as a pure convenience measure (i.e. save the devs effort) and partly to make it easy for players to create flowing streams and waterfalls. In Towns, there was nothing more annoying than having water evaporate while it was in transit to its final location.