Claim set · data/claims/fluid-network.yaml

Fluid networks across games

Concept: Fluid network.

In BuildCraft 2.2.4 a waterproof pipe stores its own liquid, in seven buffers: one at each of its six sides and one at its center. A buffer accepts liquid only up to a quarter bucket (250 units) plus its flow rate, 270 units in most pipes, and refuses a different liquid while it holds some. Each tick a buffer releases at most its flow rate, 20 units (80 in a golden pipe). Liquid waits in a delay line once after it arrives and again after it is released: written to the slot before the current tick's, it is read five ticks later (one tick later in a golden pipe). Liquid that came in by a side goes on to the center; the center hands it to the sides that lead out; and a side that leads out passes it into the next pipe or, when that pipe takes none, back to its own center, a side refused more than 20 times in a row being treated as an input. What nothing takes stays in the buffer for a later tick. So liquid crosses a line one pipe at a time, never faster than its pipes' flow rate. fluid-network/buildcraft-pipe-buffers

About: BuildCraft Fluid network

Value
{
 "fillLimit": 270,
 "fillLimitGolden": 330,
 "flowRate": 20,
 "flowRateGolden": 80,
 "delayTicks": 5,
 "delayTicksGolden": 1
}
CodeBuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/api/API.java#L22public static final int BUCKET_VOLUME = 1000;BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L31-L34public static int LIQUID_IN_PIPE = API.BUCKET_VOLUME / 4; public int travelDelay = 6; public int flowRate = 20;BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L87-L107if (qty > 0 && this.liquidId != liquidId && this.liquidId != 0) { return 0; } if (this.liquidId != liquidId) { reset (); } this.liquidId = liquidId; int date = (int) (worldObj.getWorldTime() % travelDelay); int newDate = date > 0 ? date - 1 : travelDelay - 1; if (qty + toFill > LIQUID_IN_PIPE + flowRate) { toFill = LIQUID_IN_PIPE + flowRate - qty; } …BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L113-L122int date = (int) (worldObj.getWorldTime() % travelDelay); int newDate = date > 0 ? date - 1 : travelDelay - 1; if (ready - toEmpty < 0) { toEmpty = ready; } ready -= toEmpty; out [newDate] += toEmpty;BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L130-L162int date = (int) (worldObj.getWorldTime() % travelDelay); ready += in [date]; in [date] = 0; if (out [date] != 0) { int extracted = 0; if (orientation < 6) { if (isInput [orientation]) { extracted = center.fill(out [date], true, liquidId); } if (isOutput[orientation]) { Position p = new Position(xCoord, yCoord, zCoord, Orientations.values()[orientation]); p.moveForwards(1); …BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L192-L194qty -= extracted; ready += out[date] - extracted; out[date] = 0;BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L388-L396int [] rndIt = getSplitVector(worldObj); for (int r = 0; r < 6; ++r) { int i = rndIt [r]; side [i].empty(flowRate); } center.empty(flowRate);BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L411-L412if (side [i].bouncing) { isInput [i] = true;BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/pipes/PipeLiquidsGold.java#L20-L21((PipeTransportLiquids) transport).flowRate = 80; ((PipeTransportLiquids) transport).travelDelay = 2;Checked by claude, 2026-10-26 — read PipeTransportLiquids.LiquidBuffer (fill, empty, update) and moveLiquids at the 2.2.4 tag and the golden pipe's constructor

The delay: fill writes to slot (time − 1) mod travelDelay and update adds that slot to ready when time mod travelDelay comes round to it, five ticks later with six slots (one with two); empty does the same for out. The golden pipe sets travelDelay after the buffers are built, so its arrays keep six slots and use two. No pipe at this tag implements IPipeTransportLiquidsHook (L358), so every pipe fills through its side buffer. How many ticks liquid takes to cross one pipe wasn't measured. The center's split among outputs is buildcraft-pipe-split.

Cited by: Fluid network

In BuildCraft 2.2.4 a liquid pipe's center buffer divides what it releases among its outputs: the sides that the pipe leaves open (an iron pipe only the one it points to), that face a pipe or liquid container it connects to, and that liquid didn't come in by. Each output is offered an equal share, rounded up, until the amount runs out, in an order reshuffled every tick by 20 random swaps. If the outputs took less than all of it, the rest is offered once more, split among the outputs not marked full; the test that marks one full compares the total taken so far in the pass, not that output's own amount, with a share, so it can mark full an output that took its whole share and leave unmarked one that took none. A side counts as an input from when liquid enters by it until it has been empty for more than 20 ticks, and every side stops counting as one when the pipe has had no output for more than 20 ticks. fluid-network/buildcraft-pipe-split

