The Satisfactory Train Throughput Calculator solves the complete logistics chain for transporting items (solid or fluid) by train between two factories in the game Satisfactory. It answers:
Given your factory's belt speeds and total production rate, the calculator determines the minimum number of freight platforms needed at your source and destination stations.
It generates step-by-step build instructions for connecting your factory belts to platforms using Splitters, Mergers, and ISCs — including complex fractional ratios.
The RtD (Round-Trip Duration) analysis tells you whether your train's travel time falls within the safe operating window, or if it's too fast or too slow.
The destination solver generates a cascading overflow manifold using Smart Splitters and ISCs to feed your factory lines at exact rates.
Every calculation generates a live SVG diagram showing exactly how your belts, splitters, mergers, ISCs, and platforms connect. You can pan, zoom, and hover over any node to highlight its input and output connections — making it easy to visualize complex multi-platform layouts.
📦 Solid Mode — For items on belts (Iron Ore, Wire, Screws, etc.). Uses belt tiers Mk.4/5/6 with speeds of 480/780/1200 items/min.
💧 Fluid Mode — For liquids in pipes (Water, Oil, etc.). Uses pipe tiers Mk.1/Mk.2 with speeds of 300/600 m³/min. Fluid mode is simpler because pipes auto-level via fluid pressure — no fractional balancers needed.
When you select a belt tier (Mk.4, Mk.5, or Mk.6) in the header, the entire calculator reconfigures itself instantly. Every formula that references belt speed — the Capacity Ceiling, MinRtD, MaxRtD, platform counts, safety margins, and all fractional balancer math — is recalculated using the new tier's speed.
How it works under the hood: The setBeltTier() function updates the global constants GAME.MK4_BELT_SPEED and GAME.DUAL_MK4_MAX to the selected tier's values (e.g., Mk.6 sets them to 1200 and 2400). It then clamps all existing input values — if you had a belt set to 780/min and switch down to Mk.4 (max 480), that belt is automatically capped to 480. Finally, it triggers a full recalculation of every output panel.
In plain English: Switching from Mk.4 to Mk.6 doesn't just change a label — it fundamentally changes how many platforms you need, how your belts are balanced, and what your safe RtD window looks like. Always set your tier before entering belt speeds to avoid unexpected clamping.
The Complete Workflow
Every term displayed in the calculator, explained in plain English.
((RtD − 27.08) / RtD) × DualBeltMax. If your actual load is below this ceiling, your throughput equals your load — the game does NOT magically delete items. The ceiling is only a limit, not a tax.(load / DualMax) × 100. Below 80% is very safe. Above 90% is risky — items may back up during docking pauses.(Capacity / BeltRate_per_sec) + 27.08. If TtF < RtD, the train departs fully loaded (ideal). If TtF ≥ RtD, the train departs before it's full (semi-loaded).StackSize × 32 (32 inventory slots per freight car). For Quickwire (stack size 500), that's 16,000 items per car. For Iron Ore (stack size 100), that's 3,200 items per car. For fluids, capacity is always 2,400 m³.⚠ Tight: RtD is between MinRtD and 1.2× MinRtD. Works but cutting it close.
✓ Optimal: The sweet spot between Tight and Safe boundaries.
◉ Safe: RtD is between SafeEnd and MaxRtD. Comfortable margin.
↻ Overflow: RtD > MaxRtD. Train is too slow — freight cars overflow and items are wasted.
Every mathematical formula used by the Calc engine. These are the building blocks that all higher-level solvers depend on.
FreightCapacity = StackSize × 32
What it does: Calculates how many items fit in one freight car. Each car has 32 inventory slots, and each slot holds one stack.
Example: Quickwire has a stack size of 500. So one freight car holds 500 × 32 = 16,000 items. Iron Ore (stack size 100) → 3,200 items per car.
Why it matters: This determines how much "cargo budget" your train has per trip. A higher freight capacity means the train can sustain more throughput at the same RtD.
TtF = (Capacity / BeltRate_per_sec) + 27.08
What it does: Calculates how long it takes to fill one freight car, including the 27.08-second docking lockout at the start.
Example: Capacity = 16,000, Belt input = 960 items/min (16/sec). TtF = (16,000 / 16) + 27.08 = 1,000 + 27.08 = 1,027.08 seconds.
Why it matters: If TtF < RtD, the freight car fills before the train returns — you're "fully loaded" (ideal). If TtF ≥ RtD, the train departs before the car is full — "semi-loaded" (items are wasted capacity).
C_max = ((RtD − 27.08) / RtD) × DualBeltMax
What it does: Calculates the absolute maximum sustained throughput a single platform can handle. The multiplier ((RtD − 27.08) / RtD) represents the fraction of time the platform is actually available for item flow (i.e., NOT locked out).
Example (Mk.4, RtD = 600s): C_max = ((600 − 27.08) / 600) × 960 = 0.9549 × 960 ≈ 916.7 items/min.
Critical insight: This is a ceiling, not a tax. If your actual load is 500/min and the ceiling is 917/min, your throughput IS 500/min — the game does not penalize you. The ceiling only matters when your load approaches or exceeds it.
ActualTP = min(Load, CapacityCeiling, FreightLimit)
What it does: Determines the true throughput by taking the minimum of three constraints:
- Load — How much your belts are actually sending
- Capacity Ceiling — Platform's sustained max from the lockout formula
- Freight Limit — How much cargo the freight cars can carry per round trip
Your throughput is always limited by the tightest bottleneck.
TP_full = (NumCars × Capacity) / RtD_min
What it does: The throughput when the train fills completely before departure. All freight capacity is utilized.
Example: 3 freight cars × 16,000 items each, RtD = 600s (10 min). TP = 48,000 / 10 = 4,800 items/min.
MaxRtD = Capacity / InputRate_per_sec
What it does: The maximum Round-Trip Duration before the freight car overflows. If RtD exceeds this, items arrive faster than they can be transported — items back up and may be lost.
Example: Capacity = 16,000, input = 16 items/sec. MaxRtD = 16,000 / 16 = 1,000 seconds.
MinRtD = (27.08 × DualBeltMax) / (DualBeltMax − RequiredTP)
What it does: The minimum Round-Trip Duration needed for the capacity ceiling to be ≥ the required throughput. If RtD is shorter than this, the platform physically cannot sustain the required flow rate.
Derivation: Starting from Required = ((RtD − 27.08) / RtD) × DualMax, solve for RtD.
Example (Mk.4, need 900/min): MinRtD = (27.08 × 960) / (960 − 900) = 25,997 / 60 ≈ 433 seconds.
Cars = ceil((DesiredTP × RtD_min) / Capacity)
What it does: Calculates the minimum number of freight cars needed to sustain a desired throughput. If the result is 2.3 cars, you need 3 (always round up).
Key insight: If throughput is bottlenecked, do NOT run multiple trains! Instead, elongate the single train by adding more freight cars and matching platforms.
Utilization = (LoadPerMin / DualBeltMax) × 100
What it does: Shows how close a platform is to its maximum belt speed. Used to color-code platform status (green = safe, yellow = warning, red = danger) and determine if more platforms are needed.
SafeMax = DualBeltMax × SafetyPct
What it does: Calculates the effective maximum throughput the calculator will assign to a single platform, after applying the safety buffer. This is the value that directly determines how many platforms you need.
Auto mode: When the safety field is left blank, the calculator computes SafetyPct dynamically: SafetyPct = ((RtD − 27.08) / RtD) × 0.95. This means the safe maximum is 95% of the Capacity Ceiling — leaving a 5% buffer above the lockout-adjusted limit. For example, at Mk.4 (dual max = 960) with RtD = 600s: SafetyPct = 0.9549 × 0.95 = 0.9072, so SafeMax = 960 × 0.9072 ≈ 871 items/min.
Custom mode: If you enter 80%, SafetyPct = 0.80 and SafeMax = 960 × 0.80 = 768 items/min. This requires more platforms but gives you much more headroom for disruptions.
Why it matters: This is the bridge between the Capacity Ceiling (F3) and the platform count. If your total source rate is 2,250 items/min and SafeMax is 871, you need ceil(2250 / 871) = 3 platforms. Without understanding SafeMax, the platform count can seem mysterious.
The Source Solver determines how your factory belts connect to the train loading station. It uses a Deficit-Based Symmetrical Distribution algorithm to achieve perfect platform balance.
The old greedy bin-packing approach would assign whole belts to platforms before splitting, which could trap the algorithm into unbalanced results (e.g., 825/825/600 instead of 750/750/750). The new algorithm fixes this by calculating each platform's deficit from the ideal balanced target and distributing remaining belts proportionally.
Step-by-Step Algorithm
Total = sum(allBeltRates)SafeMax = DualBeltMax × SafetyPercentNumPlatforms = ceil(Total / SafeMax)Target = Total / NumPlatforms
The target is the ideal perfectly-balanced load per platform. The system aims to make every platform hit this exact number.
Any belt exceeding the single belt speed (e.g., >480 for Mk.4) is chunked into multiple Mk.4-safe parts. For example, a 780/min belt on Mk.4 becomes Belt 1 (Part 1) at 480/min + Belt 1 (Part 2) at 300/min.
All chunks are sorted descending by rate so the largest belts are placed first.
For each belt (largest first), find the platform with the least current load where adding this belt keeps the total ≤ the balanced target. If such a platform exists, assign the entire belt to it. If no platform can fit the belt without exceeding the target, put it in the "remaining" pile for Phase 2.
Key: This phase only assigns belts that fit perfectly. It never overfills a platform beyond the target.
For each remaining belt, the algorithm:
- Recalculates each platform's deficit =
Target − CurrentLoad - If only one platform has a deficit, the belt is split: the platform gets exactly its deficit, and the remainder goes to the next-neediest platform
- If multiple platforms have equal deficits, a legal N-way split (1/2 or 1/3) is used
- If deficits are unequal, the belt is sliced proportionally: each platform gets
(its deficit / total deficit) × belt rate
This proportional slicing is what achieves perfect symmetrical balance — every platform ends up within fractions of a unit of the ideal target.
For platforms receiving >2 input belts, the algorithm partitions them across Port 1 and Port 2 (each capped at belt speed, e.g., 480/min for Mk.4). Belts are assigned to ports using a balanced partitioning approach (largest-first, to the least-loaded port).
If a port has >1 belt, a Merger is generated (max 3 inputs). If >3 belts, cascading mergers are built in a tree pattern: groups of 3 feed into mergers, whose outputs feed the next level.
Floating-point arithmetic can cause tiny drift (e.g., portions summing to 450.01 instead of 450). The algorithm forces the sum of all portions for a split belt to exactly equal the original belt rate by adjusting the last portion to absorb any rounding difference. This prevents throughput leaks.
Factory Belts → [Splitters (if needed)] → [Mergers (if >2 belts/platform)] → ISC Buffer → Freight Platform
The most complex module. When the Source Solver splits a belt across platforms in unequal portions, this solver generates detailed, game-accurate build instructions using only legal Splitters (½ or ⅓) and Mergers.
In Satisfactory, a Splitter always divides items equally — ½ with 2 outputs or ⅓ with 3 outputs. You cannot set a custom ratio. So how do you achieve a 300/150 split (2:1 ratio) from a 450/min belt? Answer: Split into 3×150, then merge 2 of them. The Fractional Balancer Solver automates this process for any ratio.
The 7 Strategy Types
The solver runs through a prioritized strategy pipeline. It tries each strategy in order and uses the first one that works:
When used: 2 outputs, and both can be formed by merging equal-sized slices from a 2, 3, 4, or 6-way split.
Example: 450/min → 300 + 150. Split 3-way (150 each), merge 2 slices for 300, route 1 slice for 150. Total: 1 Splitter + 1 Merger.
How it works: For each candidate split factor N ∈ {2, 3, 4, 6}, compute slice = rate/N. Check if both target portions can be expressed as integer multiples of that slice.
When used: All target portions are integer multiples of (totalRate / 3).
Example: 900/min → 600 + 300. Third = 300. 600 = 2 thirds, 300 = 1 third. Split 3-way, merge 2 thirds → 600, route 1 third → 300.
When used: A 2-way split cleanly separates one half that matches a target (or a subset of targets that sum to half).
How it works: Split 2-way. One half goes directly to a platform (or is sub-split for multiple platforms). The other half is recursively sub-split using the same solver.
When used: Targets can be partitioned into groups where each group uses an integer number of "chunks" from an N-way split, and each group can be resolved with minimal machines.
How it works: For each split factor (3 or 2), check if targets can be partitioned into merge groups (multiple chunks → merge), route groups (single chunk → direct), and subsplit groups (single chunk split among multiple small targets). Uses backtracking to find valid partitions.
Why it's powerful: Dramatically reduces machine count compared to atom decomposition for many practical scenarios.
When used: The GCD (Greatest Common Divisor) of all portions gives a clean "atom" size, and the total number of atoms is factorable into 2s and 3s (achievable with in-game splitters).
Algorithm:
- Find GCD of all portions (scaled to integers) → atom rate
- Total atoms = totalRate / atomRate
- Each portion needs (portion / atomRate) atoms
- Factor totalAtoms into 2s and 3s → split tree (e.g., [3, 2] = 6-way)
- Build cascading splitters per the split tree
- Merge the right number of atoms for each target platform
Example: 480 → 320 + 160. GCD = 160. Atoms: 3 total (2 for 320, 1 for 160). Split tree: [3]. Place 1 splitter (3-way), merge 2 for platform A, route 1 for platform B.
When used: The total atom count is NOT factorable into 2s and 3s (e.g., 5, 7, 11 — prime numbers). Standard splitter trees can't produce exactly this many equal outputs.
Solution (community-standard method):
- Find the next valid split count ≥ totalAtoms that IS factorable into 2s and 3s (e.g., 5 → 6)
- Build a split array for the valid count
- Route the "extra" belts (validCount − totalAtoms) BACKWARD into an Injection Merger that feeds the splitter array
- The loop creates a steady-state equilibrium that produces exactly totalAtoms equal outputs
Internal Load = TotalInput × (ValidSplitCount / TotalAtoms)Loop-Back Volume = TotalInput × (LoopBackCount / TotalAtoms)
Belt Choke Detection: If the internal load exceeds the belt speed limit, the solver switches to a Distributed Loop-Back — it pre-splits the input N-way and runs N parallel injection mergers, keeping each sub-array within belt limits.
When used: Total atom count exceeds 100. A physical balancer would need thousands of machines — completely unbuildable.
Solution: Smart Splitter Overflow Manifold. Each Smart Splitter's Center output feeds one platform's ISC (set to "Any"), while the Overflow output carries remaining items to the next splitter. The ISC buffers create back-pressure that achieves perfect steady-state equilibrium within 2–3 train cycles.
Priming required: Let buffers fill to 100% before starting trains, so back-pressure distributes items correctly from the start.
Key Helper Algorithms
GCD (Greatest Common Divisor)
Uses the Euclidean algorithm iteratively: while (b) { [a, b] = [b, a % b]; }. Applied to an array via reduction. Portions are scaled to integers (×1000) before GCD to avoid floating-point issues.
Split Tree Factoring
_findSplitTree(totalRate, targetSlices) — Factors a number into a sequence of 2s and 3s. Returns null if impossible. For example, 6 → [3, 2] (split 3-way, then each 2-way = 6 outputs). 12 → [3, 2, 2]. Sorted with larger factors first for efficiency.
Physical Splitter Count
For a split tree like [3, 2] (6-way): Level 1 = 1 splitter (3-way), Level 2 = 3 splitters (2-way each) = 4 physical splitters total. Formula: iterate tree, count = 1 at first level, multiply by factor for each subsequent level.
The Complexity Guard
Sometimes the math produces ratios that would require an absurd number of physical machines. For example, if three platforms need portions of 137, 211, and 102 items/min from a single belt, the GCD-based atom decomposition might require a 450-way split — meaning hundreds of cascading Splitters and Mergers that would be physically impossible to build in-game.
The safety valve: The Fractional Balancer Solver has a built-in Complexity Guard. If the calculated atom count exceeds 100 parts, the solver automatically abandons the symmetrical balancer approach entirely. Instead, it generates a much simpler Smart Splitter Overflow Manifold — a compact chain of Smart Splitters where each one pulls the exact amount needed via back-pressure, and the overflow continues to the next platform.
How the manifold works:
- The belt feeds into the first Smart Splitter. The Center output is set to "Any" and connects to an ISC buffering Platform 1. Back-pressure from the ISC naturally limits flow to the exact required rate.
- The Left or Right output is set to "Overflow", which carries all remaining items to the next Smart Splitter in the chain.
- This repeats for each platform. The last platform in the chain receives whatever is left — no splitter needed.
- Priming required: The manifold needs all ISC buffers to fill to 100% before the system reaches steady-state equilibrium. This typically takes 2–3 complete train cycles.
In plain English: If the calculator can't build a neat symmetrical balancer without going insane with machines, it switches to a design that uses game physics (back-pressure) to achieve the same perfect distribution with just a few Smart Splitters. You'll see a note in the build guide when this happens, explaining why the simpler design was chosen.
The Destination Solver distributes items from freight platforms to factory lines using a cascading overflow manifold pattern with Smart Splitters and Consolidator ISCs.
The Cascading Overflow Manifold
At the destination, every freight platform unloads into a buffer ISC. Output A feeds a factory line directly (via back-pressure). Output B carries the remainder into a cascading chain of Smart Splitters and Mergers that serve the remaining factory lines.
If a factory line demands more than the belt speed (e.g., >480/min on Mk.4), it's split into multiple parts. For example, a 720/min demand becomes "Factory Line 1 (Part 1)" at 480 + "Factory Line 1 (Part 2)" at 240. Requirements are sorted descending — largest first.
For each ISC (sorted by load, descending), check if the largest unsatisfied requirement fits within a single belt. If so, assign it to Output A. The factory line pulls items via back-pressure, and Output B naturally carries the remainder.
ISC.OutputA → FactoryLine (pulls req.rate via back-pressure)ISC.Remainder = ISC.TotalRate − req.rate → OutputB
Critical check: The projected remainder must fit on a single belt (≤480). If it doesn't, this ISC is skipped and handled by the cascade pool instead.
All ISC remainders (from Output B) and unused ISC outputs are added to a "source pool." Local factory inputs are also available but deferred — they're only consumed when ISC remainders can't satisfy a requirement.
Deferred Local Injection: The old algorithm eagerly dumped local belts into the first merger, wasting train-carried items. The fixed version consumes ISC remainders first, adding locals only when needed.
For each unsatisfied requirement, the solver tries these cases in order:
Case A — Single Source Fit: A single remainder ≥ the requirement. Use a Smart Splitter: Center="Any" feeds the factory line, Overflow carries the excess back to the pool.
Case B — Multiple Sources (≤ belt limit): Combine multiple remainders (and locals if needed) via Mergers. If the combined total exceeds the requirement, add a Smart Splitter to extract the exact amount.
Case C — Belt Limit Exceeded (Consolidator ISC): When combined sources exceed the belt speed limit, they can't be merged onto a single belt. Instead, they're routed into a new ISC's two ports (each ≤ belt speed). The ISC internally consolidates the flow and Output A feeds the factory line.
If a Consolidator ISC's remainder exceeds the belt limit on Output B, the solver redistributes: Output A overdraws (pulls more than the factory needs), and a Smart Splitter on Output A extracts the exact requirement, pushing the overflow back into the cascade. This keeps Output B within belt limits.
When routing multiple sources into a Consolidator ISC, they must be split across 2 ports (each ≤ belt speed). The solver uses greedy balanced partitioning: sort sources descending, assign each to the port with the lower total, preferring the port that stays under the limit.
The RtD Analysis Engine evaluates whether your train's Round-Trip Duration is too fast, too slow, or just right for your specific platform loads.
Zone Boundary Computation
globalMinRtD = max(minRtD for each platform)globalMaxRtD = min(maxRtD for each platform)tightStart = globalMinRtD × 1.2safeEnd = globalMaxRtD × 0.8
The system takes the tightest constraints across all platforms. If one platform needs a minRtD of 200s and another needs 300s, the global minimum is 300s (the most restrictive). Similarly, the global maximum is the smallest maxRtD across all platforms.
Zone Classification Logic
Per-Platform Analysis
For each platform, the engine computes:
- Load — Actual items/min flowing through this platform
- Belt Speed — min(load, DualBeltMax) — can't exceed the physical belt limit
- TtF — Time to Fill for this platform's freight car
- Actual Throughput — min(load, ceiling, freightLimit) at the current RtD
- Individual minRtD / maxRtD — This platform's own danger and overflow boundaries
- Utilization % — How loaded this platform is relative to the dual-belt max
- Is Over-Saturated — Whether TtF < RtD (fully loaded) or TtF ≥ RtD (semi-loaded)
The original calculator had a critical bug: it applied the lockout formula ((RtD − 27.08) / RtD) × actualLoad to penalize the actual throughput — as if the lockout "taxed" every item. This is WRONG. The lockout formula gives the ceiling — the maximum the platform can sustain. If your load is below the ceiling, your throughput IS your load. The fix: actualTP = min(load, ceiling, freightLimit).
Fluid mode is a completely separate calculation engine (fluid.js) that handles liquid transport. It's simpler than solids because pipes auto-level via fluid pressure — no fractional balancers or smart splitters needed.
Key Differences from Solid Mode
| Aspect | Solid Mode | Fluid Mode |
|---|---|---|
| Transport | Belts (Mk.4/5/6) | Pipes (Mk.1/Mk.2) |
| Speed per pipe/belt | 480 / 780 / 1200 items/min | 300 / 600 m³/min |
| Dual max per platform | 960 / 1560 / 2400 | 600 / 1200 m³/min |
| Freight car capacity | StackSize × 32 (varies) | Fixed: 2,400 m³ |
| Distribution method | Splitters + Mergers | Junction Crosses (auto-level) |
| Fractional balancers | Yes (complex) | Not needed (pipes auto-balance) |
| Buffer architecture | ISC per platform | Dual Junction Buffer Sandwich |
The Dual Junction Buffer Sandwich
The Problem: A single Mk.2 pipe can only carry 600 m³/min. If you connect a single pipe from the platform to the buffer, you create a 600 m³/min bottleneck — even though the platform can output 1,200 m³/min through its dual ports.
The Solution: Place Pipeline Junction Crosses directly on the Platform Ports. Connect the Industrial Fluid Buffer in parallel through both junctions. This allows fluid to flow at up to 1,200 m³/min total, bypassing the single-pipe bottleneck.
Catch-Up Bandwidth Math
CatchUpBandwidth = DualMax − AverageLoadLockoutLoss = AverageLoad × (27.08 / 60)CatchUpTime = (LockoutLoss / CatchUpBandwidth) × 60
During the 27.08s lockout, the factory continues consuming fluid. The buffer must hold enough to cover this gap. After the lockout, the platform can push fluid at the full dual-pipe speed (1,200 m³/min), giving a catch-up bandwidth of DualMax − Load. The catch-up time tells you how quickly the buffer recovers.
Fluid Source Solver
Uses greedy bin-packing (simpler than solid mode's deficit-based approach). Pipes are sorted largest-first and assigned to the least-loaded platform. This works because pipes auto-level — you don't need fractional splitting.
Fluid Formulas
C_max = ((RtD − 27.08) / RtD) × DualPipeMax
Same formula as solid mode, but using pipe speeds instead of belt speeds. For Mk.2 pipes (dual max = 1,200 m³/min) at RtD = 300s: C_max = ((300 − 27.08) / 300) × 1200 ≈ 1,091.7 m³/min.
FreightLimit = 2400 / RtD_min
Each fluid freight car holds exactly 2,400 m³. Divide by RtD (in minutes) to get the sustained throughput per car. At RtD = 300s (5 min): 2400 / 5 = 480 m³/min per car.
The dashboard overlay (dashboard.js) hooks into the main recalculate() function and updates the 8 stat cards in the System Overview panel. Here's how each one is computed.
sum(all source belt rates)Simple sum of all active source belt/pipe values. Displayed in items/min (solid) or m³/min (fluid).
((RtD − 27.08) / RtD) × DualMaxPer-platform ceiling. Color: green if highest platform load ≤ ceiling, red if exceeded. Shows "N plat × ceiling = total" as subtitle.
Locomotives = ceil(NumPlatforms / 4)Ratio = floor(NumPlatforms / Locos)One locomotive per ~4 freight cars (game recommendation). Shows "N Locomotive(s) + M Freight Cars (1:R ratio)".
tightStart – safeEndThe goldilocks zone formatted as "Xm Ys – Xm Ys". Green if current RtD is inside the window, yellow if outside.
Classifies the current RtD into one of the 5 zones (Danger, Tight, Optimal, Safe, Overflow) using the zone boundaries from the RtD Analysis Engine. Color-coded to match the zone severity.
TtF = (Capacity / BeltRate_sec) + 27.08if TtF ≥ RtD → "Semi-Loaded"if TtF < RtD → "Fully-Loaded"Uses the highest platform load to determine TtF. Shows "TtF Xm Ys vs RtD Xm Ys".
max((platformLoad / DualMax) × 100)The highest platform utilization across all platforms. Red if >90%, yellow if above safety threshold, green otherwise.
EffectiveSupply = ActualTrainTP + LocalTotalDelta = EffectiveSupply − TotalDemandNote: Uses actual train throughput (accounting for ceiling and freight limits), not the raw source total. Shows "✓ Balanced", "+N surplus", or "-N deficit".
System Status Banner
The banner aggregates all issues into three severity levels:
- 🟢 System Pass — No issues. Shows total capacity vs demand.
- 🟡 System Operational — Warnings — Non-critical issues (surplus, high utilization, non-optimal RtD zone).
- 🔴 System Issues Detected — Critical problems (deficit, danger zone, capacity ceiling exceeded).
The calculator's codebase originally contained four critical engineering flaws that have been corrected. Understanding these fixes explains WHY the formulas work the way they do.
TP = ((RtD − 27.08) / RtD) × actualLoadApplied the lockout formula to the actual load, treating it as a "tax" that reduced throughput proportionally. A 500/min belt would be "penalized" to 477/min even though 500/min is well below the platform's physical limit.
Ceiling = ((RtD − 27.08) / RtD) × DualMaxTP = min(Load, Ceiling, FreightLimit)The lockout formula calculates a CEILING using the platform's maximum speed (e.g., 960), not the actual load. If your load is below the ceiling, your throughput equals your load — no penalty.
The old algorithm assumed splitters could divide items in arbitrary ratios (e.g., 60/40 split). In reality, Satisfactory splitters ONLY divide equally: ½ or ⅓.
All splits strictly follow game mechanics. Unequal distributions are achieved through chains of legal ½ or ⅓ splitters combined with mergers — the Fractional Balancer Solver (Section 5).
The old destination solver merged remainders and local belts onto a single belt without checking if the combined rate exceeded the belt limit (e.g., >480/min). This is physically impossible in-game.
When combined sources exceed the belt limit, the solver generates a Consolidator ISC instruction. Sources are routed into the ISC's two ports (each ≤ belt limit), and the ISC internally consolidates the flow.
Local factory belts were immediately merged with train remainders at the first opportunity, often creating belt limit violations and suboptimal routing.
Local belts are held in reserve. ISC remainders are consumed first. Local belts are injected only when remainders alone cannot satisfy a requirement. This minimizes belt-limit violations and optimizes routing.