On this page
  1. Pipe to pipe and merged
  2. Across games
  3. Quirks
  4. History
  5. Related
  6. Games
  7. References
  8. Sources

A fluid network carries a liquid or gas through connected pipes from where it is pumped or made to the machines that use it. The games here either pass the fluid from pipe to pipe, so it takes time to cross a line and every pipe limits the rate, or merge connected pipes into one unit whose fluid every outlet can draw on at once1,2,3.

  • Pipe to pipeBuildCraft (2011). Waterproof pipes keep liquid in buffers at each side and the center, passing at most 20 units a tick (80 in a golden pipe) from buffer to buffer and pipe to pipe.1,4,5,6
  • Merged segmentThermal Expansion (2012). Thermal Dynamics merges connected fluiducts into one grid with one tank, and every outlet duct draws on it.7,2,8,9Factorio (2016). Since 2.0, connected pipes and tanks form one segment holding one fluid, and pumps split segments; before, fluid flowed from pipe to pipe.3,10,11,12

#Pipe to pipe and merged

In BuildCraft 2.2.4 each waterproof pipe holds its own liquid, in a buffer at each of its six sides and one at its center1. Liquid that enters by a side moves to the center, the center deals it out to the sides that lead on, and each of those passes it into the next pipe1. Every buffer releases at most 201 units a tick, and the liquid waits in a delay line at every step, so a line fills one pipe at a time and carries no more than its pipes pass1. Factorio’s fluids also moved from pipe to pipe until 2.0, and Wube’s posts say throughput there fell as pipes got longer3.

Thermal Dynamics, the duct mod split from Thermal Expansion, merges connected fluiducts into one grid that holds one fluid7. The grid keeps that fluid in one tank, sized by its duct count, and fluid put into any duct goes straight into the tank2. Every duct beside a machine draws on the same tank each tick, so fluid never travels along the grid8. Factorio 2.0’s segments work the same way by Wube’s description: pipes, underground pipes, and storage tanks form one segment holding one fluid, fluid pushed in is available at once anywhere along it, and a pump splits one segment from the next3.

A merged network still limits its rate, by how full its store is. A Thermal Dynamics outlet duct hands out between half and all of the fluid’s throughput, more as the tank fills8. Factorio 2.0 caps each transfer at 1003 units and scales it by how full both the source and the sink are3. Thermal Dynamics has no counterpart to that fixed cap or to the scaling by the sink13.

#Across games

Game and versionWhere the fluid isHow it moves inside the networkRate limit
BuildCraft 2.2.4seven buffers in each pipe1buffer to buffer and pipe to pipe, through a delay line at each step1201 units a tick per buffer, 801 in a golden pipe1
Factorio before 2.0in each pipe3pipe to pipe3throughput fell with pipe length and could depend on the order pipes were built3,12
Thermal Dynamics r2.3.9one tank per grid2it doesn’t: every outlet draws on the tank8each outlet from half to all of the fluid’s throughput, by the tank’s fill8
Factorio 2.0one store per segment3it doesn’t: fluid pushed in is available anywhere along the segment31003 units per transfer, scaled by the fill of source and sink3

#Quirks

  • A BuildCraft 2.2.4 pipe offers its outputs equal shares in an order reshuffled every tick, but the test that marks an output full checks the running total instead of that output’s own amount, so a second offer of the leftover can skip an output that took its whole share and go to one that took none4.
  • In Factorio’s pipe-to-pipe system, the fluid going to each side of a junction depended on the order the pipes were built; in the 2.0 segments junctions don’t matter12.
  • Factorio’s merged pipelines had to end somewhere. When Wube added a limit to a Factorio pipeline’s extent in 2024, a pipeline that overran it stopped all flow until a pump split it10. In the same 2024 post Wube cut the pump’s rate to a tenth11.
  • A Thermal Dynamics duct placed between grids of different fluids closes its sides to every neighbour whose fluid differs from the one it picked, so the grids stay apart7. Breaking a grid apart divides its tank equally among its ducts, which carry their shares into the grids they join next9.

#History

BuildCraft 2.1.0 (2011) added liquid pipes and pumps, by the account of asie, a later maintainer14. Its 2.2.4 tag of October 2011 has five waterproof pipes, each made from a transport pipe and a pipe sealant5.

By Team CoFH’s account, Thermal Expansion began as a BuildCraft addon15. Its 2.1.0 update added Liquiducts, ducts for fluids, by a note captured on 2 January 201316. Thermal Expansion 3’s fluid ducts were the Fluiducts17, and 4.0.0 moved the ducts into Thermal Dynamics18. No source links the ducts’ design to BuildCraft’s pipes, so the two are compared here, not traced one from the other. Thermal Expansion’s CurseForge description says its fluid system is now part of Minecraft Forge, a statement Forge’s documentation makes only for the energy system19.

For Factorio 2.0, Wube’s FFF #416 (2024) says Rseding proposed an algorithm “very close to” one from Thermal Expansion, in which pipes, underground pipes, and storage tanks merge into segments20. The post doesn’t say how much of the mod’s design Factorio kept. The system it goes on to describe merges segments as Thermal Dynamics merges grids, but limits rates differently13.

Conveyor belts and BuildCraft’s transport pipes carry items instead, each item an object that travels along the line21.