About: BuildCraft Fluid network

CodeBuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L164-L189int outputNumber = 0; for (int i = 0; i < 6; ++i) { if (isOutput [i]) { outputNumber++; } } filled = new boolean [] {false, false, false, false, false, false}; // try first, to detect filled outputs extracted = splitLiquid(out [date], outputNumber); if (extracted < out [date]) { outputNumber = 0; // try a second time, if to split the remaining in non …BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L209-L232private int splitLiquid (int quantity, int outputNumber) { int extracted = 0; int slotExtract = (int) Math .ceil(((double) quantity / (double) outputNumber)); int [] splitVector = getSplitVector(worldObj); for (int r = 0; r < 6; ++r) { int toExtract = slotExtract <= quantity ? slotExtract : quantity; int i = splitVector [r]; if (isOutput [i] && !filled [i]) { extracted += side [i].fill(toExtract, true, liquidId); quantity -= toExtract; if (extracted != toExtract) { …BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L355-L356public int fill(Orientations from, int quantity, int id, boolean doFill) { isInput[from.ordinal()] = true;BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L371-L385int outputNumber = computeOutputs (); if (outputNumber == 0) { lockedTime++; } else { lockedTime = 0; } if (lockedTime > 20) { for (int i = 0; i < 6; ++i) { isInput[i] = false; } outputNumber = computeOutputs(); }BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L413-L419} else if (side [i].qty == 0) { side [i].emptyTime++; } if (side [i].emptyTime > 20) { isInput [i] = false; }BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L431-L432isOutput [i] = container.pipe.outputOpen(p.orientation) && canReceiveLiquid(p) && !isInput[i];BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L523-L530for (int i = 0; i < 20; ++i) { int a = worldObj.rand.nextInt(6); int b = worldObj.rand.nextInt(6); int tmp = splitVector [a]; splitVector [a] = splitVector [b]; splitVector [b] = tmp; }BuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeLogicIron.java#L112-L114public boolean outputOpen(Orientations to) { return to.ordinal() == worldObj .getBlockMetadata(xCoord, yCoord, zCoord);Checked by claude, 2026-10-26 — read the center branch of LiquidBuffer.update, splitLiquid, computeOutputs, the input bookkeeping in fill and moveLiquids, getSplitVector, and the iron pipe's outputOpen at the 2.2.4 tag

With no output left unmarked, the second pass divides by zero in doubles; the cast gives a huge share but no side is offered it, so nothing happens. The shuffle is cached per world tick (lastSplit), so every liquid pipe uses the same order in one tick. Whether the marking test is meant to compare the output's own amount isn't stated in the code.

Cited by: Fluid network

BuildCraft 2.2.4 and Factorio before 2.0 both move liquid from pipe to pipe, and split it differently where pipes branch. A BuildCraft pipe offers its outputs equal shares, in an order it reshuffles every tick. In Factorio's old system, by Wube's FFF #416 (2024), the amount going to each side of a junction depended on the order the entities were built, as could a pipe's throughput. In the segment system the same post describes for 2.0, junctions don't matter: a segment answers only to the machines connected to it, each limited by how full the segment is, which the post says splits fluid much more evenly, though not perfectly. fluid-network/junction-splits-compared

Dev blogBuildCraft 2.2.4 source · buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java#L212-L215int slotExtract = (int) Math .ceil(((double) quantity / (double) outputNumber)); int [] splitVector = getSplitVector(worldObj);Friday Facts #416 - Fluids 2.0 · Reaching the breaking pointFurthermore, the throughput can vary depending on the order that the pipes were built.Friday Facts #416 - Fluids 2.0 · JunctionsThe amount of fluid flowing to each side of the junction would be different based on the order that the entities were built.Friday Facts #416 - Fluids 2.0 · JunctionsIn the new system, junctions are entirely unimportant; a segment only cares about the machines connected to it.Friday Facts #416 - Fluids 2.0 · JunctionsThis results in much more even splitting, which while still not perfect, is pretty damn close.Checked by claude, 2026-10-26 — read splitLiquid's share at the 2.2.4 tag and found the four sentences in the pinned FFF #416 capture

Tier 2 because Factorio's side is Wube's description, not code. BuildCraft's even shares can still come out uneven when an output backs up (buildcraft-pipe-split).

Cited by: Fluid network