Musings: Fluid dynamics

Post your ideas and suggestions how to improve the game.

Moderator: ickputzdirwech

Post Reply
galibert
Inserter
Inserter
Posts: 42
Joined: Fri Sep 15, 2017 7:42 am
Contact:

Musings: Fluid dynamics

Post by galibert »

This is a bunch of reflexions on what could be done for better fluids/heat in Factorio. Some aspects are really similar to a post of Rseding91 I found recently and can't find again.

The context: Fluids in Factorio (that's liquids, gas and heat in heat pipes) are currently simulated through a local fluid deynamics-ish simulation of flow. Containers (pipes, tanks) try to equalize the pressure with their neighbours by moving an amount a fluid around. The pressure is defined as the amount of fluid contained in the container divided by the capacity of said container. For instance, a pipe with capacity 20 filled with 10 units of fluid is at equilibrium with a 25K-capacity tank which contains 12500 units of fluid. Pumps take fluid from one side and add it to the other, if there's space, and so do everything using or producing fluids. Update is done per-tick in a single pass and the entities are taken in essentially placement order.

The problems: There are gameplay problems with that system. The main one is that it's very hard to see what's going on. Amount of fluid that can go through a pipeline is extremely dependant on the placement order: in front to back order, a pipe sees added fluid after at least n ticks, where n is the distance to the source, while in back-to-front the fluid propagates through the whole pipe in one tick. Even with the most efficient placement order, the amount going through is inverse exponential with the length of the pipe, and the amount displaced reduces as the pipe fills (less pressure difference). So you need pumps on a regular basis to keep the pressure differencial, but there's no real way to know how often you need pumps. If you have multiple fluid consumers connected to a running pipe the last ones may be somewhat starved but, unlike belts, there's no easy way to see when that happens. And, also unlike belts, there's no easy way to upgrade the piping. So there's a general debuggability/optimizeability problem with piping. A secondary problem, which I personally never encountered, is performance. These are a lot of computations per tick, and they seem to be really noticeable in megabases. It's sad to never see Nuclear power used in megabases just because of that. A final very annoying problem is that when you put the wrong fluid in a pipe network, it's almost impossible to empty it, there's always a near-zero amount lurking in a pipe or two you have to find and remove/replace.

Proposed solution: Drop the fluid dynamics. Create fluid domains which group every connected pipe and tank (and the internal capacity of connected entities, if any) together. Pumps have two different domains on their sides. Each domain has a total capacity, which is the sum of the individual ones, and a total contained amount. A domain can only contain one fluid (or be empty). Pumps, users, producers work the same way, but against the domain instead of the local container, which gives instantaneous transmission of fluids with infinite speed. No more pumps needed except for their basic semantics, which is a one-way active, circuit-controllable valve. Placement order will still matter, but not within the domain. The order in which entities add or remove fluid from the domain will matter, but if inflow equals outflow then after one tick the content level will stabilize (to a not really predictable value) and the flow will be maximal.

Placement/Removal: Placement of a container can merge multiple domains. Removing one can split a domain in multiple parts, or make it disappear entirely. When merging, if there are different fluids the one present in the largest quantity stays and the other(s) is spilled. In case of equality a random but deterministic one is kept (lowest domain id for instance). When splitting a domain the fluid goes into the new domains proportionally to their capacity. What doesn't fit spills. Spilling fluid makes it disappear, and possibly creates pollution in an amount proportional to the fluid quantity.

UI: Hovering over a pipe/tank should give the information for the domain. No scaling to the individual entity, it's way less surprising that way. For a better user experience, the domains should also keep track of some more information. This shouldn't be a performance problem, because there shouldn't be many actual fluid domaines in a base (a half dozen in a normal base, 2-3x that in a megabase, another 2-3x in a A&B mod run, less than a hundred in any case). It should keep track in particular of:
  • underflow and overflow conditions, the first one happens when an entity tries to grab fluid but doesn't have enough, the second when an entity tries to add fluid but there's not enough space. That could then be used for a red/yellow/green color coding
  • mean inflow and outflow (in units/second) over the last 5 seconds or so. It can be bucketized with buckets of roughly half a second, one just has to be careful that addition over floating point values is not associative.[/b]
With that it should be able to see how things are going and whether a problem is looming.

Circuit network: Tanks should give out the total contents of the domain. Multiple connections will then multiply the result, but that's life. People will have to fix that to connect to only one tank per domain, which it not something big.

Possible new entities:
  • Splitter pump: a pump that takes from one domain, and puts half-and-half on two other domains, putting on the other what doesn't fit in one. Useful to split between plastics and acid
  • Overflow pump: a pump that takes from one domain, puts on a second, and if it doesn't fit sends the overflow to a third. Useful to send oil to cracking only when the primary production (lubricant, solid fuel) is backed up
  • Manometer: connects to a domain and reads to the circuit network the contents, capacity and instantaneours flow amounts
  • Fluid spiller: a tool not unlike the repair tool that spills the content of a fluid domain on the floor (up to a given amount per tick?), possibly producing pollution. We may want to require construction bots to have one to remove filled pipes/tanks too, then again maybe not. Very useful when you misconnect something anyway
Well, that's it. The more complex code in there is managing domains, but that's already done in other places with nuances (rail blocks, circuit network, electrical network, optimized belts) so it should theorically be ok. The rest is actually very simple. There's some details here and there (like whether fluid-producing or using entities should have a capacity - yes) but afaict without actually trying nothing major.

Thoughts?

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Musings: Fluid dynamics

Post by bobingabout »

TL;DR, well, I skimmed it, so I'm probably missing a load.
For starters, what Rseding posted isn't a suggestion, that is planned, and will be done.

you say pointing to an entity should tell you the amount of fluid in the entire domain, not that specific entity...
I disagree, it should tell you the fluid in that specific entity, though knowing how much fluid is in the domain would be useful extra information.
Circuit network... well, again, I'd go by the specific entity, but domain wouldn't be a bad option.
The reason I say I'd want things for a specific entity is... you know how much fluid a tank contains, and you'll most likely want a percentile of how full the tank is. 2500 is full, 2000 is 80%, or 2250 is 90%, and that's the level I usually go with. if suddenly the readout starts saying 150000... well, VENT ALL THE GAS!!! because it's above 2250.

That's about it for the moment.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

galibert
Inserter
Inserter
Posts: 42
Joined: Fri Sep 15, 2017 7:42 am
Contact:

Re: Musings: Fluid dynamics

Post by galibert »

bobingabout wrote:you say pointing to an entity should tell you the amount of fluid in the entire domain, not that specific entity...
I disagree, it should tell you the fluid in that specific entity, though knowing how much fluid is in the domain would be useful extra information.
Circuit network... well, again, I'd go by the specific entity, but domain wouldn't be a bad option.
The reason I say I'd want things for a specific entity is... you know how much fluid a tank contains, and you'll most likely want a percentile of how full the tank is. 2500 is full, 2000 is 80%, or 2250 is 90%, and that's the level I usually go with. if suddenly the readout starts saying 150000... well, VENT ALL THE GAS!!! because it's above 2250.
But the truth would be that entities wouldn't be actually holding fluid anymore, only domains. So showing anything else would be very artificial. As for overflow venting, that's why you'd need to be able to read the total capacity. Then it's just a couple of arithmetic combiners (one *100 on current contents, one *-90 on capacity) linked ot the pump for the decider. It's different, but I think not horribly so.

OG.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Musings: Fluid dynamics

Post by eradicator »

[rant]First of all...spilling liquid should never produce pollution. Because that kind of mechanic messes with the "i can remove and place anything i want, any time i want" aspect of factory construction. I've played on a server before that had a mod that added that kind of spill-pollution mechanic alongside mods that made pollution management more important... and it was the most annoying thing i ever experienced. Having to care for every fucking little drop of fluid. [/rant]

I'd say entities should show both individual and domain concent. Ofc the entities own content would just be calulated for the purpose of the tooltip (and only if a tooltip is shown), but it'd be more intuitive for players who don't know about the whole domain thing yet.

Rsed already said that it won't be possible to connect two domains that contain different fluids. For that purpose there's definetly a need for some kind of "make this domain empty NOW" button. Whatever you call it. So the player can chose which of the two to spill.

The splitting pump is something i've wanted for ages. But so far it hasn't happend and so i doubt it will happen any time soon :U. The overflow pump is basically just a combination of a normal pump, a splitting pump and some circuitry. So it's not required.

I definetly like the aspect of including the entities internal fluidboxes into the domain. I'm not sure how rsed was planning to handle that but i sure hope he does it exactly like that. That would give nuclear with it's heaps of connected turbines a really significant boost.

I don't think the domain should keep track of under/overflow or any additional info tho that needs to be calculated seperately. It's supposed to be a major performance improvement, so we might just as well squeeze every little bit out of it that we can get.

For circuitry i'm not sure. Accumulators currently output a value between 100 and 0. So tanks might need that too. Because otherwise you'd have to calculate the individiual value for every (connected) tank every tick and loose half the performance gained. You also can't output the absolute fluid value because that would change every time you add or remove a pipe/machine to the domain. And you don't want your circuits to break every time you add a few machines. Conclusion: either add a gui to chose between "percentage" and "absolute domain content" or just to straight for percentage.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

galibert
Inserter
Inserter
Posts: 42
Joined: Fri Sep 15, 2017 7:42 am
Contact:

Re: Musings: Fluid dynamics

Post by galibert »

eradicator wrote:[rant]First of all...spilling liquid should never produce pollution. Because that kind of mechanic messes with the "i can remove and place anything i want, any time i want" aspect of factory construction. I've played on a server before that had a mod that added that kind of spill-pollution mechanic alongside mods that made pollution management more important... and it was the most annoying thing i ever experienced. Having to care for every fucking little drop of fluid. [/rant]
That mechanic has its limits though, and anybody who tried to move a bunch of filled storage boxes know :-) I don't care either way about the pollution though.
eradicator wrote:I'd say entities should show both individual and domain concent. Ofc the entities own content would just be calulated for the purpose of the tooltip (and only if a tooltip is shown), but it'd be more intuitive for players who don't know about the whole domain thing yet.
I don't know. I've always found it annoying to have no way to know how much <x> I have. Wandering over all the tanks is rather annoying, even more when you add the pipes. Only ever seeing how much <x> I have and how much I can store would have been intuitive when I started, I think.
eradicator wrote:The splitting pump is something i've wanted for ages. But so far it hasn't happend and so i doubt it will happen any time soon :U. The overflow pump is basically just a combination of a normal pump, a splitting pump and some circuitry. So it's not required.
It would be very complicated to do in circuitry, while it's three changed lines of C++ compared to the splitter pump.
eradicator wrote:I don't think the domain should keep track of under/overflow or any additional info tho that needs to be calculated seperately. It's supposed to be a major performance improvement, so we might just as well squeeze every little bit out of it that we can get.
For me it's primarily a gameplay issue, performance is secondary as long as it doesn't get worse (and it would get much better). Giving the tools for the player to know what's going on and detect when it's going wrong is my aim. Only megabase addicts notice the fluid ups impacts. Lots more people notice how opaque they are though. Especially when trying to build a nuclear power station.
eradicator wrote:For circuitry i'm not sure. Accumulators currently output a value between 100 and 0. So tanks might need that too. Because otherwise you'd have to calculate the individiual value for every (connected) tank every tick and loose half the performance gained. You also can't output the absolute fluid value because that would change every time you add or remove a pipe/machine to the domain. And you don't want your circuits to break every time you add a few machines. Conclusion: either add a gui to chose between "percentage" and "absolute domain content" or just to straight for percentage.
You most definitely need a way to read the total capacity, and then your circuitry can adapt easily. You can output it on channel 'C' for instance, the same way train stops can output stuff on specific channels. Percentage is not always what you want, some people may want to do "is there enough to fill a train?" or "give me enough for <n> plastics".

