import type { Waypoint } from "./pathFollow.js"; export interface RailNode { id: string; at: Waypoint; } export interface RailEdge { id: string; from: string; to: string; /** Intermediate shape points between the two node positions (curves, sidings). */ via?: readonly Waypoint[]; } export interface RailGraphConfig { nodes: readonly RailNode[]; edges: readonly RailEdge[]; } export interface ResolvedRailEdge { id: string; from: string; to: string; points: readonly Waypoint[]; length: number; } /** * A directed graph of track segments with junction switch-throw semantics — the topological seam * `nav/navGrid`'s walkable cells can't express. Each node with several out-edges is a switch whose * thrown edge decides where traffic exits; riders (`createRailRider`) run along edge polylines and * take the thrown edge at every junction. */ export interface RailGraph { node(id: string): RailNode | null; edge(id: string): ResolvedRailEdge | null; edges(): readonly string[]; /** Out-edge ids leaving a node, in declaration order. */ outEdges(nodeId: string): readonly string[]; /** The edge a rider leaves this node on — the thrown switch, defaulting to the first declared out-edge; `null` at a dead end. */ thrownEdge(nodeId: string): string | null; /** Throw the switch at `nodeId` to `edgeId`; `false` unless `edgeId` leaves that node. */ throwSwitch(nodeId: string, edgeId: string): boolean; } export interface RailRiderConfig { edgeId: string; /** Arc-length position along the starting edge; default `0`. */ s?: number; /** World units per second; mutate via `setSpeed`. */ speed: number; } export interface RailRiderPose { position: Waypoint; /** Yaw (radians) of the travel direction, matching engine `rotationY`. */ heading: number; edgeId: string; /** Arc-length along the current edge. */ s: number; /** True once the rider stops at a node with no thrown out-edge. */ atDeadEnd: boolean; } export interface RailRider { advance(dt: number): RailRiderPose; pose(): RailRiderPose; setSpeed(speed: number): void; /** Teleport onto an edge (a respawn or re-rail); throws on an unknown edge. */ place(edgeId: string, s?: number): void; } export declare function createRailGraph(config: RailGraphConfig): RailGraph; export declare function createRailRider(graph: RailGraph, config: RailRiderConfig): RailRider;