Rail Logistics Daemon (RLD)


UPS-first train logistics for megabases: tag stops as providers, requesters, and depots, set thresholds, and RLD dispatches trains for you. Event-driven with no per-tick polling, native chain deliveries, item quality and fluid support, multiple networks, a live dashboard, and one-command in-place LTN migration. Factorio 2.0: stable 1.0.x. Factorio 2.1: 2.0.x BETA — feedback welcome!

Content
2 hours ago
2.0 - 2.1
122
Trains

Changelog

Version: 2.0.9
Date: 2026-08-22
  Bugfixes:
    - Switching the dispatcher mode no longer notifies every other mod when nothing actually changed (re-selecting the active mode, or a redundant remote call). Some third-party mods crash with a chat error on those notifications; a real mode change still notifies as the game requires.
  Info:
    - This is the Factorio 2.1 line. Same code as RLD 1.0.9, built from the same commit.
Version: 1.0.9
Date: 2026-08-22
  Bugfixes:
    - Switching the dispatcher mode no longer notifies every other mod when nothing actually changed (re-selecting the active mode, or a redundant remote call). Some third-party mods crash with a chat error on those notifications; a real mode change still notifies as the game requires.
Version: 2.0.8
Date: 2026-08-21
  Features:
    - Fluid thresholds can now differ per side: new Provide Fluid Threshold and Request Fluid Threshold fields (and matching circuit signals) override the shared Fluid Threshold for their side. Leave them unset and nothing changes - the shared field keeps gating both sides as before.
  Info:
    - This is the Factorio 2.1 line. Same code as RLD 1.0.8, built from the same commit.
Version: 1.0.8
Date: 2026-08-21
  Features:
    - Fluid thresholds can now differ per side: new Provide Fluid Threshold and Request Fluid Threshold fields (and matching circuit signals) override the shared Fluid Threshold for their side. Leave them unset and nothing changes - the shared field keeps gating both sides as before.
Version: 2.0.7
Date: 2026-08-16
  Bugfixes:
    - Deleting a train no longer leaves it listed in the Manager as "Unknown". Those leftover rows also counted against the fleet totals on the Depots tab, so the train and capacity numbers were too high.
    - Hardened the icon tinting against a future base-game change that gives the train stop or combinator layered icons. Nothing looked wrong before and nothing changes now.
  Info:
    - This is the Factorio 2.1 line. Same code as RLD 1.0.7, built from the same commit.
Version: 1.0.7
Date: 2026-08-16
  Bugfixes:
    - Deleting a train no longer leaves it listed in the Manager as "Unknown". Those leftover rows also counted against the fleet totals on the Depots tab, so the train and capacity numbers were too high.
    - Hardened the icon tinting against a future base-game change that gives the train stop or combinator layered icons. Nothing looked wrong before and nothing changes now.
Version: 2.0.6
Date: 2026-07-30
  Features:
    - Alerts about a held train now carry a Release button right in the message, so putting the train back in service is one click instead of typing /rld-release. The button only appears while the train is actually still held.
    - The Manager now reopens on the tab you last used instead of always starting at Stations. Per player; remembered across sessions with the save.
  Bugfixes:
    - The RLD train stop and RLD Combinator icons now carry the same amber shading as the placed buildings. Inventory, crafting menu, cursor, ghosts, and blueprints previously showed the vanilla-colored icons.
    - A stop whose combinator has neither Provider nor Requester (nor Depot) enabled now shows the red "disabled" lamp instead of a healthy white. A stop with no role can never dispatch, so the lamp now says so.
    - The amount overlay on cargo slots ("-100k") is now bold with a black outline, so it stays readable over bright item and fluid icons. Applies to the combinator GUI and the Manager's slot grids.
    - "Disable warnings" on a stop now also suppresses its "no provider" and "no train" starvation alerts - the one warning family that ignored the checkbox. Fleet-level alerts (duplicate names, held-train reminders, low fuel) are deliberately not affected.
    - The "Unload stuck timeout" setting tooltip still described the old behavior (train leaves with its leftover). It now says what actually happens: an empty train leaves; a train still carrying cargo is held at the stop per "Hold trains with leftover cargo".
    - Setting an item threshold on a stop now actually applies. Before, the default stack threshold always won, so a "Provide Threshold 1000" stop still gated at 40 stacks and hovered "gate 4000". An explicit override now beats the other unit's default; the combinator GUI refuses to save both an item and a stack threshold on the same side (red message, Apply disabled), counting a threshold left at 0 as unset. Fluid thresholds are unaffected.
    - The stop hover showed the requester-side gate on provider lines. It now shows each role its own gate.
  Info:
    - This is the Factorio 2.1 line. Same code as RLD 1.0.6, built from the same commit.
