minetest / minetest

Minetest is an open source voxel game-creation platform with easy modding and game creation
https://www.minetest.net/
Other
10.71k stars 2.02k forks source link

Flowing Liquids Should Not Use Param2 For Flow Direction #12897

Open ghost opened 1 year ago

ghost commented 1 year ago

Problem

Flowing liquids currently use param2 for the flow direction. As an example, this makes it impossible to use a colour palette with flowing water, without also messing up the way that the water flows and spreads. This is quite disadvantageous for a game such as MineClone 2.

Solutions

A different method should ideally be used to determine the flow direction of liquids, one that still allows for the use of a colour palette with the flowing liquid.

TurkeyMcMac commented 1 year ago

There's nowhere else to store this information. However, it seems like only the lower 4 bits of param2 are used, so a paramtype2 could be added "colorflowingliquid". This would allow for liquid of 16 different colors, but the color would not be preserved through liquid flow.

wsor4035 commented 1 year ago

(didnt double check this), but the flowing using param2 is beneficial for those looking to get the level, etc as some mods and games do. this issue is sorta a duplicate to a degree of https://github.com/minetest/minetest/issues/11019, https://github.com/minetest/minetest/issues/6979, and https://github.com/minetest/minetest/issues/6663. i cant seem to find a current open issue that advocates for moving hardware coloring to be its own thing/param3/etc.

ghost commented 1 year ago

This would allow for liquid of 16 different colors, but the color would not be preserved through liquid flow.

What a shame, but I guess it is better than what we currently have, which is either colourless water, or water that is only one specific colour.

I do hope that the development team one day finds a way to have flowing water use something else, while still allowing for way more colours to be chosen from.

TurkeyMcMac commented 1 year ago

If colorflowingliquid existed, you could probably add the color in with minetest.register_on_liquid_transformed, though it would be a lot slower.

Wuzzy2 commented 1 year ago

If colorflowingliquid existed by using the upper 4 bits for color and the lower 4 bits for flowing info (or whatever the number of bits used for flowing currently is), I don't think this is a problem. The engine just needs to be taught to never zero-out the top 4 bits.

That could be done by only ever looking and changing the lower 4 bits (the "flow" bits) when flowing and never touch the top 4 bits. That way, mods can use the top 4 bits freely (even for stuff other than color).

I am not sure if removing the flow information completely from flowingliquids is even possible. Doesn't the engine need this?

By the way, the issue title is incorrect. param2 does not store "flow direction", but actually the liquid level (bits 0-2) and whether the liquid flows downwards (bit 3). I think the liquid level is needed to Minetest so it knows how "full" a flowingliquid node is. This is important for viscosity and when the liquid drains out.

TurkeyMcMac commented 1 year ago

I tried implementing this, and I wonder if the upper 4 bits should be propagated by liquid flow. This would let color be preserved throughout a flowing body of water.

I believe Minecraft's water color depends on the biome. Would MineClone follow this, instead of basing water color on provenance? It could probably be accomplished with minetest.register_on_liquid_transformed, but it would be expensive.

Desour commented 1 year ago

Making color spread correctly sounds very complicated, because you have to decide how two same liquids with different colors interact. The easiest solution is to treat them as different liquids, but you probably don't want this, if you just want differently styled water.

AFAIK, it wouldn't be too hard to add biome based node tile coloring, if that is what you really want to achieve. You'd just have to specify how to store biome colors. Maybe a simple grid with colors at mapblock corners would suffice? (And then interpolate colors trilinearly for each node.)

ghost commented 1 year ago

how two same liquids with different colors interact.

It's the same liquid, so nothing weird could really happen. Besides, you cannot bring water from one ocean biome to another ocean biome, as the liquid changes "temperature" the moment it crosses the border between the ocean biomes.

ghost commented 1 year ago

but it would be expensive.

How much more expensive are we talking about here?

TurkeyMcMac commented 1 year ago

but it would be expensive.

How much more expensive are we talking about here?

You would have to run some Lua code for every liquid node that changed, checking the biome for each node.

Desour commented 1 year ago

how two same liquids with different colors interact.

It's the same liquid, so nothing weird could really happen.

I don't know what you assume on how color should spread when liquid flows.

