Skip to content

Link Logistics

Link logistics extends the hauler role. It does not replace conventional hauling and does not activate from RCL alone.

Runtime Rule

A link-assisted route is usable only when completed visible structures form a specific route:

source -> planted harvester -> source link -> storage link -> storage

Construction sites, planned structures, and unclassified links are not runtime participants. The infrastructure plan may explain intended topology, but current completed structures are the source of truth.

The shared logistics-network adapter can represent planned preferred link endpoints before they are runtime participants. Route IDs use semantic source and storage identity rather than the current link object IDs, so the same route identity survives planned, approved, site-present, completed, damaged, missing, and restored infrastructure. The route's infrastructure summary keeps those component states separate from its logistics lifecycle.

Classification

room/links classifies owned completed links from visible topology:

  • source: within configured source-link range of a source
  • storage: within configured storage-link range of owned Storage
  • controller: within configured controller-link range of the owned controller
  • unclassified: no safe topology match

This patch uses source-to-storage routes for hauler service jobs. Controller links remain available to existing upgrader withdrawal behavior and LinkManager transfer policy, but hauler controller-link service is deferred.

Jobs

workflows/linkLogistics creates focused energy jobs:

  • A planted local harvester transfers its carried energy into the adjacent source link while continuing to issue its harvest intent. Screeps permits harvest and transfer in the same tick; both use the tick-start state.
  • load-source-link remains a compatibility fallback only when the completed harvester-serviced topology is unavailable.
  • unload-receiver-link: withdraw from a storage receiver link and transfer to owned Storage when Storage has free capacity.

Jobs carry a stable id, kind, source id, destination id, route id, amount, priority, and reason in creep memory. A loaded hauler continues its assigned job while the destination remains valid, even if the source-side threshold changed after withdrawal.

Priority And Fallbacks

Haulers keep the existing gather/deliver state machine. The compatibility load-source-link job retains its existing position ahead of ordinary acquisition. Receiver unloading is different: an ordinary hauler considers it only when no useful conventional acquisition or delivery target remains. Urgent spawn, Extension, and Tower delivery always preempts receiver service.

When direct source-link service leaves ordinary source containers empty, urgent spawn, Extension, or Tower demand may use Storage as a bounded acquisition fallback. The withdrawal still obeys the operating-reserve policy, so haulers can use only energy above the protected minimum. This fallback does not disable receiver-link service and does not authorize routine Storage withdrawals.

A hauler born for storage-link service is recalled ahead of other nonurgent local work, while still helping with that ordinary work when pressure is absent:

urgent spawn/extension/tower demand
retained useful conventional assignment
ordinary acquisition or delivery
receiver-link service before idle

Receiver service enters at 400 energy and a retained lease continues down to 100 energy. This hysteresis prevents repeated assignment churn around the entry threshold. Only one hauler can own the receiver lease. If a specialist exists, ordinary haulers defer to it when pressure returns.

A partially loaded hauler with no useful delivery target resolves its carried energy into Storage before withdrawing from the receiver. Its stale local-route assignment and load provenance are cleared, so mixed cargo is not represented as a receiver-link collection and same-source energy-echo protection remains intact.

If the completed source or downstream link topology disappears, conventional source-container hauling becomes eligible again. A transient full receiver or link cooldown does not resurrect creep hauling; the source container buffers energy until the link cycle resumes. Rooms with no links, planned-only links, one source link without a receiver, or partial source coverage continue working conventionally.

The preferred link route records the stable conventional creep route as its fallback. A missing optional source or receiver link therefore reports degraded preferred infrastructure while fallbackUsable remains true when the creep route is operational or degraded and economy policy permits it. A missing critical source container is different: it blocks infrastructure support for both forms rather than making planned link intent look usable.

The shared route treats the receiver link as a transit endpoint. Capacity below linkMinimumReceiverFreeCapacity is not serviceable receiver demand. When that receiver blocker is present, source backlog remains obligated only if owned Storage can accept the conventional fallback; fallback demand is bounded to the source backlog and expected throughput retains the nominal post-loss link rate. Without Storage acceptance the blocked route is terminally idle, even if the receiver has a small residual gap below the threshold. When the receiver meets the threshold, its free capacity alone bounds expected link throughput and Storage capacity does not inflate the preferred route expectation.