Version: 1.0.6
Date: 2026-07-30
  Features:
    - Alerts about a held train now carry a Release button right in the message, so putting the train back in service is one click instead of typing /rld-release. The button only appears while the train is actually still held.
    - The Manager now reopens on the tab you last used instead of always starting at Stations. Per player; remembered across sessions with the save.
  Bugfixes:
    - The RLD train stop and RLD Combinator icons now carry the same amber shading as the placed buildings. Inventory, crafting menu, cursor, ghosts, and blueprints previously showed the vanilla-colored icons.
    - A stop whose combinator has neither Provider nor Requester (nor Depot) enabled now shows the red "disabled" lamp instead of a healthy white. A stop with no role can never dispatch, so the lamp now says so.
    - The amount overlay on cargo slots ("-100k") is now bold with a black outline, so it stays readable over bright item and fluid icons. Applies to the combinator GUI and the Manager's slot grids.
    - "Disable warnings" on a stop now also suppresses its "no provider" and "no train" starvation alerts - the one warning family that ignored the checkbox. Fleet-level alerts (duplicate names, held-train reminders, low fuel) are deliberately not affected.
    - The "Unload stuck timeout" setting tooltip still described the old behavior (train leaves with its leftover). It now says what actually happens: an empty train leaves; a train still carrying cargo is held at the stop per "Hold trains with leftover cargo".
    - Setting an item threshold on a stop now actually applies. Before, the default stack threshold always won, so a "Provide Threshold 1000" stop still gated at 40 stacks and hovered "gate 4000". An explicit override now beats the other unit's default; the combinator GUI refuses to save both an item and a stack threshold on the same side (red message, Apply disabled), counting a threshold left at 0 as unset. Fluid thresholds are unaffected.
    - The stop hover showed the requester-side gate on provider lines. It now shows each role its own gate.
Version: 2.0.5
Date: 2026-07-28
  Features:
    - Factorio 2.1 support (BETA). Same mod, same features as 1.0.4 - this line (RLD 2.0.x) is for Factorio 2.1, while RLD 1.0.x remains the stable line for Factorio 2.0.
  Info:
    - This build passed a full API audit but has not yet been play-tested on 2.1. Please report anything odd - especially trains leaving a held/quarantined state on their own - on the mod portal discussion board or the GitHub issues page.
Version: 1.0.4
Date: 2026-07-27
  Features:
    - Two new sortable columns on the Stations tab. Dwell: the rolling average time trains spend loading/unloading at each stop, so slow stations that hold up the fleet sort straight to the top. Health: flags providers that have had nothing to offer for a while ("low") and requesters throttled by their own max-trains limit ("capped").
    - New Deliveries tab in the Manager: every delivery in flight on one sortable page - cargo, route, train, state, age, and network. Route names teleport-link like the Stations tab, the train id opens the vanilla train window, and the default sort puts the longest-running delivery on top so a stuck one is the first thing you see.
    - The Depots tab now shows fleet utilization: what share of the last hour your trains spent idle at depots, traveling, loading/unloading, or chaining in the field. Mostly idle means you own more trains than the base needs; near-zero idle means build more.
    - The Manager's Stations tab now shows how long a starved stop has been waiting, right in the status word - "starved (97s)". Sorting the Status column puts the longest-waiting stops first, so the tab doubles as a what's-about-to-break list.
  Changes:
    - The Manager's History and Alerts tabs now draw a separator line between rows, matching the Stations and Trains tabs.
  Bugfixes:
    - A train stop renamed out of a duplicate-name conflict kept its pink duplicate lamp even though RLD had already resumed dispatching to it. The lamp now clears as soon as the name is fixed.
    - The "Locked Slots per Wagon" setting now actually works. It was accepted (and imported from LTN) but never applied, so trains were sized as if every wagon slot were usable. Providers with locked slots now dispatch correspondingly smaller loads.
