The main terrain component water-tight region is not updating when a world is first created. This affects both a standard game initially and also affects microworlds. Once the game world has been saved and reloaded then the water-tight region gets updated and everything appears to be working normally.
Secondary to this the hydrology service has a null value stored for the water-tight region because what it receives from the main terrain component initially is nil. The result is that any water bodies not created with create_water_body_with_region() throw an exception and fail to add any water. As above, once the game has been saved and loaded back then it behaves normally.
To see the region in question call the following method and also observe the behaviour of water when adding in a new water body or changing the shape of an existing container of water:
Is there a method I can call to force it to refresh the calculated water-tight region? I assume that it will be a CPU-expensive call but I need a way to handle this case in the mean time.
For annoying technical reasons (buffered updates to the navgrid interacting with world generation) the water tight region doesn’t update until the end of the first gameloop.
Try adding your code after the first gameloop ends:
radiant.events.listen_once(radiant, 'radiant:gameloop:end', function()
-- do stuff here
end)
Unfortunately that doesn’t quite apply in my case. What I’m running is well after the first gameloop event ends. All I can find different is that this bug appears when the game world is fresh, meaning it wasn’t loaded from a save file. But any world I load from a save file works just fine. For most users this is an edge case they probably won’t see. However, when using microworld this is a big problem since in order to test things I have to make save copies each time and can’t just use the microworld fresh.
I discovered this while doing some mod work where an entity attempts to spawn water in the air and keeps adding to it via add_water() in the hydrology service. If the world is fresh then the water just piles up in a big column and doesn’t flow down to the ground in a waterfall. However as soon as I save the world and load it back up from the save then the water falls the the ground and spreads like normal. I left the world running for at least 30 seconds and the terrain water-tight region still hadn’t refreshed.
I know this is an edge case that most players won’t see so I understand this being a low priority and am okay with that. Just painful for my microworld testing right now.
Any further thoughts/ideas? Need anything else from me?
@chessmaster42, as I’m a total noob with code and console manipulation, could you explain this add-water() command please? (that’s the kind of stuff that sounds very helpful for the exercise I’ve done with the lakeside village unfortunately I missed such command and no one told me about it…)
The latter is essentially what I’m doing though inside of an entity component class. However the water-tight region still hasn’t updated and the water goes nowhere. Is it possible that it has something to do with how I’m deforming the terrain in the startup of the microworld? Here’s how I’m doing it. Please let me know if I’m doing it wrong and there’s a better way:
--Only run terrain modifications once the main gameloop has run at least once
radiant.events.listen_once(radiant, 'radiant:gameloop:end', function()
local block_types = radiant.terrain.get_block_types()
--Dig the hole in the terrain for the water
local region3 = Region3()
region3:add_cube(Cube3(Point3(20, 6, -28), Point3(28, 10, -20), block_types.grass))
radiant.terrain.subtract_region(region3)
--Create the body of water to fit the region
stonehearth.hydrology:create_water_body_with_region(region3, 3.95)
--Dig the hole in the terrain for transferring water to
local region3 = Region3()
region3:add_cube(Cube3(Point3(20, 6, -40), Point3(28, 10, -32), block_types.grass))
radiant.terrain.subtract_region(region3)
end)
Also, here’s a screenshot with terrain chunks and collision mode on so you can see this:
It would seem that there were two things here contributing to what I was experiencing. The first is this bug which after more testing appears to be even more of an edge case than I thought. The second is the fact that the water component will only accept volume changes greater than constants.hydrology.WETTING_VOLUME. What I’m doing can add as little as 0.01 water volume at a time and it was all going poof. Took me ages to figure out what was going on here.
That said I’m not sure if you want to close out this bug. Technically it’s still a problem in microworld but of minimal impact. As for my specific problem with very tiny volume changes I came up with the following to handle it:
--Accumulate the dumped water because the water component nils out volume changes less than the constants.hydrology.WETTING_VOLUME (0.25)
self._stored_water = self._stored_water + liquid_removed / 1000.0
if self._stored_water > (0.25 + self._keep_alive_water) then
--log:error('DEBUG - Water added is %s', tostring(self._stored_water))
--Add the water to the world and reset the counters
stonehearth.hydrology:add_water(self._stored_water, location, nil)
self._stored_water = 0
self._keep_alive_water = 0
else
--Keeps the waterfall alive
stonehearth.hydrology:add_water(0.01, location, nil)
--Track how much pseudo-water is being used to keep the waterfall alive
self._keep_alive_water = self._keep_alive_water + 0.01
end
Thanks for the help so far; it is much appreciated!