BuildCraft|Core

BuildCraft|Core

7M Downloads

Fluid pipe transfer rate limited by non-input, non-output sides

mconwa01 opened this issue ยท 2 comments

commented

For example, under the default settings, a single length of emerald (40 mB/t) fluid pipe, connected to a single input and a single output, transfers only about 31 mB/t.

I think the issue may be here, in PipeTransportFluids.moveToCenter():

private void moveToCenter() {
    int transferInCount = 0;
    int spaceAvailable = getCapacity() - sections[6].amount;

    for (ForgeDirection dir : directions) {
        inputPerTick[dir.ordinal()] = 0;
        if (transferState[dir.ordinal()] != TransferState.Output) {
            inputPerTick[dir.ordinal()] = sections[dir.ordinal()].drain(flowRate, false);
            transferInCount++;
        }
    }

    float min = Math.min(flowRate * transferInCount, spaceAvailable) / (float) flowRate / transferInCount;
    for (ForgeDirection dir : directions) {
        // Move liquid from input sides to the center
        if (transferState[dir.ordinal()] != TransferState.Output && inputPerTick[dir.ordinal()] > 0) {

            int amountToDrain = (int) (inputPerTick[dir.ordinal()] * min);
...

All non-output sides are counted in transferInCount, including (in the simple case above) the four unconnected sides, giving us 5. When min is calculated, it assumes that all five can provide the total flowRate of input and allocates up to 1/5 of the remaining capacity to each, even though only one of those five can provide any input. (This ends up stabilizing with an amount of 124 in the center section, and if I'm understanding the code correctly, 31 in each of its 4 incoming slots. When we reach this point, 31 mB have already been transferred out by moveFromCenter(), leaving 93, and a remaining capacity of 250-93=157, so we end up pulling floor(157/5)=31 mB from the input, leaving us in the same state.)

Tested on version 7.1.8. This may be the cause of #2865.

commented

What a fail!

(Also, your detective skills are amazing. Good job.)

commented

Great, thanks! By the way, the percentage loss varied with the intended throughput--if I remember correctly, the 80 mB/t pipes were closer to 50%.

Pathological case time...

Given the new code, suppose we upped the pipes to gold (80 mB/t), increased our main input to 80 mB/t, added fluid pipes to the 4 remaining sides, and supplied 1 mB/t from each of these new pipes. The center's capacity is still 250 mB, so no matter how little fluid is already there, min is capped by spaceAvailable at 0.625 (probably less at equilibrium). Thus we'll pull at most 50 mB from the main input, plus the 1 mB from each small input, giving 54 mB instead of the intended 80. Is that analysis correct? If so, is it worth fixing? (I suspect you could trigger it with a less extreme case, though you might have to look at it at equilibrium.)