Skip to content

WIP: optional new liquid behavior#1

Open
j-r wants to merge 26 commits intomasterfrom
liquid_physics
Open

WIP: optional new liquid behavior#1
j-r wants to merge 26 commits intomasterfrom
liquid_physics

Conversation

@j-r
Copy link
Owner

@j-r j-r commented Jun 25, 2024

This is a test PR to solicit feedback concerning the usefulness of the new liquid behavior implemented in this branch, primarily from the Mineclonia community.

It differs from other attempts in that it remains fully within the framework of the current minetest liquid implementation and therefore should be bug-for-bug compatible with current minetest unless the new liquid behavior is explicitly switched on. It adds two new param types, directionalflowing and directionalsource with the following changes in behavior

  • flowing in a single direction if there is a path within liquid_directed_range to a lower level
  • when two or more different liquids meet in a node the strongest flow will displace the other liquids
  • a liquid source node that flows down will not spread horizontally
  • flowing liquid above a source node of the same kind will not spread horizontally
  • rendering is slightly different; older clients will render linear flows without volume, but otherwise work fine

As a special bonus feature directional liquid node tops are rendered 1/16 node lower. But unlike most of the rest of the series, that is just an ugly hack.

Note that this branch is currently based on a rather old version of minetest 5.9-dev, because that is the version I've been using for some time on my private server and am pretty sure that it has no issues interfering with testing these liquid physics changes.