Fallback performance is execution evidence, not readiness or preemption evidence. A positive successful conventional delivery increments fallback telemetry on the blocked link route only when the completed local route ID matches its fallbackRouteId and the parent route carries a receiver blocker. Urgent conventional preemption still suspends the optional route job and increments preemptedAssignments, but it does not emit a fallback completion.

LinkManager remains the only owner of transferEnergy() and of parent link-route delivered/completed performance events. It identifies source links and valid receivers, respects cooldown and capacity, and records per-tick transfer results. Haulers do not coordinate link-to-link transfers; they only move energy into source links and out of receiver links. Those staging actions advance assignment lifecycle and dedicated link-service counters without claiming parent route throughput or completion.

Population And Bodies

Receiver pressure creates work demand first. While Storage can accept energy, an execution-eligible living local hauler or an assigned receiver lease suppresses all extra population demand. Ordinary haulers are not considered available while urgent spawn, extension, or tower delivery gates link service. If the receiver remains at or above 400 energy for 50 consecutive population evaluations while every living local hauler is occupied or urgent-delivery gated, the population plan may authorize one additional service slot. Clearing pressure, finding an available hauler, or assigning the lease resets that bounded pressureSince/lastEvaluatedAt evidence; no history is retained.

The authorized service body is the bounded short-distance [CARRY, CARRY, MOVE] body. It remains role hauler and carries a lifetime storageLinkServiceHome identity. Its carry capacity and temporary ordinary work are excluded from general and remote-hauler capacity accounting. While it is effective, receiver-link service is its primary duty even while ordinary haulers are urgent-delivery gated. Its service slot remains distinct so loss of a general hauler is still replaced; after the specialist retires, it is not replaced unless sustained receiver pressure earns the slot again. A link's mere existence never creates population demand.

Pressure evaluation runs once with the normal per-room population plan and uses the already classified storage links, primary Storage, and grouped hauler context. It performs no room scan or pathfinding. Its planning cost is included in cpu.profile.rooms.<roomName>.sections.spawnManager; execution remains in the existing hauler.linkJobSelection and hauler.taskExecution sections.

Telemetry

Memory.stats.rooms[roomName].links includes link counts, route mode, transfer attempts, sent/received/lost energy, usable and blocked route counts, cooldown blocks, receiver blocks, and cumulative route totals.

Memory.stats.rooms[roomName].haulers includes per-tick conventional delivery selections, link-service job selections, blocked link jobs, and whether link-service haulers were active, moving, or idle.

Debugging

Use:

debug.links("E48N13")
debug.logistics("E48N13")
debug.creep("Hauler123")

debug.links() shows classification and transfer pressure. debug.logistics() shows route readiness, available link jobs, assigned haulers, and the current hauler link-service counters. debug.creep() includes the assigned logisticsJob when present.

The shared network view is available through debug.logisticsNetwork(), debug.logisticsNodes(), debug.logisticsRoutes(), and debug.logisticsRoute(routeId). These helpers adapt link-assisted routes into the shared route contract but do not change link transfer or hauler behavior. Full shared-network derivation is cadence-bounded, so this debug route state may lag live link state by up to the configured logistics-network evaluation interval. Route lines include preferred infrastructure state, critical endpoint state, planned/site/completed/missing/damaged component counts, fallback usability, and the last infrastructure validation tick.

Successful direct link transfers are attributed to the stable parent link route ID. Source-container loading and receiver unloading remain staging telemetry; they do not duplicate parent throughput or completion. The shared route performance summary therefore compares expected and delivered link throughput, records LinkManager completion and blocked conditions, and distinguishes the preferred link path from successful conventional creep fallback. These observations do not change link classification, transfer authority, or hauler target selection.

Future Extraction Boundary

The hauler role still owns execution. The link logistics workflow owns job creation and validation. This makes a future local logistics role possible without changing harvester behavior or removing conventional hauler transport.