ghost commented 1 year ago

I don't know what you assume on how color should spread when liquid flows.

I do not understand your reply. What did you mean by this? Please elaborate.

If you want, could you explain more about this biome based node tile coloring that you spoke about earlier? What's the difference between your method and TurkeyMcMac's method? Is your method better?

Desour commented 1 year ago

I don't know what you assume on how color should spread when liquid flows.

I do not understand your reply. What did you mean by this? Please elaborate.

If you have for example a red water liquid source, one could expect that when it flows, the flowing water also is red (in general: the param2 bits used for coloring spread when it flows). Not spreading the color would of course also be possible. But I'm not sure whether your feature request includes color spreading (and if yes, in what form).


If you want, could you explain more about this biome based node tile coloring that you spoke about earlier? What's the difference between your method and TurkeyMcMac's method? Is your method better?

My idea was to add a biome based node coloring feature to minetest, by adding a coarse grid of colors to the world, and using these colors to color the nodes, not param2. One could for example store at each corner of each mapblock a color value, which can be set using the lua api. (Maybe allow to make the grid more dense in some mapblocks.) Then on mapblock meshgen, set vertex colors by interpolating between all nearby color values.

ghost commented 1 year ago

If you have for example a red water liquid source, one could expect that when it flows, the flowing water also is red (in general: the param2 bits used for coloring spread when it flows). Not spreading the color would of course also be possible. But I'm not sure whether your feature request includes color spreading (and if yes, in what form).

This still confuses me. I get the feeling that I need some sort of drawing or sketch in order to understand the difference between the two.

In any case, if what I think you mean is correct, I don't think my feature request includes colour spreading. I think that the water colour should be that which the biome it is currently located in tells it to be. If that's your definition of not spreading the colour.

My idea was to add a biome based node coloring feature to minetest, by adding a coarse grid of colors to the world, and using these colors to color the nodes, not param2. One could for example store at each corner of each mapblock a color value, which can be set using the lua api. (Maybe allow to make the grid more dense in some mapblocks.) Then on mapblock meshgen, set vertex colors by interpolating between all nearby color values.

Sounds interesting, but would it still be possible for texture packs to change said colour values? The advantage of using param2 with a colour palette is that texture packs are able to replace the colour palette with their own.

Wuzzy2 commented 1 year ago

To answer the question of when to propagate the color: Whenever a liquid spawns a new node due to flowing, the "color" bits from the origin node are copied towards the new node. That's it. Existing liquid nodes are not changing their color. There is no color mixing.

This solution seems the cheapest one, you're literally just copying 4 bits of param2 towards the newly spawned node. Performance impact should be minimal and this seems the most reasonable interpretation of "propagating color".

ghost commented 1 year ago

Makes sense, but how would the alternative of not having the colour propagate from the origin block, but still have the flowing water be coloured work? Just curious.

Also, how does the game remember what colour the water was once you scoop it up in a bucket? How will it prevent from forgetting what colour water it contains?

Desour commented 1 year ago

Makes sense, but how would the alternative of not having the colour propagate from the origin block, but still have the flowing water be coloured work? Just curious.

You could always set the color bits to 0 on flow and require the mod to set the bits in an minetest.register_on_liquid_transformed callback, as TurkeyMcMac already said.

Also, how does the game remember what colour the water was once you scoop it up in a bucket? How will it prevent from forgetting what colour water it contains?

The same way as when you dig a node with param2 color: Store it in item meta.

Sounds interesting, but would it still be possible for texture packs to change said colour values? The advantage of using param2 with a colour palette is that texture packs are able to replace the colour palette with their own.

Depends on the implementation details, but probably not. Anyway, non-param2 biome colors would be a big new (and separate) feature. You'd need to find someone to implement it and someone to approve, which is hard. Sorry for going a bit offtopic.

ghost commented 1 year ago

I think the best solution right now would just be a colorflowingliquid like previously mentioned. The flowing water checks which biome it is located in on generation with minetest.register_on_liquid_transformed, and then uses the water colour for that biome (which the biome gets from a colour palette image).

The only two issues that I see with this, are the following:

But to those things, I have the following counterarguments:

I also find this the best solution for the following reasons:

If I misunderstood anything, then please do tell me.