OG.
Last edited by galibert on Thu Nov 09, 2017 10:47 pm, edited 1 time in total.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Musings: Fluid dynamics

Post by eradicator »

galibert wrote:It would be very complicated to do in circuitry, while it's three changed lines of C++ compared to the splitter pump.
Maybe i'm too naive, but it looks to me like one of each splitting pump (hazard concrete), pump, tank and cable would be enough to make an overflow valve.
overflow.jpg
overflow.jpg (55.53 KiB) Viewed 3459 times
galibert wrote:You most definitely need a way to read the total capacity
I agreed on that. I said that reading the individual (relative to the domain) content of each tank would be detrimental to performance. And that having only the total domain content as an output would make circuits annoying. As long as there's some way to chose which value you want, be it multi-output-signals or ["a" or "b"] type output i don't care which it is.
Last edited by eradicator on Fri Nov 10, 2017 4:42 pm, edited 1 time in total.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

JohnyDL
Filter Inserter
Filter Inserter
Posts: 533
Joined: Fri May 16, 2014 3:44 pm
Contact:

Re: Musings: Fluid dynamics

Post by JohnyDL »

You can do an equal splitter relatively easy if you don't need full throughput on the outputs I designed someone a 6 way split

Image

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Musings: Fluid dynamics

Post by bobingabout »

