RailCommand Operating Sessions (Running Trains)

Last updated: August 27, 2026

Concept

An operating session is where a RailCommand layout actually runs trains — it brings together the layout, trains, routes, schedules, crews, and the live runtime. Every session sits on one richness dial (SessionRichness), and you CHOOSE it when you create the session — it is never inferred from how complete the layout is: Arcade is museum "pick-up-and-run" — trains follow their routes on the fast clock with roles auto-filled and no paperwork; Operating-Session is the full club/prototype op — the same trains and routes, now with crew roles, jobs, car-forwarding, switchlists, and dispatcher warrants. This is not two code paths. It is one Operations Engine (OperationsEngine.ExecuteAsync); the dial only turns bureaucratic preconditions on or off (SessionProfile). It never relaxes the safety floor. Because Arcade has no crew, jobs or paperwork, an Arcade session mints no Crew authority at all - that absence is what Arcade IS, not a failure, and it is why a session's richness is chosen at run time and is never derived from the layout or carried as a permission by a package (ADR-0257). Each train is either computer-driven or human-driven and can be switched live mid-run, but both flow through the identical interceptor, movement-authority window, and interlocking kernel. The browser throttle never treats a server simulation projection as physical proof: motion and functions are enabled only when its primary relay, separate priority emergency-stop relay, and exact live UE probe are all ready, and displayed state changes only after an authoritative host/UE acknowledgement.

Starting a new desktop operating session also requires valid server-signed RailCommand operating access. Connected operation and a mounted .rspkg use the same subscription-expiry-plus-30-day deadline; the five-day period is an advance warning, not the operating cutoff. This commercial check is made at the new-session boundary. A package-license refresh is bound to the exact signed-in organization, selected layout, mounted package object, and file bytes that began it; if any of those changes while the relay or activation is in flight, the response is discarded and the newly current package is left untouched. A session already admitted is never interrupted just because the deadline passes or the network disappears. If the desktop and its supervised UE child restart, one exact nonterminal local-package session can continue only through its encrypted, package-bound admission receipt; a different package, layout, session, terminal session, missing receipt, or unreadable receipt must start through the ordinary entitlement check and fail closed when access has ended.

Crew Call is the assignment gate inside that admitted session. Exact admitted Host, Dispatcher, Crew Caller, and Yardmaster roles can manage Crew Call; other participant states fail closed. A human call revalidates the accepted host relationship, exactly one paid coverage source, qualification, hours-of-service, availability, exact session, and assignment conflicts. A valid NPC can be called without a user, seat, device, or QR, but it receives the same exact-session assignment and release fencing. Human QR is only a one-time device handoff for an already committed human assignment; possession of a QR cannot create a participant or assignment.

An operational schema-3 package is issuer-signed to the target install identifier and public key, exporting user, PlantSession, Operating-Session richness, immutable Crew base, and mutation-chain genesis; an unbound package is diagnostic only. The package ends with one install-signed final completion record only after every Human and NPC authority projection is clear. That terminal evidence can be recovered and imported after the operating deadline because it reconciles already-ended authority rather than authorizing new work. Recovery re-verifies the exact package, install, signed mutation chain, final zero-authority state, and completed session; it never mounts the expired package or grants operation, reseal, or actuation capability.

