I'm making a game that is like a mix of many other games (Minecraft, Factorio, Don't Starve, Terraria, etc). I want to make pipes and fluid handling like it works in Factorio. I can't seem to find much information on it. I thought about making fluid even out across all connect pipes with less fluid than this pipe, but the order in which I processed pipes would matter a lot. So, how exactly does Factorio work? I also want pumps, if that changes anything.
I don't know how Factorio does it, but I have a suggestion.
You have an issue with the order in which you process your pipes. One way to remove this issue is to store two sets of pipes in your code.
Set 1: The current frame's fluid values in all sections of the pipe.
Set 2: The next frame's fluid values in all sections of the pipe.
When you are processing your current frame's pipes, store the result in the next frame's pipes. By doing it this way, order does not matter. But after you are finished processing the pipes, you need to swap Set 1 and Set 2, so that the game uses the results and not the old values.
The cost of this would be that storing the pipes would require twice the space. Swapping the sets could be done efficiently by choosing which one to read, not copying one and overwriting the other.
A weakness with this technique is that it might take a long time before fluid moves through a very long pipe. Depending on how 'realistic' you want your game to be, this might be very acceptable. If you want or need fluid to move quickly or to not be compressible, then this problem becomes a different more tricky problem.
You could make pumps by transferring fluid values from one pipe section to a section next to it.
I am assuming your pipes are composed of 'blocks' or individual sections that are connected to each other. And that each section contains a fluid value like liters, pressure or density.
If you do not need to handle viscosity (some liquids flowing faster than others) and are OK with all of them flowing essentially immediately, you could do this:
- Separate your pipe-network into individual sections of connected pipes and reservoirs (pumps would separate the pipeline flowing through them into two individual sections). Calculate the maximum capacity of each section by simply summing up the capacities of all their parts. You only need to recalculate the networks and their capacities when parts are added or removed, not every frame.
- Keep track of the total amount of liquid in each section (producers, consumers and pumps add or remove liquid from the sections they are connected to)
- Calculate the fill-state of each individual cell by simply taking the average fill-state of the whole section. Example: If a section has a total max capacity of 4000l, is currently holding 1000l and you are looking at a pipe section with a max capacity of 10l, it currently contains 2.5l (
10 * 1000/4000)
Problems with this approach:
- It doesn't handle the case of multiple different liquids pouring into the same section. But the way Factorio handles it is not very realistic anyway and the realistic way of doing it (you get a mixture of liquids which might or might not be a useful resource for the player) might not actually be desirable either. You will have to consider for yourself what makes most sense in the context of your game for handling liquids interacting with other liquids.
- As I said before, liquids now flow through pipes with the speed of light. For some games this might be an acceptable break from reality, for others it might not. If you want to do this, you will have to go for the cellular automat approach as described in the answer by No.Manual.