:::gap{internal}[Earlier duct code] Thermal Dynamics r2.3.9 is the only duct code read. Thermal Expansion 2’s Liquiducts, Thermal Expansion 3’s Fluiducts, and the 1.7.10 Thermal Dynamics branch, which has classes named FluidGrid and FluidTankGrid, would date the merged grid. Later BuildCraft versions’ liquid pipes aren’t read either. :::

Games

GameYearHowNote
BuildCraft2011Pipe to pipewaterproof pipes keep liquid in buffers at each side and the center, passing at most 20 units a tick (80 in a golden pipe) from buffer to buffer and pipe to pipe
Thermal Expansion2012Merged segmentThermal Dynamics merges connected fluiducts into one grid with one tank, and every outlet duct draws on it
Factorio2016Merged segmentsince 2.0, connected pipes and tanks form one segment holding one fluid, and pumps split segments; before, fluid flowed from pipe to pipe
Every claim about this mechanic, by game (3)
BuildCraft 2011In 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.Code
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.Code
generalBuildCraft 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.Dev blog

References

  1. ^ abcdefghijkIn 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.CodeBuildCraft 2.2.4revised
    How we know
    22	public static final int BUCKET_VOLUME = 1000;
    
    buildcraft/common/net/minecraft/src/buildcraft/api/API.java line 22 at 0a20887 · upstream ↗
    31	public static int LIQUID_IN_PIPE = API.BUCKET_VOLUME / 4;
    ⋮
    33	public int travelDelay = 6;	
    34	public int flowRate = 20;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 31–34 at 0a20887 · upstream ↗
    87			if (qty > 0 && this.liquidId != liquidId && this.liquidId != 0) {
    88				return 0;
    ⋮
    91			if (this.liquidId != liquidId) {
    92				reset ();
    ⋮
    95			this.liquidId = liquidId;
    ⋮
    97			int date = (int) (worldObj.getWorldTime() % travelDelay);
    98			int newDate = date > 0 ? date - 1 : travelDelay - 1;
    ⋮
    100			if (qty + toFill > LIQUID_IN_PIPE + flowRate) {
    101				toFill = LIQUID_IN_PIPE + flowRate - qty;
    ⋮
    104			if (doFill) {
    105				qty += toFill;			
    106				in [newDate] += toFill;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 87–107 at 0a20887 · upstream ↗
    113			int date = (int) (worldObj.getWorldTime() % travelDelay);
    114			int newDate = date > 0 ? date - 1 : travelDelay - 1;
    ⋮
    116			if (ready - toEmpty < 0) {
    117				toEmpty = ready;
    ⋮
    120			ready -= toEmpty;
    ⋮
    122			out [newDate] += toEmpty;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 113–122 at 0a20887 · upstream ↗
    130			int date = (int) (worldObj.getWorldTime() % travelDelay);
    ⋮
    132			ready += in [date];
    133			in [date] = 0;
    ⋮
    135			if (out [date] != 0) {
    136				int extracted = 0;
    ⋮
    138				if (orientation < 6) {
    139					if (isInput [orientation]) {
    140						extracted = center.fill(out [date], true, liquidId);
    141					} if (isOutput[orientation]) {
    142						Position p = new Position(xCoord, yCoord, zCoord,
    143								Orientations.values()[orientation]);
    144						p.moveForwards(1);
    ⋮
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 130–162 at 0a20887 · upstream ↗
    192				qty -= extracted;
    193				ready += out[date] - extracted;
    194				out[date] = 0;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 192–194 at 0a20887 · upstream ↗
    388		int [] rndIt = getSplitVector(worldObj);
    ⋮
    390		for (int r = 0; r < 6; ++r) {
    391			int i = rndIt [r];
    ⋮
    393			side [i].empty(flowRate);
    ⋮
    396		center.empty(flowRate);
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 388–396 at 0a20887 · upstream ↗
    411			if (side [i].bouncing) {
    412				isInput [i] = true;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 411–412 at 0a20887 · upstream ↗
    20		((PipeTransportLiquids) transport).flowRate = 80;
    21		((PipeTransportLiquids) transport).travelDelay = 2;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/pipes/PipeLiquidsGold.java lines 20–21 at 0a20887 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Revised after a check by a second AI model, 2026-10-26.

    In the claim ledger

  2. ^ abcdIn Thermal Dynamics r2.3.9 a fluid-duct grid stores its fluid in one tank, not in its ducts. The tank holds the grid's duct count times a per-duct volume, which for ordinary fluiducts is 25 times the fluid's throughput, at most 3,000 mB. The throughput is 120,000 divided by the fluid's viscosity (taken as at least 100), clamped to 80-600 mB a tick; steam is set to 600. A fluid of viscosity 1,000 gets 120 mB a tick and 3,000 mB a duct, the tank's defaults. Fluid of the grid's kind put into any open side of any duct goes straight into that tank, up to its free space, with no other limit on the rate.CodeThermal Dynamics r2.3.9 · CoFH Core r4.3.9
    How we know
    27	public final FluidTankGrid myTank = new FluidTankGrid(1000, this);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java line 27 at 5ae9f68 · upstream ↗
    81	public void balanceGrid() {
    ⋮
    84		myTank.setCapacity(size() * myTank.fluidPerDuct);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 80–85 at 5ae9f68 · upstream ↗
    135	public float getThroughPutModifier() {
    ⋮
    137		return 1.0F;
    ⋮
    140	public int getMaxFluidPerDuct() {
    ⋮
    142		return 3000;
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 135–143 at 5ae9f68 · upstream ↗
    10	public int fluidThroughput = 120;
    11	public int fluidPerDuct = 3000;
    ⋮
    16		fluidFlowrate.put("steam", 600);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/FluidTankGrid.java lines 10–17 at 5ae9f68 · upstream ↗
    58			viscosity = Math.max(fluid.getFluid().getViscosity(), 100);
    59			fluidThroughput = MathHelper.clamp(120000 / viscosity, 80, 600);
    ⋮
    62				fluidThroughput = fluidFlowrate.get(fluid.getFluid().getName());
    ⋮
    64			fluidThroughput *= myMaster.getThroughPutModifier();
    65			fluidPerDuct = Math.min(25 * fluidThroughput, myMaster.getMaxFluidPerDuct());
    
    src/main/java/cofh/thermaldynamics/duct/fluid/FluidTankGrid.java lines 53–68 at 5ae9f68 · upstream ↗
    489			public int fill(FluidStack resource, boolean doFill) {
    ⋮
    491				if (resource != null && isOpen(from) && matchesFilter(from, resource)) {
    492					return grid.myTank.fill(resource, doFill);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/DuctUnitFluid.java lines 489–494 at 5ae9f68 · upstream ↗
    190		if (!fluid.isFluidEqual(resource)) {
    191			return 0;
    ⋮
    193		int filled = capacity - fluid.amount;
    ⋮
    195		if (resource.amount < filled) {
    196			fluid.amount += resource.amount;
    ⋮
    199			fluid.amount = capacity;
    
    src/main/java/cofh/core/fluid/FluidTankCore.java lines 186–201 at ccf809a · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  3. ^ abcdefghijklmWube's FFF #416 and #430 (2024) describe 2.0's fluids: connected pipes, underground pipes and storage tanks form one segment holding one fluid, and a pump splits one segment from the next. Fluid put into a segment is available at once anywhere along it: there is no flow from pipe to pipe, so pipe length and junctions no longer cut throughput as they did in 1.x. Each transfer is capped at 100 units (6,000 a second) and scaled by how full the source and the sink are, so a machine pushing in slows as the segment fills. These rules are the posts'; they weren't re-checked against 2.1.23.Dev blogFriday Facts #416 · Friday Facts #430revised
    How we know
    Pipes, underground pipes, and storage tanks are merged into fluid "segments". … There is no longer a realistic fluid "flow" through pipes; fluid pushed to a segment will be immediately available at any point along a segment. … In the old system, throughput would get worse as pipes got longer. … In the new system, junctions are entirely unimportant; a segment only cares about the machines connected to it.
    Fluids 2.0 · archived copy ↗
    You can split a pipeline using a pump.
    Pipeline extents · archived copy ↗
    Output rate used to be unlimited, but it is now inversely proportional to the fullness ratio of the sink. … there is a hardcoded limit of 100 fluid per flow operation (6000/s). … This limit is multiplied with the fullness ratios of the source and sink to produce the actual flow value
    Algorithm tweaks · archived copy ↗

    The quote matches our archived copy.

    Revised after a check by a second AI model, 2026-10-26.

    In the claim ledger

  4. ^ abIn 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.CodeBuildCraft 2.2.4
    How we know
    164					int outputNumber = 0;
    ⋮
    166					for (int i = 0; i < 6; ++i) {
    167						if (isOutput [i]) {
    168							outputNumber++;
    ⋮
    172					filled = new boolean [] {false, false, false, false, false, false};
    ⋮
    174					// try first, to detect filled outputs
    175					extracted = splitLiquid(out [date], outputNumber);
    ⋮
    177					if (extracted < out [date]) {
    178						outputNumber = 0;
    ⋮
    180						// try a second time, if to split the remaining in non
    181						// filled if any
    182						for (int i = 0; i < 6; ++i) {
    ⋮
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 164–189 at 0a20887 · upstream ↗
    209		private int splitLiquid (int quantity, int outputNumber) {
    210			int extracted = 0;
    ⋮
    212			int slotExtract = (int) Math
    213			.ceil(((double) quantity / (double) outputNumber));
    ⋮
    215			int [] splitVector = getSplitVector(worldObj);
    ⋮
    217			for (int r = 0; r < 6; ++r) {
    218				int toExtract = slotExtract <= quantity ? slotExtract : quantity;				
    ⋮
    220				int i = splitVector [r];
    ⋮
    222				if (isOutput [i] && !filled [i]) {
    223					extracted += side [i].fill(toExtract, true, liquidId);
    224					quantity -= toExtract;
    ⋮
    226					if (extracted != toExtract) {
    ⋮
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 209–232 at 0a20887 · upstream ↗
    355	public int fill(Orientations from, int quantity, int id, boolean doFill) {
    356		isInput[from.ordinal()] = true;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 355–356 at 0a20887 · upstream ↗
    371		int outputNumber = computeOutputs ();
    ⋮
    373		if (outputNumber == 0) {
    374			lockedTime++;
    375		} else {
    376			lockedTime = 0;
    ⋮
    379		if (lockedTime > 20) {
    380			for (int i = 0; i < 6; ++i) {
    381				isInput[i] = false;				
    ⋮
    384			outputNumber = computeOutputs();
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 371–385 at 0a20887 · upstream ↗
    413			} else if (side [i].qty == 0) {
    414				side [i].emptyTime++;				
    ⋮
    417			if (side [i].emptyTime > 20) {
    418				isInput [i] = false;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 413–419 at 0a20887 · upstream ↗
    431			isOutput [i] = container.pipe.outputOpen(p.orientation)
    432					&& canReceiveLiquid(p) && !isInput[i];
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 431–432 at 0a20887 · upstream ↗
    523		for (int i = 0; i < 20; ++i) {
    524			int a = worldObj.rand.nextInt(6);
    525			int b = worldObj.rand.nextInt(6);
    ⋮
    527			int tmp = splitVector [a];
    528			splitVector [a] = splitVector [b];
    529			splitVector [b] = tmp;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 523–530 at 0a20887 · upstream ↗
    112	public boolean outputOpen(Orientations to) {
    113		return to.ordinal() == worldObj
    114				.getBlockMetadata(xCoord, yCoord, zCoord);
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeLogicIron.java lines 112–114 at 0a20887 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  5. ^ abBuildCraft 2.2.4 (October 2011) has three families of pipe. Seven transport pipes carry items (wooden, cobblestone, stone, iron, golden, diamond, obsidian); five waterproof pipes carry liquids and are made from a transport pipe of the same material and a pipe sealant made of green dye; three conductive pipes carry energy and are made from a transport pipe and redstone.CodeBuildCraft 2.2.4
    How we know
    115		CoreProxy.addName(pipeWaterproof, "Pipe Waterproof");
    ⋮
    118			Character.valueOf('W'), new ItemStack(Item.dyePowder, 1, 2)});
    
    buildcraft/common/net/minecraft/src/BuildCraftTransport.java lines 113–118 at 0a20887 · upstream ↗
    124		pipeItemsWood = createPipe (DefaultProps.PIPE_ITEMS_WOOD_ID, PipeItemsWood.class, "Wooden Transport Pipe", Block.planks, Block.glass, Block.planks);
    ⋮
    130		pipeItemsObsidian = createPipe (DefaultProps.PIPE_ITEMS_OBSIDIAN_ID, PipeItemsObsidian.class, "Obsidian Transport Pipe", Block.obsidian, Block.glass, Block.obsidian);
    ⋮
    132		pipeLiquidsWood = createPipe (DefaultProps.PIPE_LIQUIDS_WOOD_ID, PipeLiquidsWood.class, "Wooden Waterproof Pipe", pipeWaterproof, pipeItemsWood, null);
    ⋮
    136		pipeLiquidsGold = createPipe (DefaultProps.PIPE_LIQUIDS_GOLD_ID, PipeLiquidsGold.class, "Golden Waterproof Pipe", pipeWaterproof, pipeItemsGold, null);			
    ⋮
    140		pipePowerWood = createPipe (DefaultProps.PIPE_POWER_WOOD_ID, PipePowerWood.class, "Wooden Conductive Pipe", Item.redstone,  pipeItemsWood, null);		
    ⋮
    144		pipePowerGold = createPipe(DefaultProps.PIPE_POWER_GOLD_ID, PipePowerGold.class, "Golden Conductive Pipe", Item.redstone, pipeItemsGold, null);
    
    buildcraft/common/net/minecraft/src/BuildCraftTransport.java lines 124–144 at 0a20887 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  6. ^The 2.2.4 pump lowers a tube to the liquid below it and, for 10 energy, takes up one block of it as a bucket's worth (1,000 units), removing the block from the world, then pushes the liquid into an adjacent tank, pipe or machine that holds liquids. A pumped deposit is used up.CodeBuildCraft 2.2.4
    How we know
    84						if (powerProvider.useEnergy(10, 10, true) == 10) {
    85							index = getNextIndexToPump(true);
    86							worldObj.setBlockWithNotify(index.i, index.j, index.k, 0);
    87							internalLiquid = internalLiquid += API.BUCKET_VOLUME;
    
    buildcraft/common/net/minecraft/src/buildcraft/factory/TilePump.java lines 74–93 at 0a20887 · upstream ↗
    124				if (tile instanceof ILiquidContainer) {
    125					internalLiquid -= ((ILiquidContainer) tile).fill(
    
    buildcraft/common/net/minecraft/src/buildcraft/factory/TilePump.java lines 115–132 at 0a20887 · upstream ↗
    22	public static final int BUCKET_VOLUME = 1000;
    
    buildcraft/common/net/minecraft/src/buildcraft/api/API.java line 22 at 0a20887 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  7. ^ abcIn Thermal Dynamics r2.3.9 (Minecraft 1.12.2), connected fluid ducts form one grid. A grid forms outward from one duct, breadth-first over its connected ducts: a duct with no grid joins, and a duct in another grid merges the two grids, the smaller into the larger, the larger keeping its fluid and taking the other's. A grid holds one fluid: a duct joins, and two grids merge, only when their fluids match or one is empty; otherwise the connection is rejected. When a duct is placed, it compares its neighbours' fluids with one of them, the fluid of the duct the player aimed at or else the first neighbour that has one, and blocks its sides to every neighbouring duct whose fluid differs from that.CodeThermal Dynamics r2.3.9revised
    How we know
    16		theGrid = theMultiBlock.createGrid();
    ⋮
    22		while (!blocksToCheck.isEmpty()) {
    23			checkMultiBlock(blocksToCheck.remove());
    
    src/main/java/cofh/thermaldynamics/multiblock/MultiBlockFormer.java lines 14–26 at 5ae9f68 · upstream ↗
    45					if (aBlock.getGrid() == null && theGrid.canAddBlock(aBlock)) {
    ⋮
    51							if (theGrid.size() >= aBlock.getGrid().size()) {
    52								theGrid.mergeGrids(aBlock.getGrid());
    ⋮
    54								aBlock.getGrid().mergeGrids(theGrid);
    ⋮
    59						currentMultiBlock.onConnectionRejected(i);
    
    src/main/java/cofh/thermaldynamics/multiblock/MultiBlockFormer.java lines 44–61 at 5ae9f68 · upstream ↗
    205	public void mergeGrids(MultiBlockGrid<DuctUnitFluid> theGrid) {
    ⋮
    211		myTank.fill(gridFluid.getFluid(), true);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 204–225 at 5ae9f68 · upstream ↗
    419			if (retrace != null && retrace.sideHit != null) {
    420				EnumFacing sideHit = retrace.sideHit.getOpposite();
    421				DuctUnitFluid fluids = IDuctHolder.getTokenFromTile(world().getTileEntity(pos().offset(sideHit)), DuctToken.FLUID);
    422				if (fluids != null) {
    423					fluidStack = fluids.getConnectionFluid();
    
    src/main/java/cofh/thermaldynamics/duct/fluid/DuctUnitFluid.java lines 419–425 at 5ae9f68 · upstream ↗
    434				if (fluidStack == null) {
    435					fluidStack = connectionFluid;
    436				} else if (connectionFluid != null && !fluidStack.isFluidEqual(connectionFluid)) {
    437					parent.setConnectionType(facing.ordinal(), ConnectionType.BLOCKED);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/DuctUnitFluid.java lines 427–442 at 5ae9f68 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Revised after a check by a second AI model, 2026-10-26.

    In the claim ledger

  8. ^ abcdeIn Thermal Dynamics r2.3.9 a fluid-duct grid hands out fluid once a tick. If its tank holds fluid, each duct beside a block that takes fluid offers its neighbours, side by side from where it last stopped, up to the tank's amount divided by the grid's duct count (the remainder when that rounds to 0), and no more than the grid's throughput for that tick. That throughput is the fluid's full rate while the tank is at least three-quarters full, half of it at a quarter full or less, and rises in a straight line from half to full in between. Fluid inside a grid doesn't travel from duct to duct: every outlet draws on the one tank.CodeThermal Dynamics r2.3.9
    How we know
    61		for (MultiBlockGrid grid : tickingGrids) {
    62			grid.tickGrid();
    
    src/main/java/cofh/thermaldynamics/util/WorldGridList.java lines 59–66 at 5ae9f68 · upstream ↗
    162		if (myTank.getFluid() != null && nodeSet.size() > 0) {
    163			toDistribute = Math.min(myTank.getFluidAmount() / size(), getFluidThroughput());
    ⋮
    165			if (toDistribute <= 0) {
    166				toDistribute = Math.min(myTank.getFluidAmount() % size(), getFluidThroughput());
    ⋮
    170				for (DuctUnitFluid m : nodeSet) {
    171					if (!m.tickPass(0) || m.getGrid() == null) {
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 162–176 at 5ae9f68 · upstream ↗
    233		// if over 3/4 full, full throughput
    234		if (myTank.getFluid().amount >= capacity * 3 / 4) {
    235			return myTank.fluidThroughput;
    ⋮
    237		// if under 1/4 full, half throughput
    238		if (myTank.getFluid().amount <= capacity / 4) {
    239			return myTank.fluidThroughput >> 1;
    ⋮
    241		// otherwise scale between half and full
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 227–243 at 5ae9f68 · upstream ↗
    89		if (pass == 0) {
    90			int available = grid.toDistribute;
    ⋮
    93			for (int i = this.internalSideCounter; i < 6 && sent < available; i++) {
    94				sent += transfer(i, available - sent, false, grid.myTank.getFluid(), true);
    ⋮
    102			for (int i = 0; i < this.internalSideCounter && sent < available; i++) {
    103				sent += transfer(i, available - sent, false, grid.myTank.getFluid(), true);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/DuctUnitFluid.java lines 89–110 at 5ae9f68 · upstream ↗
    165		tempFluid.amount = available;
    166		int amountSent = capability.fill(tempFluid, false);
    ⋮
    173					tempFluid = grid.myTank.drain(amountSent, true);
    ⋮
    177				return capability.fill(tempFluid, true);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/DuctUnitFluid.java lines 164–177 at 5ae9f68 · upstream ↗
    157		C c = cacheTile(tile, side);
    ⋮
    160			if (isNode(c)) {
    161				nodeMask |= (1 << side);
    
    src/main/java/cofh/thermaldynamics/duct/tiles/DuctUnit.java lines 157–162 at 5ae9f68 · upstream ↗
    269	public boolean isNode() {
    ⋮
    271		return nodeMask != 0;
    
    src/main/java/cofh/thermaldynamics/duct/tiles/DuctUnit.java lines 269–272 at 5ae9f68 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  9. ^ abIn Thermal Dynamics r2.3.9, removing a duct that had two or more connected ducts queues its grid to be rebuilt; a duct with one connection or none leaves the grid as it is. A rebuilt grid first gives every duct its share of the tank, the amount divided equally among the ducts that store fluid, with the first duct also taking the remainder, and each duct pours its share into whatever grid it joins next. A duct saved with the world keeps its share the same way.CodeThermal Dynamics r2.3.9
    How we know
    145		destroyNode(oldBlock);
    ⋮
    160			if (oldBlock.isSideConnected(i)) {
    ⋮
    164		if (s <= 1) {
    165			balanceGrid();
    ⋮
    170		worldGrid.gridsToRecreate.add(this);
    
    src/main/java/cofh/thermaldynamics/multiblock/MultiBlockGrid.java lines 143–171 at 5ae9f68 · upstream ↗
    47			for (MultiBlockGrid<?> grid : gridsToRecreate) {
    48				for (IGridTile multiBlock : grid.idleSet) {
    ⋮
    50					grid.destroyNode(multiBlock);
    ⋮
    52				for (IGridTile multiBlock : grid.nodeSet) {
    ⋮
    54					grid.destroyNode(multiBlock);
    
    src/main/java/cofh/thermaldynamics/util/WorldGridList.java lines 44–58 at 5ae9f68 · upstream ↗
    148		if (hasValidFluid()) {
    149			((DuctUnitFluid) node).setFluidForGrid(getNodeShare((DuctUnitFluid) node));
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 145–152 at 5ae9f68 · upstream ↗
    267		if (!duct.canStoreFluid()) {
    ⋮
    270		int size = getStorableNumberDucts();
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 265–275 at 5ae9f68 · upstream ↗
    51		if (aMultiBlock.getFluidForGrid() != null) {
    ⋮
    53				myTank.setFluid(aMultiBlock.getFluidForGrid());
    ⋮
    55				myTank.fill(aMultiBlock.getFluidForGrid(), true);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 46–59 at 5ae9f68 · upstream ↗
    375			mySavedFluid = grid.getNodeShare(this);
    ⋮
    377				mySavedFluid.writeToNBT(nbt);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/DuctUnitFluid.java lines 374–377 at 5ae9f68 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  10. ^ abIn 2.1.23 a pipeline's extent is limited by default_pipeline_extent = 320, which a fluidbox can override; a pipeline takes the smallest extent of its parts. The data doesn't say how the extent is measured. When Wube introduced the limit in 2024, FFF #430 described it as a 250 × 250 tile area whose overrun stops all flow until pumps split the pipeline.Codefactorio-data 2.1.23 · Factorio Prototype API 2.1.23 · Friday Facts #430revised
    How we know
    560    default_pipeline_extent = 320, -- Can be overridden on a per-fluidbox basis
    
    core/prototypes/utility-constants.lua line 560 at 39dbd0f · upstream ↗
    The max extent that a pipeline with this fluidbox can span. A given pipeline's extent is calculated as the min extent of all the fluidboxes that comprise it.
    FluidBox.max_pipeline_extent · archived copy ↗
    Pipelines are constrained to a 250x250 tile area, and exceeding this limit will cause all flow through the pipeline to cease. … You can split a pipeline using a pump.
    Pipeline extents · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Revised after a check by a second AI model, 2026-10-26.

    In the claim ledger

  11. ^ abA pipe and an underground pipe each hold 100 units and a storage tank 25,000. An underground pipe pair has a max_underground_distance of 10. A pump moves 20 units a tick (1,200 a second) for 29 kW, a tenth of its earlier rate: Wube cut it in 2024 when pipelines gained their extent limit.Codefactorio-data 2.1.23 · Factorio Prototype API 2.1.23 · Friday Facts #430
    How we know
    2766      volume = 100,
    
    base/prototypes/entity/entities.lua line 2766 at 39dbd0f · upstream ↗
    3026      volume = 100,
    
    base/prototypes/entity/entities.lua line 3026 at 39dbd0f · upstream ↗
    3035          max_underground_distance = 10,
    
    base/prototypes/entity/entities.lua line 3035 at 39dbd0f · upstream ↗
    7094      volume = 25000,
    
    base/prototypes/entity/entities.lua line 7094 at 39dbd0f · upstream ↗
    7255    energy_usage = "29kW",
    7256    pumping_speed = 20,
    
    base/prototypes/entity/entities.lua lines 7255–7256 at 39dbd0f · upstream ↗
    The amount of fluid this pump transfers per tick.
    PumpPrototype.pumping_speed · archived copy ↗
    Pumps have been nerfed to 1200/s (10x decrease), but this can be increased with quality.
    Balance tweaks · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  12. ^ abcBuildCraft 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.Dev blogBuildCraft 2.2.4 · Friday Facts #416
    How we know
    212			int slotExtract = (int) Math
    213			.ceil(((double) quantity / (double) outputNumber));
    ⋮
    215			int [] splitVector = getSplitVector(worldObj);
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportLiquids.java lines 212–215 at 0a20887 · upstream ↗
    Furthermore, the throughput can vary depending on the order that the pipes were built.
    Reaching the breaking point · archived copy ↗
    The amount of fluid flowing to each side of the junction would be different based on the order that the entities were built. … In the new system, junctions are entirely unimportant; a segment only cares about the machines connected to it. … This results in much more even splitting, which while still not perfect, is pretty damn close.
    Junctions · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  13. ^ abFactorio 2.0's fluid segments match the description of Thermal Dynamics r2.3.9's design: connected pipes or ducts merge into one unit that holds one fluid, its volume summed from its parts, and fluid put in is available anywhere along it at once (FFF #416, 2024). In the design as FFF #416 first described it, machines push in at an unlimited rate, as Thermal Dynamics takes fluid up to the tank's free space, and pull at a rate proportional to how full the segment is, half the maximum at half full; each Thermal Dynamics outlet duct instead hands its neighbours between half and all of the fluid's throughput, scaled by how full the tank is (three-quarters of it at half full), and no more than the tank's amount divided by its duct count (or the remainder, when that rounds to 0). FFF #430, still before 2.0's release, gave the rules as changed: pushing in is now slowed as the sink fills, and every transfer is capped at 100 units, a limit that already existed, multiplied by the fullness of both source and sink. The scaling by the source's fullness has a counterpart in Thermal Dynamics; the 100-unit cap and the scaling by the sink's fullness don't. FFF #416 doesn't say which version of the mod Rseding played.Dev blogFriday Facts #416 · Friday Facts #430 · Thermal Dynamics r2.3.9 · CoFH Core r4.3.9revised
    How we know
    Pipes, underground pipes, and storage tanks are merged into fluid "segments". Each segment inherits its volume from the fluid boxes that comprise it and can hold one fluid. Machines can push fluid into a segment at an unlimited rate, and can pull from a segment at a rate proportional to how full the segment is. … In other words, if a segment is half full, then the pulling rate is half of the maximum. … There is no longer a realistic fluid "flow" through pipes; fluid pushed to a segment will be immediately available at any point along a segment.
    The new algorithm · archived copy ↗
    Output rate used to be unlimited, but it is now inversely proportional to the fullness ratio of the sink. … Something that I failed to adequately explain before is that while there is no limitation on the total flow through a pipeline in a given tick, there is a hardcoded limit of 100 fluid per flow operation (6000/s). … This limit is multiplied with the fullness ratios of the source and sink to produce the actual flow value
    Algorithm tweaks · archived copy ↗
    81	public void balanceGrid() {
    ⋮
    84		myTank.setCapacity(size() * myTank.fluidPerDuct);
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 80–85 at 5ae9f68 · upstream ↗
    return aBlock instanceof DuctUnitFluid &&
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java#L215-L219 · upstream ↗
    163			toDistribute = Math.min(myTank.getFluidAmount() / size(), getFluidThroughput());
    ⋮
    165			if (toDistribute <= 0) {
    166				toDistribute = Math.min(myTank.getFluidAmount() % size(), getFluidThroughput());
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 162–167 at 5ae9f68 · upstream ↗
    233		// if over 3/4 full, full throughput
    234		if (myTank.getFluid().amount >= capacity * 3 / 4) {
    235			return myTank.fluidThroughput;
    ⋮
    237		// if under 1/4 full, half throughput
    238		if (myTank.getFluid().amount <= capacity / 4) {
    239			return myTank.fluidThroughput >> 1;
    ⋮
    241		// otherwise scale between half and full
    
    src/main/java/cofh/thermaldynamics/duct/fluid/GridFluid.java lines 227–243 at 5ae9f68 · upstream ↗
    193		int filled = capacity - fluid.amount;
    ⋮
    199			fluid.amount = capacity;
    
    src/main/java/cofh/core/fluid/FluidTankCore.java lines 193–201 at ccf809a · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Revised after a check by a second AI model, 2026-10-26.

    Revised after a check by a second AI model, 2026-10-26.

    In the claim ledger

  14. ^By asie's account, BuildCraft 2.0.0, at the end of July 2011, was the first version to depend on Minecraft Forge and added the power system, Minecraft Joules; 2.0.1 brought oil and wrenches, 2.1.0 liquid pipes and pumps, and 2.2.0 conductive pipes, fuel and the refinery.Dev blogasie, "BuildCraft History and Design", 30 January 2015
    How we know
    version 2.0.0 came out at the very end of July 2011. It was the first version to depend on Minecraft Forge. The major revolution here was the addition of a power system - Minecraft Joules. … In 2.0.1, we got oil and wrenches, and 2.1.0 gave us fluid pipes and pumps. … BuildCraft 2.2.0 added power pipes, fuel and the refinery.
    on 2.0.0 · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  15. ^Team CoFH says Thermal Expansion began as a BuildCraft addon: it needed BuildCraft, or addons such as Forestry, to power its machines with Minecraft Joules, and became independent only in its third iteration.PublisherTeam CoFH, "About"
    How we know
    TE was a BuildCraft addon: it required BuildCraft itself or addons like Forestry in order to power the machines with Minecraft Joules, BuildCraft’s old power system. It wasn’t until the third iteration that the mod became fully independent.
    History · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  16. ^Thermal Expansion 2.1.0 added Tanks and Liquiducts, ducts for fluids, by King Lemming's update note in the Minecraft Forum thread as captured on 2 January 2013.Dev blogKing Lemming, Thermal Expansion 2.1.6 post (2013)revised
    How we know
    So, 2.1.0 is out! It adds Tanks, Liquiducts, and a couple other things.
    #1, Update News (2.1.0) · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Revised after a check by a second AI model, 2026-10-26.

    In the claim ledger

  17. ^Thermal Expansion 3.0.0.0 came out on 25 December 2013, a rewrite in which, by its changelog, "everything has been completely redone"; it introduced Redstone Flux, and its fluid ducts were the Fluiducts, in opaque and transparent kinds.PublisherTeam CoFH, Thermal Expansion changelog (2014)
    How we know
    3.0.0.0: 12/25/2013 - Merry Christmas! Okay, so everything has been completely redone here. … The new energy system is Redstone Flux. (RF).
    3.0.0.0: 12/25/2013 · archived copy ↗
    Two types of Fluiducts - Opaque and Transparent.
    3.0.0.0, Fluid · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  18. ^Thermal Expansion 4.0.0 ported the mod to Minecraft 1.7.10 and moved its Energy Conduits, Fluiducts, and Itemducts into a separate mod, Thermal Dynamics. Team CoFH's downloads page, captured on 27 December 2014, says it was released for 1.7.10 without the ducts, which would follow as a separate mod. Team CoFH credit RWTema, the author of Extra Utilities, with most of the work of porting the ducts to 1.7.10, from around late 2014.PublisherCoFH changelogs (Version repo) · Team CoFH, Downloads page (2014) · Team CoFH, About (2017)
    How we know
    8934.0.0:
    ⋮
    895Welcome to Thermal Expansion 4!
    896-Ported to Minecraft 1.7.10.
    
    thermalexpansion_changelog.txt lines 893–896 at 1bdb613 · upstream ↗
    993		-Energy Conduits, Fluiducts, and Itemducts.
    994			Now in Thermal Dynamics.
    
    thermalexpansion_changelog.txt lines 993–994 at 1bdb613 · upstream ↗
    Thermal Expansion is now RELEASED for 1.7.10. Ducts are not in the release, they will be a separate mod when they are finished.
    The Mods · archived copy ↗
    Tema stepped in around late 2014 when there wasn't anyone around that had time to work on Thermal Dynamics. He did most of the work on porting the missing piece of the Thermal mods in 1.7.10: ducts!
    Team members, RWTema · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  19. ^Minecraft Forge's energy interface, IEnergyStorage, states in its documentation that it is derived from the Redstone Flux system that King Lemming designed for Thermal Expansion, and that it was made with the consent of King Lemming and Team CoFH. Thermal Expansion's own CurseForge description says its fluid and energy systems are now both part of Forge.PublisherMinecraftForge, IEnergyStorage · Team CoFH, Thermal Expansion on CurseForge (2019)
    How we know
    15 * Derived from the Redstone Flux power system designed by King Lemming and originally utilized in Thermal Expansion and related mods.
    16 * Created with consent and permission of King Lemming and Team CoFH. Released with permission under LGPL 2.1 when bundled with Forge.
    
    src/main/java/net/minecraftforge/energy/IEnergyStorage.java lines 15–16 at 243490d · upstream ↗
    Many of the gameplay ideas and mechanics set forth by Thermal Expansion have become staples in the modded Minecraft community, including both the Fluid and Energy (RF) systems, now both included as part of Minecraft Forge.
    description · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  20. ^Friday Facts #416 (2024) says that in the discussions on Factorio 2.0's fluids, Rseding proposed an algorithm "very close to" one from the Minecraft mod Thermal Expansion by Team CoFH, in which pipes, underground pipes, and storage tanks merge into fluid "segments".Dev blogFriday Facts #416
    How we know
    Rseding proposed an algorithm very close to one he had played with several times, an algorithm from the Minecraft mod Thermal Expansion by team CoFH: Pipes, underground pipes, and storage tanks are merged into fluid "segments".
    The new algorithm · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

  21. ^In 2.2.4 an item in a transport pipe travels to the pipe's center and there picks an exit: any side but the one it came in by that leads to a pipe carrying items, a machine that accepts them, or an inventory with room for it. With several, it takes one at random (single-player) or by a fixed hash of the item's id and the pipe's position (multiplayer). With none, the item drops out of the pipe into the world, and an item that reaches a full inventory drops what doesn't fit.CodeBuildCraft 2.2.4
    How we know
    119			if (Orientations.values()[o] != pos.orientation.reverse()
    120					&& container.pipe.outputOpen(Orientations.values()[o])) {
    ⋮
    159		if (entity instanceof IPipeEntry) {
    160			return true;
    161		} else if (entity instanceof TileGenericPipe) {
    ⋮
    164			return pipe.pipe.transport instanceof PipeTransportItems;
    165		} else if (entity instanceof IInventory) {					
    166			if (new StackUtil(item.item).checkAvailableSlot((IInventory) entity,
    ⋮
    168				return true;
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportItems.java lines 114–173 at 0a20887 · upstream ↗
    225				Orientations nextOrientation = resolveDestination (data);
    ⋮
    227				if (nextOrientation == Orientations.Unknown) {
    228					scheduleRemoval(data.item);
    ⋮
    230					EntityItem dropped = data.item.toEntityItem(data.orientation);
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportItems.java lines 225–237 at 0a20887 · upstream ↗
    263				} else if (tile instanceof IInventory) {
    ⋮
    271							data.item.remove();						
    272						} else {
    273							data.item.item = utils.items;
    274							EntityItem dropped = data.item.toEntityItem(data.orientation);
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportItems.java lines 263–282 at 0a20887 · upstream ↗
    377		if (listOfPossibleMovements.size() == 0) {					
    378			return Orientations.Unknown;													
    379		} else {
    ⋮
    382			if (APIProxy.isClient(worldObj) || APIProxy.isServerSide()) {
    383				i = Math.abs(data.item.entityId + xCoord + yCoord + zCoord
    384						+ data.item.deterministicRandomization)
    385						% listOfPossibleMovements.size();
    386			} else {
    387				i = worldObj.rand.nextInt(listOfPossibleMovements.size());
    
    buildcraft/common/net/minecraft/src/buildcraft/transport/PipeTransportItems.java lines 373–393 at 0a20887 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-26.

    Checked by a second AI model, 2026-10-26.

    In the claim ledger

Sources

Code

Primary