## [Mod] Dynamic liquids [dynamic_liquid]

Yvanhoe
Member

Posts: 62
Joined: Fri Jul 05, 2019 03:18

### Re: [Mod] Dynamic liquids [0.8] [dynamic_liquid]

zargulthewizard wrote:Could you create an addon to change pipeworks to function with this mod? This would be totally cool: the water pipes would have an actual purpose instead of doing this:

With just a small change I was able to make pipeworks and dynamic_liquid work together. Still some problems as the total volume is not preserved (water is created in the pipes in my tests) but a way forward! On VanessaE's suggestion, I'll look into a flow logic branch that has been dormant in her repo for a while when I am finished playing with my unicode problems :-)

FaceDeer wrote:Indeed, it's a definite limitation that I've been reluctant to address due to performance concerns. As the mod currently stands each node only needs to know about its immediate neighbors, but to have water flow through a U-bend a node at the top of one column will need to do some kind of search through a long distance to find whether there's a connected node on the other side of the U-bend that it can move to.
Not necessarily. After all, in real life water flows only happen because of local considerations (but the tick is much higher!). I suspect that by simulating pressure and making water (and pressure) move around you could even have the air bubble behavior but do we really want an ABM on air nodes?

I need to think more about it, but on first approximation I think that you could have a pressure number per water block, an ABM that computes the current pressure by taking the maximum of the pressure of the 4 touching cubes at the same level, the pressure of the above cube +1 and of the bottom cube -1 (because of gravity. 1=pressure added by the weight of a cube of water).

State for instance that atmospheric pressure is 100. Make a cube move up into air if it has a pressure of 102 or more, giving priority to the highest-pressure water neighbor. That means that in a pool at rest, pressure would rise of 1 per cube of depth.

Of course reaching equilibrium will take much longer and instead at moving at several km/s, pressure changes move at one cube/s. But ideally in most cases the equilibrium should be similar.

In a U-shaped tube, here is how the pressure would look like (making the atmosphere=0 for simpler visualization):

Code: Select all
`▯.▯.▯   ▯_▯_▯▯~▯.▯   ▯1▯_▯▯~▯.▯   ▯2▯_▯▯~▯.▯   ▯3▯_▯▯~~~▯   ▯444▯▯▯▯▯▯   ▯▯▯▯▯`

And how it would evolve in time:
Code: Select all
`▯_▯_▯   ▯_▯_▯   ▯_▯_▯   ▯_▯_▯   ▯_▯_▯   ▯_▯_▯   ▯_▯_▯▯1▯_▯   ▯1▯_▯   ▯1▯_▯   ▯1▯_▯   ▯1▯_▯   ▯_▯_▯   ▯_▯_▯▯2▯_▯   ▯2▯_▯   ▯2▯_▯   ▯2▯_▯   ▯_▯_▯   ▯1▯_▯   ▯1▯_▯▯3▯1▯   ▯3▯1▯   ▯3▯1▯   ▯_▯1▯   ▯1▯1▯   ▯2▯1▯   ▯2▯1▯▯44_▯   ▯4_2▯   ▯_22▯   ▯222▯   ▯222▯   ▯222▯   ▯322▯▯▯▯▯▯   ▯▯▯▯▯   ▯▯▯▯▯   ▯▯▯▯▯   ▯▯▯▯▯   ▯▯▯▯▯   ▯▯▯▯▯`

It should oscillate between the two levels.

FaceDeer
Member

Posts: 351
Joined: Sat Aug 29, 2015 19:01
GitHub: FaceDeer

### Re: [Mod] Dynamic liquids [dynamic_liquid]

If you're in a tinkering mood, I made waterworks primarily with this mod in mind. I want to do more polish on waterworks before calling it "done", generalizing it to function with other liquids and adding some better pressure control systems, but right now it actually can do the U-bend thing (albeit only between predefined inlet/outlet nodes). Unfortunately I'm swamped with modding various other things right now so it'll be a while before I get back to it. :)

Storing a per-node pressure value is a good way to reduce computation costs, but at the expense of a lot of storage cost. However, I note that the param2 value is not reserved for drawtype="liquid",liquidtype="source" nodes (it's reserved for engine use for flowingliquid, but it should be fine to ignore those and treat them like air). So perhaps you could store pressure values in water nodes' param2s.

One other problem that comes to mind is that currently the ABM only operates on water nodes that are adjacent to air or flowing nodes, which saves a ton of work. Pressure values wouldn't update for below-surface nodes and pressure changes wouldn't propagate.

An alternative approach comes to mind. Maybe we could emulate a "small world" network here by using two separate ABMs, the existing one that only cares about immediate neighbors and a second ABM that occasionally triggers on a random water node and does the expensive pathfinding operation searching for a route to a lower air node (and tests if it's an air pocket that should remain trapped). If this expensive operation discovers such a route, it records the fact and begins rapidly routing water nodes along it (similar to how the waterworks mod does it, I guess - there'd be a sort of imaginary pipe connecting the two points).

Over a long period of time this should reach the "correct" equilibrium. It may behave a bit strangely from the short-term player perspective though; a pond of water could sit stably for several minutes and then suddenly start draining or overflowing when a connection to a different-elevation water body is discovered.

Yvanhoe
Member

Posts: 62
Joined: Fri Jul 05, 2019 03:18

### Re: [Mod] Dynamic liquids [dynamic_liquid]

I am always in a tinkering mood but unicode woes give me plenty to tinker with right now :-) I am just looking for ways to introduce volumes and area in my educational workshops. Exploring liquids sounded like a good idea. I want to make a cement/concrete casing exercise. I am adding waterworks to my folder of mods to experiment with, thanks!

One other problem that comes to mind is that currently the ABM only operates on water nodes that are adjacent to air or flowing nodes, which saves a ton of work. Pressure values wouldn't update for below-surface nodes and pressure changes wouldn't propagate.

Could we not make flowing nodes a property that propagates? And maybe after 10 seconds not changing value and having a pressure = 100 - z (the normal equilibrium pressure for open air ponds) remove it to turn it into a stable water node?

When I was playing dwarf fortress I was really curious at how their water system worked. Turns out that it is pretty straightforward (and memory intensive, but when you count it all we do have enough memory nowadays to do a tons of stuff): they simply compute the connected component of every body of water, its floodable neighbors and teleports water from a high point to a low point. Works with U-shaped tubes but has no notion of air pressure. That's probably not realistic in lua, and even in C++ that may require too many database accesses.

If you want to go that route though, tracking with component a block of water belongs to, and what floodable neighbors it possesses may be a way to go. Note that finding a path to any low point and finding all the elements of the connected component probably take around the same amount of resources but in the later case it is re-usable for all water blocks of the same body of water.

Previous