galibert wrote:
bobingabout wrote:you say pointing to an entity should tell you the amount of fluid in the entire domain, not that specific entity...
I disagree, it should tell you the fluid in that specific entity, though knowing how much fluid is in the domain would be useful extra information.
Circuit network... well, again, I'd go by the specific entity, but domain wouldn't be a bad option.
The reason I say I'd want things for a specific entity is... you know how much fluid a tank contains, and you'll most likely want a percentile of how full the tank is. 2500 is full, 2000 is 80%, or 2250 is 90%, and that's the level I usually go with. if suddenly the readout starts saying 150000... well, VENT ALL THE GAS!!! because it's above 2250.
But the truth would be that entities wouldn't be actually holding fluid anymore, only domains. So showing anything else would be very artificial. As for overflow venting, that's why you'd need to be able to read the total capacity. Then it's just a couple of arithmetic combiners (one *100 on current contents, one *-90 on capacity) linked ot the pump for the decider. It's different, but I think not horribly so.

OG.
set up your system with 1 tank.
vent at 2250.

add a tank
Since I still want it to vent at 90%, I have to reconfigure everything so it vents at 4500 instead of 2250.

how do you know that I don't have thousands of entities all over my base checking the level to turn on or off production at certain levels. +1 tank means reconfigure EVERYTHING