Version: 1.0.3
Date: 2026-07-26
  Features:
    - Dispatch-cycle slicing is now ON by default: the dispatcher spreads its matching work across the interval instead of doing it all on one tick. Same deliveries, same behavior - only the tick-cost shape changes. On a 2,000-stop base the worst tick dropped 17.9ms -> 11.5ms with no change in average cost. Set "Dispatch slice requests" to 0 for the old single-tick cycle.
      UPGRADING: saves still on the old default are switched to 5 automatically on first load and told so. If you had already set a value yourself, it is left alone.
    - The dispatcher on/off control is now three-way: On, Pause (hold new orders, trains stay put), and Full Stop (trains return to depot, no new orders). Deliveries already in flight always finish.
      UPGRADING: if your dispatcher is currently OFF, RLD converts the save to Full Stop on first load and tells you.
    - Hover a train stop to see what RLD reads from it: the netted amount on its wire, whether it is requesting or offering, and how far it is from the threshold that triggers a delivery. A stop with nothing on its wire says so, which makes a miswired station obvious at a glance.
    - Held trains no longer go quiet and get forgotten. A held train is out of service until you run /rld-release, so RLD now re-alerts once one has been held longer than "Remind about held trains" (default 15 minutes) and repeats until it is released. Set it to 0 to turn reminders off.
    - Alerts clear themselves when the problem is fixed - a starved stop that gets a delivery, a released train, a renamed duplicate stop. Resolved alerts are hidden by default (tick "Show resolved" to see them). The Alerts tab is now sortable by When, Type, and Message.
    - New per-stop "Fluid Threshold" field. Fluids have no stacks, so a stack threshold cannot gate them - previously the fluid gate was a single global setting.
    - Depots tab now shows fleet capacity: how many trains of each type (cargo, fluid, mixed) are free versus in use. A type showing 0 available means the next request for that cargo will starve.
    - Manager polish: dispatcher dropdown with live "Deliveries in flight" and "Trains still traveling" counts (both 0 means the network is quiet and safe to modify), -/+ window size buttons remembered per player, a "Spare depot slots available" readout that goes negative when you have more trains than depot slots, and a "Chaining efficiency" line showing what share of recent jobs went to chaining trains. Clicking a train's id opens it in the normal train window. Train states read as words, cargo shows friendly names, and the Help and Depots tabs word-wrap instead of scrolling sideways.
    - The Manager's Help tab now covers setting up a stop: wiring an RLD Combinator, what the cargo sign means, and what each field does.
    - The LTN conversion dry run now lists providers that would offer nothing - a stop can convert with a clean provider role but have no cargo on its wire, and would then never dispatch. Wire the storage to the stop, or the provider sits idle.
  Changes:
    - Default unload-stuck timeout raised 30s -> 120s. At 30s, stops that were merely slow to unload could trip the leftover-cargo hold and quarantine a healthy train. Saves on the old default are upgraded once and told so; setting it back to 30 sticks.
  Bugfixes:
    - Fixed a crash when a stop still asked for an item or fluid that no longer exists, which can happen after a mod update removes or renames one.
    - Stopping the dispatcher now empties the field properly. A delivery that finished after you stopped it used to park at its station instead of returning to a depot.
    - Removing or renaming a stop mid-delivery no longer strands the train. The delivery is cancelled with an alert and the train returns to a depot - or is held in place if it is carrying cargo.
    - Stops with a duplicate name in the same network are no longer dispatched to. A train sent to one of two same-named stops could dock at the wrong one and loop forever.
    - The "no train" alert now says when the real problem is wagon type ("no idle fluid-capable train available") instead of blaming the train length window.
    - The LTN conversion dry run now warns about trains still carrying cargo. Converting too early leaves those trains loaded with nothing to unload them; the migration guide now has a "let the network go quiet" step.
