Edit: See https://imgur.com/a/XgZeXyc, the setup to reproduce the issue
When there are many warp loaders with different items, they don't reach the max throughput. Often times the input loaders are congested while the output loaders are still not saturated.
After looking into the code, I think there's some bug with enumerating the warp loaders (NextWarpLoader and _next tables). So I rewrote it by removing everything about NextWarpLoader and _next tables, and directly enumerating the loaders:
function warptorio.DistributeLoaderLine(line)
if(not isvalid(line))then return end
local inv=line.get_contents()
for item_name,item_count in pairs(inv)do
if(warptorio.OutputWarpLoader(item_name,item_count))then line.remove_item{name=item_name,count=1} return true end
end
end
function warptorio.OutputWarpLoader(cv,c)
local wpg=global.warploaders
local ins=false
if(wpg.outputf[cv])then
local coutf=wpg.outputf[cv]
for _,outline in pairs(coutf)do
if (outline and warptorio.InsertWarpLane(outline,cv)) then ins=true break end
end
if(ins)then return true end
end
local cout=wpg.output
for _,outline in pairs(cout)do
if(outline and warptorio.InsertWarpLane(outline,cv))then ins=true break end
end
if(ins)then return true end
return false
end
function warptorio.TickLogistics()
...
if(global.warploaders)then
for _,line in pairs(global.warploaders.input) do
warptorio.DistributeLoaderLine(line)
end
end
end
Then in my local testing, the throughput issue is fixed, so I should have located the bug correctly.
A downside is that it doesn't evenly distribute items between all warp loaders, but favors those built earlier. So if the supply is lower than the demand, then some output loaders will starve. But at least I can now build a speghettiless megabase on the factory floor with warp loaders.