Using this technique I can build a precision fluid splitter, which has multiple tanks of different fluid types, and on receiving a signal can distribute a fixed amount of fluid to each of the parallel tanks using either round robin or parallel push. Without mods, this fixed value is either 100 or 200, depending on whether the input side of the pump faces a full single pipe segment or another pipe/tank respectively. With just one mod, the crafting combinators mod (which I happen to be using anyway to utilise the precision fluid routing/splitting), I can get the better precision with the smallest unit of fluid I can transfer being twice of any single recipe's cost, with some caveats in speed due to crafting combinator delays. And if I use barrels with this crafting combinator technique, I can transport exactly 10 units of fluid at a time. When crafting combinators are added to the base game according to FFF 394, I think the performance caveats will mostly disappear, although I'm not sure if it will be as fully featured as xeraph's fork crafting combinators mod with a recipe combinator and the find uses/find machines and vary input count features, etc. So in that sense I'm "planning ahead" for this technique to be vanilla.
So, the idea. Occam's razor fails. Nixie tubes are used in order to see rounded down fluid counts which hovering over the container won't display. It's not currently possible to measure fluid inside an assembler, but even if I put two assemblers next to each other I find this rounding error still happens sometimes. Not often, but often enough to cause problems with automation.
Why does it break? This works, why does it work? There are three issues, none of them immediately obvious:
- The first is if a pump output is facing a tank (NOT an assembler/chemplant/etc, specifically just tanks) and its fluid storage is 40% or higher, the pump won't push a full 200 fluid each tick, usually around 199 but it varies by a few decimals. - The second issue is that fluid sloshes in between long pipe segments. Even a pipe segment of two tiles gets this sloshing, and sometimes when small amounts of fluid slosh they are "forgotten" about by the fluid network until fluid is sent through that pipe again. While "forgotten", pumps won't pull this leftover sloshed liquid. I assume this is an intentional optimisation to make fluid not slosh endlessly, but the challenge is how to override this behavior for specialised setups. - The third issue is if a pump is right next to two tanks, then factorio optimises the three components as a single fluid network, and this optimised behavior involves leaving over trace leftover amounts. The trick is to get factorio to recognise two separate fluid networks so this optimisation doesn't happen.
For the first issue, just make sure that all storage tanks never go above 40% (or 10k) fluid. Easy to set this condition on the adjacent pump with no combinators.
For the second issue, it's relatively simple - don't have any pipe segments of more than two tiles without pumps in between. Sounds annoying, but it's not as bad as it sounds in practice.
For the third issue, it was mostly trial and error, but I found four pumps and three fluid pipes was the minimum to trick factorio into treating the input and output tanks as two separate fluid networks. If you want more than 10k total fluid storage, I thought initially I'd need four pumps in between each 10k tank, but it turned out I could have just one pump in between the storage tanks and it worked fine. More specifically, three pipe-pump tiles after the pump with the circuit condition. Again, no way to really know for sure without seeing source code. (Don't forget to hook up all pumps with their output facing a tank, to the 10k storage cutoff.) Keep in mind, the first pump in this four pump-pipe chain needs to be active for exactly one tick only - for the precision fluid splitter, you need a "buffer" pump to store the 200 units being sent to it in that iteration, which is why there are five pumps per parallel slice in that blueprint. For this to work, it's important that the fuel unloading is done in tick pulses. If you go too fast, then the intermediate pipes won't catch up and so not all pumps will work at exactly 200 fluid/tick. I found with a pulse former I was able to do 2 tick pulses 100% of the time to transfer 400 fluid on the one tank setup, but it broke the 10k fluid stopping condition. There may be a way around this, but I am finding 200 tick pulses satisfactory for my throughput needs for the time being.
The next important question, is the minimum number of ticks between pulses. In other words, how many ticks in the worst case may it take for one pipe plus one pump to shuffle all the liquid down. In the example without fluid splitting this is 6. The formula for number of ticks needed, signal U in my blueprints, is the number of pipes in the longest chain in the network, plus three. Based on this, I come to the conclusion it takes exactly four ticks for a pipe+pump segment to fully move 200 units of fluid along to the next segment. Of course, with multiple channels of different fluid types along the same row of pipes, the delay needs to be a bit longer due to the longer chain of pumps.
Splitting precise fluids
For the six channel splitter, the overall throughput with the tank on the same row as the main buffer, is 200/15 = 13.33 fluid/tick, or 200/(15*6) = 2.22 fluid/tick for each channel. The number of different fluids increases the maximum chain length, but you can use a separate combinator row per fluid type so that not all combinators are impacted by the increased tick delay due to higher chain length. While this may sound slow on paper, keep in mind that the buffer tank/s on the input side can have an unlimited throughput input rate for storage. Also, the highest liquid consuming rate in vanilla is a chemplant is sulfuric acid, with 100 water every second without beacons, or 100/60 = 1.67 fluid/tick, so this splitting method meets throughput even for the highest vanilla consumer.Actually, in my design I made a modulo clock pulser that spends one clock cycle resetting, so it's a small bit slower in practice, I'm just not sure of a good combinator design to modulo pulse without the reset clock cycle. Increasing the parallel number and adding rows further down will both increase the chain length, but it's easy to figure out what the throughput would be with the equation known. Simple answer, keep water in the first row, followed by oil if you choose to use such a splitter setup for generic oil processing (which I plan to be posting about in a separate thread soon!).
In practice, the disadvantages are having to use the extra pumps, space for combinators to pulse the signal, and that you can only use each tank for 10k fluid or 40% of their normal capacity. Overall I find this an acceptable tradeoff, also pointing out that multiple setups can share the same modulo clock pulser.
For the splitter, if you don't want to share fluid types via the same pump, there is a more efficient setup runs with just a clock pulser carefully timed to refill all the buffer pumps before each pulse (as shown below). In this case, all pumps can push every 11 ticks, so total fluid distributed for the example six channel splitter is (200*6)/11=109.09 fluid/tick, or 18.18 fluid/tick for each channel. I have this in the blueprint, I don't think it is that useful though.
How Low Can You Go?
Just for the sake of it, what's the smallest precise fluid amount I can pull out? Here are two setups, both using the crafting combinator: Getting 10 fluid in a tank was more of a technical challenge than serving any useful purpose - at least currently, but maybe in future if a mod makes some machines get overflow penalties, this could be useful. The trick to making this work is ensuring the chemplant never receives power, so it won't start the recipe, and when the crafting combinator unsets the recipe the leftover fluid is dumped back into the adjacent input tank. In other words, the chemplant for a lubricant recipe can only hold 20 fluid input, so all that's left to do is solve this simplified "water pouring puzzle" (https://en.wikipedia.org/wiki/Water_pouring_puzzle). I spent a while trying to do it with fluid detection, but I found that I'd need quite a few buffer tanks for the detection which makes the setup dramatically bigger. So I elected to go with manually calibrated delay lines specifically for the heavy oil -> lubricant recipe, the timings aren't optimised and it still takes up a decent amount of space, and the crafting combinator takes about 2 seconds to set or unset recipes which is the main time bottleneck. Due to relying on crafting combinator timing estimates, this is the only blueprint that's UPS sensitive.The algorithm is:
- unbarrel 50 fluid and deposit into a tank facing a chemplant, deposit 20 into the chemplant.
- store the 30 leftover in an intermediate buffer (in my solution, a pump buffer rather than a tank buffer. Keep in mind you can't read pump internal storage with signals.)
- remove 20 deposited into chemplant back into the input buffer
- deposit 30 back into the chemplant facing tank, deposit 20 into the chemplant again
- send the 10 leftover to the output and the 20 in the chemplant back to the input buffer a second time.
It's definitely possible to build a "generic" version of this setup to minimise the fluid count of any recipe, but it'd require more combinators, doing some math on the selected recipe capacity and the minimum fluid stack size that can be obtained. With recipe combinators these calculations can all be done automatically. Given the poor performance and complexity of this design, I think it's easier to just calculate LCM(x, 100) or LCM(x, 200) of how much fluid a recipe needs and scale up its crafts with combinator logic rather than subdividing fluid amounts like this.
Curious determinism
I found that fluid sloshing was not as probabilistic as I'd expected. Repeating this setup I found there was very little variation in the split outputs, which I also found were affected by chunk alignment: Nturally, all of these lead to the dreaded fluid rounding errors, meaning they can't be used for precise splitting even assuming they are fully deterministic 100% of the time. I don't think it's worth reverse engineering the fluid code any more...Blueprint
The blueprints use the nixie tubes, blueprint sandboxes and pushbutton mods. All just for ease of use in testing, of course. When making it I used the map editor to do step through ticks.Also, I should mention, this is my first post but I've been lurking on these forums for a few months, I'm just a bit shy