Version: 1.0.2
Date: 2026-07-24
  Features:
    - /rld-status adopt-report lists trains stuck outside the dispatch pool (state "unknown" — the small set that can linger after an LTN conversion), grouped by why (automatic with no RLD schedule / already heading to an RLD stop / manual mode), each with a clickable [train=] icon and a [gps=] map ping to find it. Bare /rld-status now also shows an "N train(s) in state unknown" line when any exist. Detection is on-demand only (the full fleet walk runs solely when adopt-report is requested) — no per-tick cost. List-only: it never adopts trains automatically (manual trains were parked on purpose; automatic-foreign ones are adopted by running /rld-recycle-trains, which the report points you to).
    - Reproducible benchmark harness (scripts/benchmark/rld_sweep.py + docs/BENCHMARKING.md): drives a headless server over RCON to run per-interval throughput soaks and deterministic timing benchmarks against any save, emitting the standard sweep table. Standard-library Python only; consumes existing commands and the read-only rld remote interface, so its in-engine per-tick cost is zero.
    - Leftover-cargo hold (#20): when the unload-stuck timeout fires with cargo still aboard (the requester asked for more than it can hold, e.g. a 40k request into a 20k warehouse), the train is now HELD in place at the requester instead of returning to service. The stop's requests are suppressed (no more trains are sent to the broken request), and a persistent map alert stays pinned on the train until you fix the stop and run /rld-release <train>. Stops with warnings disabled keep the old release-and-continue, and the whole behavior can be turned off with the new "Hold trains with leftover cargo" setting. Per-tick cost: zero while nothing is held; one bounded alert re-pin per dispatch cycle per held train (typically 0) while one is.
  Changes:
    - Default dispatch interval raised 1s -> 3s. A 1-5s sweep on a 2,000-stop base showed delivery throughput and starvation flat across the whole range (hauls take minutes; seconds of dispatch latency are invisible) while mean per-tick cost and over-budget ticks drop steeply up to 3s. Existing saves keep their current value (change it in Settings or via /rld-set); new games start at 3s.
  Bugfixes:
    - All RLD command output now reaches RCON callers. Previously only /rld-set replied over RCON; every other command (/rld-status, /rld-alerts, /convertLTN-to-RLD, /rld-release, ...) printed via game.print, which is invisible to RCON and lost entirely on a headless server - a remote admin running the LTN conversion got no report at all. /rld-delivery-test's result is deferred past the RCON connection's lifetime, so an RCON caller now gets an immediate ack pointing at the server console/log instead of silence.
    - The alerts remote interface now exposes stop_name. It was stored on every alert but dropped at the list boundary, so a remote consumer could not tell WHICH name a duplicate_stop_name alert fired for.
Version: 1.0.1
Date: 2026-07-23
  Bugfixes:
    - The request threshold is now a minimum SHIPMENT size enforced on every delivery, not just a minimum request size. Previously a large request was split greedily and the last chunk could be tiny (needing 1,700 items at an 800-item threshold shipped 800 + 800 + 100), and a provider left with a few items after in-cycle reservations could win the pick and send a nearly-empty train (observed: a 9-item delivery). Now every shipment carries at least the threshold; a below-threshold leftover waits until the shortfall crosses the threshold again. A threshold larger than every train's capacity surfaces a "no train" alert instead of silently shipping small loads.
Version: 1.0.0
Date: 2026-07-23
  Major Features:
    - Initial release.
    - Provider/requester/depot train logistics: tag stops, set thresholds, and RLD dispatches trains to move cargo where it's needed. Items, fluids, and item quality; multiple networks via ID masks.
    - Native chain deliveries: a freed train goes straight to its next delivery instead of returning to a depot (fuel-gated, default 30%).
    - UPS-first engine: event-driven, dirty-flagged scanning with an adaptive scan slice and quiet-stop cadence backoff — per-tick cost stays flat as the base grows.
    - RLD Manager: a tabbed dashboard (Stations, Depots, Trains, Deliveries, History, Alerts, Help) that costs nothing while closed.
    - Guided in-place migration from an existing LTN base (/convertLTN-to-RLD): swaps each stop in place and preserves all circuit wiring.