This is why I sugest it should tell you how much is in that entity, because adding a tank doubles the capacity, and it therefore vents at this doubled capacity without you having to go reconfigure everything.


I'm not saying it shouldn't tell you how much is in the entire domain, just that it should tell you information about the specific entity you connect it to for situations like this.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Musings: Fluid dynamics

Post by eradicator »

bobingabout wrote: set up your system with 1 tank.
vent at 2250.

add a tank
Since I still want it to vent at 90%, I have to reconfigure everything so it vents at 4500 instead of 2250.

how do you know that I don't have thousands of entities all over my base checking the level to turn on or off production at certain levels. +1 tank means reconfigure EVERYTHING

This is why I sugest it should tell you how much is in that entity, because adding a tank doubles the capacity, and it therefore vents at this doubled capacity without you having to go reconfigure everything.


I'm not saying it shouldn't tell you how much is in the entire domain, just that it should tell you information about the specific entity you connect it to for situations like this.
That's exactly why i said that a "percentage of domain capacity" signal is mandatory for such a system.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

galibert
Inserter
Inserter
Posts: 42
Joined: Fri Sep 15, 2017 7:42 am
Contact:

Re: Musings: Fluid dynamics

Post by galibert »

bobingabout wrote: set up your system with 1 tank.
vent at 2250.
Why? Why not vent at 90% capacity instead? You'll need a couple of arithmetic combiners for that, but I don't see that as a problem...

OG.

Post Reply

Return to “Ideas and Suggestions”