How To

  1. Open Operating Sessions at /app/railcommand/operating-sessions. Existing sessions show a status badge (Planned, Active, Paused, Completed, Cancelled) and participant count. Click New Session from Layout.
  2. On Create Operating Session (/app/railcommand/operating-sessions/create): enter a Session Name, pick the layout (starting from the Layout Hub inherits era, integration mode, and theme), choose the session mode (Arcade, or the full Operating session — the panel pre-selects whichever the layout is marked for, and either is one click away), choose a Session Type (Solo, Collaborative, Competitive, Training), set Max Participants (1–50), then Create Session. If the chosen layout has devices that are not yet configured for automation — for example turntables imported but not yet completed in the editor — an amber informational banner lists them. It is advisory only: it does not gate session start. You can create and run the session for arcade/freeform play unaffected; the flagged devices just will not participate in full automation until you configure them in the layout editor.
  3. Before physical controls open for a new desktop session, RailCommand validates the signed operating entitlement from the connected license or the exact mounted .rspkg. If access is outside its inclusive operating deadline, reconnect and refresh the package or subscription from the website. If an already-admitted package session is resumed after a desktop/UE restart, RailCommand accepts only the encrypted receipt for that exact package, layout, and nonterminal session, then rotates the receipt and safety generation before exposing controls. A signed terminal package uses the separate recovery-only path and can never resume operation.
  4. On the session page (/app/railcommand/operating-sessions/{SessionId:guid}) use Join, call eligible Human or NPC principals from Crew Management at /app/railcommand/crew, and drive lifecycle with Pause, Resume, and End Session. Human calls revalidate relationship, coverage, qualification, service, availability, session, and conflicts; NPC calls never mint a QR. End from the owning Avalonia station when possible so UE authority is removed before the terminal round trip. A web completion atomically releases the server authority ledger and stages exact host-generation fences; if it reports that a fence is queued, completion is durable but local physical release is still awaiting the exact host acknowledgement.
  5. On the session page, switch between the Overview tab (participants and lifecycle) and the Build Reports tab — a leveled, filterable log of why each train was built the way it was, filtered by severity and by build stage, with an optional Detail view for per-car reasoning. Toggling filters re-renders instantly and never rebuilds the trains.
  6. To dispatch, open Dispatcher at /app/railcommand/dispatcher, then Open CTC Panel (/app/railcommand/layouts/{LayoutId:guid}/ctc-panel). Click Set Route, then click the entrance signal and the exit signal to lock a route. The sidebar's Slow Orders section is the dispatcher's speed-restriction desk: issue or deny maintenance-of-way requests, impose a restriction directly, and lift one when the track is restored (requests originate from /app/railcommand/layouts/{LayoutId:guid}/slow-orders). Slow orders are operating paperwork and display — they do not gate movement authority. On large layouts the whole control sidebar collapses behind the thin rail button at its edge (and reopens the same way), giving the schematic the full width — the same affordance the desktop CTC panel has. A panel may also carry freestanding indicator lamps: click one on the CTC panel and it turns on or off for every viewer of the session, the way a panel's on/off lamp works on a real board. The lamp is panel display state — it drives no hardware, binds to no block or signal, and grants no authority. A lamp the session has said nothing about is drawn unknown (a dashed lens), not off: lamp state is not replayed when you join, so a dispatcher who opens the panel after a lamp was set sees unknown until it is toggled again, and the panel deliberately drops back to unknown after a reconnect rather than keeping a possibly-stale reading. On the Avalonia desktop every lamp reads unknown today — the desktop has no lamp-state channel yet.
  7. To run a train, open a throttle at /app/railcommand/throttle/{LocomotiveId}. Wait until it reports that the primary relay, priority emergency-stop relay, and exact live UE state are ready. Choose Forward or Reverse, then set Speed from 0–128: step 0 is controlled stop, step 1 is reserved for emergency stop and is skipped by the ordinary slider, and step 2 is the lowest running step. A requested speed remains visibly pending until UE returns the exact safety-clamped aggregate state; a refusal restores the last confirmed state. Function buttons likewise show only aggregate acknowledgements from every routed consist target. Hand a train between computer- and human-driven as needed; the handoff changes the intent source, not the safety path. If a commander loses standing mid-run — the hours-of-service ceiling is reached, the runtime clock is halted, or a lease turnover leaves a moving train with nobody claiming it — RailCommand brings that train to a controlled, graceful stop through the normal speed path (never an emergency stop); a commercial coverage lapse or a membership suspension never interrupts a tour already underway, and is enforced at the next call instead.

Troubleshooting

The session will not start — a session cannot start on un-synced layout data (ADR-0227); sync the layout, then retry. Operating readiness is NOT a reason a session will not start: it is guidance about what a session will be able to DO (without a traffic profile no waybills are generated; without a yard the Yardmaster panel has nothing to show), never a gate on starting one.

"Your subscription expired — refresh from our website" — the signed operating deadline for a new session has passed. Reconnect and renew the subscription or refresh/re-export the .rspkg; changing the computer clock, relying on a stale JWT, or exporting from an old package cannot extend access. Emergency stop and safety shutdown remain available.

"The selected layout or mounted package changed while its license was refreshing" — the refresh result belongs to the selection and package tenure that started it, not the one now on screen. Keep the intended organization, layout, and package selected, then start a new refresh. RailCommand discards the stale response rather than applying it to the replacement package.

An existing local-package session will not resume after restart — continuation requires the encrypted receipt for the exact nonterminal session and signed package identity. Mount the same package and select the same session. If the package, layout, or session differs, the session is terminal, or the receipt is missing, unreadable, or cannot be persisted after rotation, RailCommand refuses controls rather than manufacturing continuity. Start a new authorized session or recover the original package and receipt.

An eligible person does not appear in Crew Call — Confirm the accepted host relationship, the single selected coverage source, current qualification and territory, hours-of-service, availability, and absence of another live physical assignment. Free or trial-only coverage does not authorize a self-funded operating guest. NPC candidates must likewise be available, capable, and conflict-free for the exact session and role.

An expired package contains a completed offline session — Do not mount or refresh it as an operating package. Use the terminal round-trip recovery action. RailCommand verifies the exact install-signed final completion and zero-authority state, uploads the unchanged terminal evidence, imports it, and replaces the cached package with a current nonterminal package without ever enabling controls from the expired bytes.

An amber "automation blockers" banner on Create Session — this is informational, not a stop. Unconfigured devices such as imported-but-incomplete turntables are listed so you know they will sit out full automation; you can still create and run the session for arcade/freeform play. Finish those devices in the layout editor when you want them automated. (This is distinct from the un-synced-data gate below, which does prevent start.)

Set Route does nothing / won't lock — the entrance-to-exit path conflicts with an already-locked route or an occupied block. Cancel, wait for the conflict to clear, and set it again.