To test it out

  1. check out the branch and build it normally in your environment. (Note that while most of the changes are compiled into the minetest and minetestserver executables, builtin/game/register.lua and builtin/settingtypes.txt also have relevant changes.)

  2. run it from the build directory or from a suitable installation directory

  3. create a new world or take a copy of an existing world (it should be non destructive in the sense that no liquid should flow where it didn't flow before, but there may be bugs)

  4. go to the settings and switch the force_directional_liquids setting

  5. run your world

  6. on page 3 of the F6 engine profiler you should see some statistics about liquid processing; when creating a new world or loading a world that didn't have directional liquids, there will be a lot of activity on initial loading; it should become stable after a while and only do anything when loading new blocks (e.g. when turning and moving): stopping and reloading the world should have very little activity

  7. check out how the water behaves now

  8. check out the force_liquid_directed_range setting that will limit the length of linear flows

  9. yell at me that it's crap:-)

The primary goal is to get feedback on whether this is actually useful, what is good, what is bad/missing etc.So please do that. Thank you very much!

Note that this isn't MC liquid even if the results may in some cases look like MC, but it still is very much the minetest liquid system and has different quirks, that might not be fixable within the given framework. The benefit of doing it this way may be that it avoids some of the pitfalls that prevented other attempts from getting accepted.

@DragonWrangler1
Copy link

Well the directional flowing is awesome, and ofc as you pointed out, the water level being a bit lower is hacky. It does have a small visual problem (from the top the texture is still at normal. From the side it's correct, except when looking at the top texture). Otherwise this looks good. I'll test more later when I get more time.

@j-r
Copy link
Owner Author

j-r commented Jun 26, 2024

Thanks for testing!

I found a bug with the liquid interaction leading to unstable constellations which should be fixed by the first commit I just pushed.

The second fixes a deviation from my original vision that all directed paths should lead from a flow down place up to the source. But while looking at it, I'm no longer sure that's the best semantics. It seems somewhat more intuitive, that a flow flows into a directed flow when they meet, but it's not clear what the meaning of the directed range property should be then...I'd like to hear your opinions:-)

@j-r
Copy link
Owner Author

j-r commented Jul 14, 2024

Some results of playtesting:

  • Voxelgardens ABM based liquid renewal (probably deliberately) disregards flowing down liquids, so with directional water flowing down into source nodes it is easy to punch holes into oceans; not a big problem, I think, but raises the question whether flowing down into a source should be separately configurable

  • it doesn't work very well with the dynamic_liquid mod; the mod probably should take direction into account to create more natural looking liquid source movement, but not a problem with this change, I think

  • being able to influence direction would be nice; I pushed a POC that prevents a directional liquid to pick a direction when above a glasslike node; this provides quite a few possibilities, e.g. using a piston to switch direction on and off; not sure how this should be implemented though: perhaps use some param2 values to force a direction/non direction that could be set by a screwdriver or similar tool

@j-r j-r closed this Dec 17, 2024
@j-r j-r deleted the liquid_physics branch December 17, 2024 09:04
@j-r j-r restored the liquid_physics branch December 17, 2024 09:05
@j-r j-r deleted the liquid_physics branch December 28, 2024 07:50
@j-r j-r restored the liquid_physics branch December 30, 2024 19:41
@j-r
Copy link
Owner Author

j-r commented Dec 30, 2024

After some more playtesting I'm mostly satisfied, except for some unintended interaction between directional liquids and liquid renewal: liquids renew only in nodes where that liquid flows, but if the flows are directional there can be holes with up to 4 surrounding sources. I think it is correct that renewal only considers nodes where the liquid actually flows, but sources above sources should not become directional. That actually fits nicely with the glasslike POC.

PS: my repo sync script is sometimes deleting this branch due to a misconfiguration. I'm going to push a variant rebased to current dev "soon".

j-r added 17 commits February 13, 2026 12:56
This shows the number of processed and transformed nodes as well as average and
max processing times of the function.
Note that lower neighbors were never added to the array.
Prevent possible misinterpretation, because the ignore node might not be
an actual liquid source node.
For consistent naming of variables holding current/new node values.
The lower neighbor is special cased and a case statement for the other neighbor
types is added.  This provides a frame where new physics logic can be added
easily.

Note that even though this change prevents the selection of liquid_kind from a
lower source node, this is no semantic change, because the lower neighbor is
checked last and in that case there were no other neighboring sources or flows
leading to no liquid entering the current node. This change makes that fact
more explicit and could be considered a fix.
Note that moving the declaration of max_node_level way to the top of the
function is not needed here, but minimizes a future diff.
Facilitate changes to liquid interaction by collecting all neighboring flows in
the flows array. In particular this allows for changing liquid_kind during the
iteration.

Note that the flows array is only used for pushing nodes to the liquid update
queue, so this change fully preserves semantics.
This removes the second call to get_max_node_level.

Note that get_max_node_level ignores same level falling flows.
This introduces the same special casing for lower neighbors as in the source
neighbor case.

Note that get_max_liquid_level() ignores both lower and same level
falling nodes.
This completes the transformation of the flow neighbor handling into a form
suitable for new physics rules similar to the source neighbor case.
This adds new param2 types for source and flowing liquids as well as the
liquid_directed_range node def property. This contains every necessary change
to run worlds using these new param2 types - with the exact same behavior as
non directional liquids.

Older clients are supported by mapping the new param2 types to existing ones.

Note that param2 handling as well as change detection has been changed to check
param2 type instead of liquid type while keeping the same semantics.
This can be used to force all liquids to the corresponding directional
param2 type, and override their liquid_range and liquid_directed_range
properties.
Draining a node doesn't trigger reflowiing itself even if neighboring flows of
a different kind are present.

This patch fixes this bug only for evaporated directional flows in order to
keep handling of classic liquids unaffected.

TODO: decide whether to apply this fix to all liquids
j-r added 9 commits February 13, 2026 12:56
Classic minetest liquids can only flow into air or floodable nodes, they will
never replace a different liquid kind. Which non directional liquid will flow
into an empty or floodable node solely depends on the geometry.

This breaks naive cobble stone generators.

With this commit a directional liquid will replace another liquid if it can
supply a higher node level. Due to this added interaction between different
liquids, all neighboring flow nodes need to be pushed to the liquid update
queue after a change.

Note that the currently selected liquid kind can now change during the neighbor
loop.
Generalize existing logic handling flowing down neighbors and also apply
it to directional source nodes. This adds the logic to decode direction
from directional param2.

Directional flows with a direction (including flowing down) will only
spread in that direction.

Note that when placing a directional source with param2 == 0 above air it
requires one update cycle for the source to update itself to the flowing
down state, so neighboring nodes will get flooded during this first cycle.
To prevent this, set param2 to 248 when placing the source (which is also
safe if not placed above air, it will then take one cycle to update to the
non flowing down state).
A directional liquid that can flow down will become directional in the down
direction.

A directional liquid that cannot flow down checks whether there are any
neighbors with a direction. It will choose to flow into the first neighbor
whose distance component indicates the shortest path to a flow down if the
resulting path is shorter than liquid_directed_range.

To allow neighboring directional source nodes to pick a direction, too, these
need to be pushed to the update queue on change.
This improves interaction with liquid renewal when e.g. trying to fill a pool
with directional liquid sources, but also provides a generally useful game
mechanic.

Flowing liquid still flows down into corresponding sources.
When inspecting neighbors to determine node corner level don't inspect nodes
above non liquid nodes.

This fix for a minor visual error is only applied to directional flows to
prevent any change to non directional behavior.

TODO: decide whether to apply this fix to non directional flows, too
Flow corners surrounded by air nodes are forced to the lower edge of the node
to visualize a flow turning into air.

For directional flows the number of air nodes required is increased from 2 to 3
to prevent linear flows being rendered flat.

Nother that this still leaves the rendering of directional flows somewhat
suboptimal.

This could also applied to non directional flows, because it only has a very
subtle effect on the outer edges, but the change is restricted to directional
liquids to not introduce any change in existing worlds.

TODO: decide whether to apply this change also to non directional flows
A flow flowing down is visualized as flowing into any neighboring flow of the
same kind even though in the actual physics implementation it only flows down.

This commit changes the visualization of directional liquids to flow into the
waterfall.

Unfortunately the solution in this commit is probably not simple enough for
this minor visual error.

TODO: decide whether this fix is worth it and perhaps apply it to all liquids
…1/16 node

This is an ugly hack.

TODO: find acceptable solution
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants