Miner Planner automates mining drill placement on ore patches. Drag-select an area, pick your drill, belts, poles, and beacons from an icon-based GUI, and ghost entities are placed in optimized paired-row layouts ready for construction bots. Works with all drill types, belt tiers, pole types, and resources across all planets.
Providing the player with new tools or adjusting the game interface, without fundamentally changing gameplay.
New Ores and resources as well as machines.
Change blueprint behavior.
It would be real neat if the mod could automatically merge output belts based on the number of miners in each row, with the goal of collecting all of the output into the minimum number of belts to carry it all.
The general logic would be:
1. Add a lane balancer to the end of each row of miners
2. Calculate how much ore each row outputs, being sure to account for the limits of the output belt.
3. Going left-to-right, merge the belt from the first row with that from the second row. Calculate the total output. If this amount is greater than one full belt, use output priority to create a full output belt, while sending the overflow on to the next merger. Otherwise, merge both belts into a single output, and send it all on to the next merger.
4. Repeat step 3 for each additional row, at each step merging the leftovers from the previous row with the output from the new row, and adding an output belt if there's enough input for a fully compressed belt.
5. Any overflow from the final row becomes a final, uncompressed output belt.
Here's a more detailed example. Assume we're working with red belts (so 15 items/s per lane) and using electric miners with no speed modules or mining productivity on iron ore (so each miner outputs 0.5 ore/s).
1. First row has 7 miners, or 3.5 ore/s.
2. Second row has 28 miners, or 14 ore/s. Combined with the previous row, that makes 17.5 ore/s, which is less than one red belt, so we just user a splitter to merge the two belts into one, using a filter so that all the output goes onto that one belt. That belt then goes to the next row.
3. Third row has 36 miners, or 18 ore/s. Combined with the previous row, that makes 35.5 ore/s, which is enough for an output belt. We thus generate a compressed output belt like so:
- The belt from the new row is split into two, with one output having priority.
- The priority output from that splitter is merged with the belt from the previous row. Input priority is set to the previous row's belt, and an output filter is used to direct all the ore onto a single belt, which becomes our output belt. There's at least 3 units of belt between the previous splitter and this one; this creates a buffer, ensuring the output belt is always compressed.
- The non-priority belt from this first splitter continues on to the next row, carrying the 5.5 ore/s of overflow.
4. Forth row has 55 miners. However, 35 of those miners are on one side of the belt, which means 5 of them will not contribute to the row's output because the lane they are outputting onto is already full. So the output of this row is 25 ore/s. This gets combined with the 5.5 ore/s overflow from the last row to make 30.5 ore/s. Another two-splitter arrangement produces one fully compressed output belt and a 0.5 ore/s overflow to the next row.
5. Fifth row has 67 miners. This time both sides of the belt have > 30 miners, so output is capped at 30 ore/s. This gets combined with the 0.5 ore/s overflow from the last row to make 30.5 ore/s. Another two-splitter arrangement produces one fully compresses output belt and a 0.5 ore/s overflow to the next row.
6. Sixth row has 41 miners, or 20.5 ore/s. Combined with the overflow, this makes 21 ore/s. Not enough for an output belt, so a single splitter is used to merge the belts and the whole thing is sent on to the next row.
7. The seventh and final row has 24 miners or 12 ore/s. Combined with the previous row, that makes 32.5 ore/s, which is more than one red belt. Another two-splitter arrangement produces one fully compressed output belt. However, since this is the last row, the 2.5 ore/s of overflow becomes another, uncompressed output belt.
I already do this process whenever I'm creating a new mining output, but manually checking the output of each row and identifying when a new output belt is called for is tedious. This mod, since it is already creating the miners and belts, could easily automate the process.
Thanks for the detailed write-up! The logic is sound for a fresh ore patch at peak output. However, there's a fundamental issue: ore patches deplete unevenly over time, and this design optimizes for a single moment rather than the full lifecycle of the patch.
Why it breaks down:
Your example calculates exact ore/s per row and builds a fixed splitter tree that produces "full" output belts. But consider what happens 30 minutes later:
The priority splitter arrangement is essentially hardcoding routing decisions based on throughput that will change. It's a snapshot optimization in a dynamic system. Every drill that runs out of ore invalidates the math that determined where to split and where to merge.
How I handle this instead:
I count total belt lines coming from miners and decide how many output lines I need, then place an N-to-M balancer (e.g., 6-to-4). This gives you:
The balancer always distributes evenly regardless of which specific rows lose drills first. Downstream furnace arrays get equal feed on every belt at every stage of the patch's life. No calculation per row needed, no fragile assumptions about throughput.
The problem with using N-to-M balancers is that, unless you're using a throughput-unlimited design, you often lose a lot of productivity on the longer rows in the middle. For instance, let's say you have 6 rows of miners producing 2 belts of total output, so you use a 6-to-2 balancer. But the most common 6-to-2 balancer design just merges each pair of adjacent belts with a single splitter and then feeds the results into a 3-to-2 balancer. This means both central rows of miners are merged into a single belt, and, given those middle rows are also the longest rows, chances are they have more than one full belt of output between them. N-to-M balancers also use a lot of belts, undergrounds, and splitters, especially the throughput-unlimited versions (when they're even available).
The point of output consolidation like I described isn't to produce N equally-full belts. It's to combine the full output of the mining patch into the minimum number of belts so that they can be transported from the mine to wherever they need to go - usually either a smelting column or a train station - with a minimum of space and expense. The fact that it initially produces N-1 full belts and 1 partial is just a side-effect of the output priorities required to ensure all miners have full output, with the nice side-effect of being a minor UPS optimization.
Those are fair points about balancer throughput limits and material cost. I'll concede that N-to-M balancers aren't perfect for every situation.
But the core concern still stands: the splitter tree your design builds is physically fixed based on miner counts at placement time. Consider what happens as the patch depletes:
Row 3 had 36 miners producing 18 ore/s, and the two-splitter arrangement was built to split off a full belt and pass 5.5 ore/s overflow. When half those miners deplete, it's now 9 ore/s — the priority splitter still routes ore the same way, but now the "full output belt" is half-empty, and downstream merges that depended on specific overflow amounts are all wrong.
Worse: your step 4 accounts for lane saturation (35 miners on one side capping output). As drills deplete unevenly on each side, the lane saturation math changes constantly. A splitter tree built for "25 ore/s from this row" might see 15 ore/s or 30 ore/s a few minutes later depending on which specific drills run out first.
The result after depletion: you still have the same number of output belts (the physical splitter tree doesn't change), but they're no longer consolidated to minimum belts — you get partially-filled "full" belts and near-empty "overflow" belts. The feature achieves minimum belts only at peak, then degrades to the same or worse state than simpler approaches.
The other practical concern from the mod's perspective: this would require calculating per-row output (accounting for drill count, modules, beacons, mining productivity research, quality bonuses, and lane saturation), then generating a variable splitter tree layout that differs for every ore patch. That's a significant increase in complexity for a benefit that only holds at peak output. The mod currently produces a layout that works consistently across the entire patch lifecycle.
That said, I do see the appeal for megabase players who prioritize belt-count efficiency for train loading. It's on my radar but not something I'd want to rush given the edge cases involved.
Yes, as the patch depletes, you'll no longer have full belts. So what? The point of this exercise is to combine the output into the minimum number of belts to get it all where it needs to go. That number is (initial output of miners) / (belt throughput), rounded up. No matter how you distribute the ore, whether its concentrated into full and empty belts or balanced evenly across all of them, you'll need that many belts minimum to move it all. And because the output of any ore patch reduces as it depletes, what was initially 'just enough' belts will eventually become 'more than you need' belts - again, this is true no matter how the ore is distributed across the belts.
Having the output be concentrated into full belts as much as possible is a UPS optimisation, not a core requirement. If you really want to ensure it retains that property, then instead of calculating the output belt locations left-to-right, calculate them working in from both sides, and set the priority to flow towards the center; since the middle rows have the most miners and the most ore under each miner, as the patch depletes you'll end up with the outermost belts running completely dry, with at most a single partial belt on each side and a bunch of fully compressed belts in the middle.
"A splitter tree built for "25 ore/s from this row" might see 15 ore/s or 30 ore/s a few minutes later depending on which specific drills run out first."
No. When a miner runs out, one of two things will happen:
- If the lane it was outputting on was oversaturated, then another miner, previously idle due to not having any space on the belt to output onto, will come online and replace the dead one, in which case the row's output remains unchanged.
- Otherwise, the row's output will decrease by one miner.
There is no scenario where a miner running out will increase the total output of the row.
"The other practical concern from the mod's perspective: this would require calculating per-row output (accounting for drill count, modules, beacons, mining productivity research, quality bonuses, and lane saturation), then generating a variable splitter tree layout that differs for every ore patch."
It really isn't that complicated. The game literally tells you the item/s output of a mining drill if you mouse over it. AFAICT, all the designs your mod generates have the exact same mining output for every miner in the patch. Calculating a lane's total output is thus simply a matter of counting how many miners are in it, multiplying by the output rate, and then capping the value to the belt's capacity if needed. It's not at all hard, just tedious to do manually.
As for generating the splitter tree, there's literally only two designs involved: merging the new row's belt into the existing row if the total ore is less than one full belt, or merging the new row in while also splitting off an output belt if the total ore is greater than one full belt. Pick whichever one is appropriate for each row, plus a few segments of belt to connect then (how many segments depending on what size of miner is being used, and thus how far apart rows are).
"That's a significant increase in complexity for a benefit that only holds at peak output. The mod currently produces a layout that works consistently across the entire patch lifecycle."
Except a) the mod does not 'produce a layout that works across the entire lifecycle'; it produces a layout with no output management of any kind, leaving that entirely up to the player to do manually, and b) the described system of output consolidation will, in fact, work over the entire patch's lifecycle. It won't be /perfectly efficient/ over the whole lifecycle, but there's literally no way to do that ever - if you have a patch that has an initial output of, say, 5 belts, then eventually its output will drop to the point of only needing 4 belts, at which point one of those belts is wasted. There's no way around that, short of coming back and removing the excess belt. But the 5 belt system will still /work/ just fine even if only carrying 4 belts of ore.
"That said, I do see the appeal for megabase players who prioritize belt-count efficiency for train loading. "
This has nothing to do with megabases. This is about turning a mining patch with, say, 12 rows of miners but only 4.8 belts of total output into /5 belts/, which can then be fed to where it needs to go. Often than will be a train station, where those 5 belts, and often belts from other ore patches, will be fed into a N-to-8 or N-to-16 balancer to be fed to the station's buffer chests, but at an earlier stage of the game it might be directly to a smelting column.
Here is an blueprint showing what I mean: pastebin (dot) com (slash) HRgj0qS2
At the top is the consolidation system I described in my original post. (Assuming each miner has an output of 0.5/s.) In the top-right corner are the two templates used to create the merge tree. 10 rows of miners neatly consolidated into 5 belts. Initially the right 4 belts will be saturated and the leftmost one partially filled; as the patch depletes, they will eventually all end up being only partially filled.
At the bottom is the alternate start-from-the-middle system I mentioned in my previous post. It produces 6 output belts. Initially, the middle 4 will be saturated, while the leftmost and rightmost of which will only be partially full. As the patch depletes, each outside belts will get sparser and sparser, but the belt inside of it will remain fully saturated until the outside one is completely empty, and then the one inside of that will remain fully saturated until the middle one is completely empty.
The bottom option is more UPS efficient, since there will only ever be 2 partial belts, with the rest either being fully saturated or totally empty. But, again, UPS optimisation isn't the main goal here; either option will do the critical job: compressing ten rows of miners into 5 or 6 belts of output, without using a huge and potentially throughput-limiting 10-to-5 balancer. I just want to get rid of the 3-4 minutes it took to set up either one manually.
Thanks for the blueprint and the detailed breakdown — the start-from-middle variant with its outside-in depletion behavior is more robust than I initially gave credit for. You're right that consolidating 10 rows into 5-6 belts is strictly better than routing 10 partial belts regardless of depletion stage.
I'll add this to the feature backlog. It's a substantial feature — the mod would need to calculate per-row throughput (accounting for drill count per lane, modules, beacons, mining productivity, quality), generate a variable splitter tree layout, and handle both the sequential and start-from-middle variants. But the use case is solid and the manual setup time you're saving is real.
No promises on timeline, but it's on the radar as a legitimate improvement.
Note that quality doesn't actually affect a drill's production rate; a higher-quality drill will delete the ore patch slower, but output at the same rate. However, you /do/ need to account for belt stacking, since that will affect belt capacity.
Also while having both the outside-in and left-to-right trees as options would be nice, having either one would be better than nothing, so I suggest going with whichever is easiest to implement, and treat adding the other option as a later feature.
One minor potential improvement with the outside-in variant: take the partial belt from one side and feed it across to the other, and merge it into the first row as if it were another row of miners. That would reduce the number of output belts back down to the minimum of 5. (Obviously, you only need to do this in cases where the left and right partial belts actually do add up to no more than one full belt between them, and in which case merging them reduces the number of output belts that need to be built by one. If you have two partial belts which add up to more than one full belt, you /could/ merge them to produce one full and one partial belt, but due to the way the splitters work, as the patch depletes you'd eventually end up with 2 partial belts again anyway.)
Also, the logic for the outside-in splitter array is as follows:
1. Add lane-balancers to every miner row.
2. Divide the patch in half. If the number of rows is odd, use a splitter to separate the middle row's output into two, and assign one half to each side.
3. Initially, all mining rows on each side should be merged together into a single output belt, using a chain of single-output splitters, with input priority on the belt from that mining row.
4. Calculate a running total of the outputs of all the rows on each side, starting from the innermost row. Every time the total meets or exceeds a new multiple of the belt capacity, you need to add another output belt. To do this, connect the new output belt to the second output of that row's splitter. However, make sure output priority is to the belt running to the next splitter, not on the output leading to the new output belt.
5. Additionally, add two more splitters. One should be just behind the existing one on the belt from the previous row, with output priority towards the existing splitter, and the other just ahead on the new output belt, with input priority from the existing splitter. A couple sections of belt should be used to connect the non-priority output of one splitter to the non-priority input of the other; this creates a small buffer which will fill in any small gaps on the output row which might happen because of the tiny random variations in input and output demands on the main splitter.
- Note: Optionally, you can skip this step for the last output belt on each side; that belt won't be fully compressed anyway, so random gaps are not a problem.
6. Check how much output the outermost belt on each side has. (This will be the total output of that side modulo the belt capacity.) If both belts combined total less than one full belt, the output belt from one side should be rerouted to the hitherto-unused input of the splitter on the outermost row on the other side.
7. Finally, check the outermost row on each side. On one or both sides (depending on if you rerouted a partial output belt in step 6), you'll have a splitter with only one input and one output. This can be deleted and replaced with a plain belt.
Here is a new version of the outside-in splitter array constructed using exactly the above logic. (The old version had a couple errors in its merging logic which would have prevented it from working correctly.) Note that this blueprint only includes the splitter array, omitting the miners; just attach it to the same mining setup as before, on the bottom:
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
Note that the splitter system described in my previous post isn't quite perfect: it ~guarantees that the full belts will be fully compressed, but it doesn't guarantee that the empty belts will remain totally empty. The issue is the splitter on each output belt which receives input from both the current row and the previous ones. Despite having an output priority set, if a unit of ore arrives on both inputs simultaneously, then one of them will be sent to the non-prioritized output belt, even if the prioritized one isn't actually fully compressed.
If you want to be absolutely maximally UPS efficient, you need to use this contraption, which ensure neither input will ever send any output down the output belt unless the belt to the next splitter backs up enough to force them to:
0eNrVl8uO2yAUhl8lYm2PDAbfpG67nc3sqioiCckg2eBiPDNW5HcvdtrGkyEWhFVXvgjOxw+H/8AZ7OqetYoLDaoz4HspOlD9OIOOnwStp3+CNgxU4Eg7HWtFRddKpeMdqzUYI8DFgX2ACo7RvT5dW3OtmVq0RuPPCDChuebsgps/hq3om51pWcHob4gDN/3pELdUsBpEoJWd6SXFRDGRYlgm+ROJwDC9ozJ5Igaj2YeRA74r2WwaLrg4bZR8N71p/U6Hbtu9mq9Kq55Nw75ho2hNsnUExXUERTGP4MAV219aFRZG6s/IfBnYn5GvMSCyQEhkX2t7+H/BSxcBmbcAmC4EZC6M3J+B1hjWSSr8IYk3pPRf7tIbApOwzZHfUrANAsMy11EKCtuDuRslDdOSuyQxxB52CfEiPF7a5XOv215v/gzMxSoheRRMluAXuRHmbbNwDyd6oEFgtxXMwyjEjVKEGZGjlhuT6E05ViclzdPRiyxqzDIO7RRSzvkDbCU18SgTEC738lfakddT1+sp48CmU4tJkrlRbNJQiDn2r54ajokEhFQNndJyL5uWKqqlCQC+TUeSy6i35ggk1aVxzY7TTHBx81/x06tdnr9hfRLptngo8GCCXawEpWFlxFEK9jk2FOv58HUB7y8UCVNHnKYw8xG3LCkkTFz+wOb+VGzWNve8G6zYIqzCOWZM6XMjuFtp5htBq9ibb61JHzj4EO8qkEIfn1z6Mv4ffDINdLDUbRIDLcxGMddVrlljQl6vyxF4Y6qbW5AMlbgsSYETlOBiHH8Dgp/4MA==
I don't actually recommend doing this. The occasional price of ore going down an otherwise-empty belt is a very miner UPS penalty. The only reason I included the triple-splitter buffer for ensuring full belts are really full is because if a belt that is supposed to be full isn't, that means the maximum output of the whole system is reduced, potentially meaning not all miners are actually running.
Another limitation: the way this maintains full belts even as the patch depletes is by 'borrowing' output from the outer belts in order to make up any deficit in the inner belts. This generally works fine because the outer belts have the fewest miners to start with and are the first to deplete, so the amount of borrowing needed remains reasonably small. However, the maximum amount of borrowing possible at any one point is one belt's worth of output, so for very large patches, it might not be able to borrow enough to keep all the inner belts fully compressed. It'll still work, but there will be more than one non-compressed belt per side.