"No Running operations session for this layout" — dispatcher and operations actions (setting a route, freezing or resuming the layout, joining or separating consists) read the live railroad, so they need a session that is actually running. Start or resume the operating session for that layout, then retry. A Paused session does not count: pausing is meant to stop the railroad, so operational commands are declined until you resume it. This message is deliberate — rather than acting on an empty or stale picture of the railroad, the command declines and tells you why.

"Layout has more than one Running operations session" — two crews have separate sessions running on the same layout, so a command that does not name its session cannot be attributed to one. Rejoin from the session page (which carries your session with each action) rather than from a standalone panel, or end the session you are not using.

Motion and functions are held — one of the two relay lanes is down or the exact live UE probe is incomplete. Use Reconnect both lanes and re-probe UE. The page deliberately refuses ordinary controls rather than displaying a database or server projection as live hardware state.

"E-STOP NOT SENT" or "E-STOP NOT CONFIRMED" — cut track power immediately if any train may still be moving. The throttle latches a critical hardware alarm; reconnecting is diagnostic recovery, not proof that the stop happened.

Emergency stop is latched — after a train-scoped stop, use Reset this throttle to controlled stop and wait for a separate UE-confirmed step-0 response; moving requires another deliberate action. A layout-wide hard stop can be released only at the authoritative layout host, not silently from the browser.

End Session says the host release is not confirmed — the owning Avalonia station has not yet published positive release evidence for its exact host-lease generation. Return to that same station and use its End Session action, which first revokes the exact UE tenure and then publishes the matching release. If you already did that, restore its server connection and retry. Do not complete from another computer or wait for the heartbeat timer: heartbeat expiry proves lost server visibility, not that a partitioned local engine stopped.

End Session says the Crew authority fence is queued — the server completion and authority-ledger release committed, but the exact registered host has not yet acknowledged removal of its Human or NPC authority. Keep the owning station connected and wait for reconciliation. Do not treat the queued result as proof that local hardware authority has already stopped.

A move is refused in an Operating-Session — satisfy the named role, crew, or paperwork precondition. If the refusal is from interlocking, movement authority, hardware, or another safety gate, correct that condition. Never lower richness or automation merely to bypass a refusal; neither setting is allowed to relax the safety floor.

Safety Notes

Authority is layered and deliberate. The web authors sessions and forwards intent; the Avalonia desktop presents runtime state and forwards intent over the sidecar; the local/UE5 runtime is the authority node that owns every safety-critical decision and actuation — interlocking, movement authority, and hardware output. Its operating data comes from the activated local package/canonical local store; it never reads the backend Azure database as part of actuation. The web and the desktop never actuate hardware. Every ordinary multi-node command must name the exact RailCommand session and the current mesh-wide finalization decision; a node with no matching, unexpired decision stays non-authorizing. The throttle exposes separate EMERGENCY STOP THIS TRAIN and LAYOUT EMERGENCY STOP — ALL TRAINS controls. Both use RelayEmergencyStop over a dedicated priority connection and require an explicit authoritative confirmation; a missing exact train target is not silently escalated to a layout stop, and an unconfirmed stop tells the operator to cut track power. The local authority actuates (signals to danger, trains stopped) — the cloud is a relay, never the actuator (ADR-0219/0227/0239). On the desktop that relay now has exactly one leg: the Avalonia app opens no internet connection at all, and everything cloud-bound — sign-in, session and crew data, the multiplayer operations feed, and package licence refresh — travels through its own layout engine (#1612). Two consequences are visible to operators. Multiplayer operating sessions need a layout engine new enough to carry the operations feed; an older one says Engine update required and the session does not start, rather than quietly falling back. And because there is only one sign-in, the app can no longer show you as signed in while the engine is not — if the engine is signed out, so are you.

Commercial admission is a separate, signed new-session gate (ADR-0241), never an in-session actuation check. Crossing the deadline cannot remove controls from an admitted session. Restart continuation does not weaken that rule: UE issues an opaque receipt bound to the exact package lineage, layout, session, and safety generation; the desktop stores it encrypted with owner-only permissions, presents it only for that exact lineage, and persists the rotated receipt before controls are enabled. Completion, package replacement, identity divergence, tampering, unreadable storage, or a failed receipt write retires or refuses that path. The CTC panel has no separate all-stop; it routes through the operate console. The richness dial and the AutomationLevel ladder (FullAuto through Manual) can add restriction but never remove the safety floor — even a fully manual train keeps the emergency-stop path armed, and a live driving-mode handoff never drops the train's authority. On remote-dispatcher disconnect the authority node engages a territory-scoped HardStop. Related: Starting a Session, CTC Dispatcher, Emergency Stop, Session Guidance.

Crew authority is also explicit and fail-closed. The server ledger contains exactly one Human or NPC principal per assignment, and replacement cannot activate until the outgoing exact-session authority fence is acknowledged. Human device pairing derives from the committed assignment and admitted Crew Call role; NPC assignments have no device identity or QR. Offline completion is accepted only from the issuer- and install-bound signed chain whose unique final completion follows all releases and reconstructs no active assignment, on-duty Human, connected throttle, or working NPC.