export type WesternTrainPhase = 'approaching' | 'boarding' | 'departing' | 'away'; /** The loco's nose when docked (the platform's west end), the docked frame's origin along the line. */ export declare const WESTERN_TRAIN_NOSE_X: number; /** The last tile of the rake when docked: the tail chain behind the guard van's veranda. */ export declare const WESTERN_TRAIN_TAIL_X: number; /** Tiles from the nose to the tail chain, inclusive (73). */ export declare const WESTERN_TRAIN_RAKE_LENGTH: number; /** Half the rake's width: every piece is 5 across, centred on the track row. */ export declare const WESTERN_TRAIN_HALF_ACROSS = 2; /** The docked tiles a rider can stand on: the rake's deck from the nose to the guard van, the track row +-2. */ export declare const WESTERN_TRAIN_RIDE_BOX: { readonly minX: number; readonly maxX: number; readonly minZ: number; readonly maxZ: number; }; export declare function inWesternTrainRideBox(x: number, z: number): boolean; /** * Every model of the docked rake, as the backend lays it (westernEntrance.ts placeStation): the entity id, its model * style and its docked tile. The client hides these while no train stands at the platform and draws a moving copy of the * same list from the clock; the backend's smoke checks each one is in the world where this says. The four slot pieces * are listed only when their model is registered (CAPITAL_BUILDING_MODELS), as the backend places them. */ export type WesternRakePiece = { id: string; style: string; x: number; z: number; }; export declare const WESTERN_RAKE_PIECES: readonly WesternRakePiece[]; /** Is this entity one of the docked rake's models (hidden while no train is at the platform)? */ export declare function isWesternRakePieceId(id: string | undefined): boolean; /** * The benches of the four open cars (quest-workshop westcarriage_v002.py: a bench against each long side either side of * the doorway, centred 1.84 off the middle line, along local y 1.3-3.5 and -3.5 to -1.3, so two tiles each). A seat is * one tile of bench: the bench tile itself is on the car's blocked side row (track +-2), so the sitter's tile is the * aisle tile beside it (track +-1), and the body is drawn WESTERN_SEAT_DRAW_OFFSET of a tile toward the bench, facing * the aisle. All tiles are in the docked frame, so a seat is the same seat on every train, docked or moving. * `side` -1 is the platform side's bench (north, z track - 2), +1 the sea side's. `yaw` (three.js, about +y, in the * docked frame) faces away from the bench: a moving train adds its leg's yaw. */ export type WesternTrainSeat = { id: string; car: string; x: number; z: number; benchX: number; benchZ: number; side: -1 | 1; yaw: number; }; /** Along the car from its anchor: the bench tiles either side of the doorway. */ export declare const WESTERN_SEAT_ALONG: readonly number[]; /** Tiles from the aisle tile's middle toward the bench where the seated body is drawn (the bench's front edge is 0.43 on). */ export declare const WESTERN_SEAT_DRAW_OFFSET = 0.62; /** Metres: the cushion's top above the deck (westcarriage_v002.py: DECK + 0.33 + 0.09). */ export declare const WESTERN_SEAT_HEIGHT_METRES = 0.42; export declare const WESTERN_SEAT_LABEL = "Sit"; export declare const WESTERN_SEAT_TAKEN_TEXT = "Someone is already sitting there."; export declare const WESTERN_SEAT_BOARD_FIRST_TEXT = "Step aboard the train first."; export declare const WESTERN_SEAT_NO_TRAIN_TEXT = "There is no train here to sit in."; export declare const WESTERN_TRAIN_SEATS: readonly WesternTrainSeat[]; export declare function westernTrainSeatById(id: string | undefined): WesternTrainSeat | null; /** The seat whose sitter stands on this docked aisle tile, or null. */ export declare function westernTrainSeatAt(x: number, z: number): WesternTrainSeat | null; /** The seat on this docked bench tile (a click on the bench), or null. */ export declare function westernTrainSeatOnBench(x: number, z: number): WesternTrainSeat | null; /** Where a sitter's body is drawn, in the docked frame (fractional tile coordinates, like a walker's draw point). */ export declare function westernSeatDrawPoint(seat: WesternTrainSeat): { x: number; z: number; yaw: number; }; /** * The tunnel under the water: a straight bore in the underground strip (x >= UNDERGROUND_ORIGIN_X), rows 800 on of * which held nothing on 2026-10-10 (scanned: no walkable tile, no entity). Fifteen tiles wide since 2026-10-11 (James, * 2026-10-10: "think a huge underground tunnel eventually"; it was seven, the rake's five and a sconce row each side): the * line down the middle, five tiles of walkway either side of the rake, the sconces on the wall tiles; x 1140-1183 of * those rows were scanned solid and empty again before it widened. Its floor is at the platform's ground height so the * cars ride at the same height, the strip's own rock round it; the client vaults it over and cuts sea windows in its * walls (frontend tunnelVault.ts). Heading south: c 174 is its north end. */ export declare const WESTERN_TUNNEL_X: number; export declare const WESTERN_TUNNEL_START_Z = 806; export declare const WESTERN_TUNNEL_LENGTH = 556; export declare const WESTERN_TUNNEL_HALF_WIDTH = 7; export declare const WESTERN_TUNNEL_FLOOR_HEIGHT = 3; /** The bore, walls excluded (the floor tiles). The rock caps at either end hide the train going in and out. */ export declare const WESTERN_TUNNEL_BOX: { readonly minX: number; readonly maxX: number; readonly minZ: 806; readonly maxZ: number; }; export declare function inWesternTunnel(x: number, z: number): boolean; /** Wall sconces (westsconce, a lantern on a riveted plate) every this many tiles down each side, staggered. */ export declare const WESTERN_TUNNEL_SCONCE_EVERY = 14; /** The /tp into the tunnel (admins): its north end, beside the line. */ export declare const WESTERN_TUNNEL_STAND: { readonly x: number; readonly z: number; }; /** * PHASE 0c SPIKE (2026-10-10, plan `.cursor/task-plans/2026-10-10-western-phase0c.md`; parent * `2026-10-10-west-land-build-plan.md`): a stub of the Western Isle's halt in the Western Kingdoms' strip, to measure * the train's jump into a new region. NOT the designed first stop: a copy of the home station's layout translated into * the strip's open sea (the platform, the gap row with its step plates, the sea kerb, the line, the portal in a rock * cap), with a short causeway straight off its east end into the sea. The train's third leg ('isle') runs from the * causeway's sea end west past the platform into the cap, then wraps to the home causeway's sea end. * * Because the stub is the docked layout moved by (WESTERN_ISLE_SHIFT_X, WESTERN_ISLE_SHIFT_Z), a train standing at * the isle stop has every docked tile exactly that far from its world tile: the step plates, doorways and platform * edge tiles line up as at home (westernStopSteps maps them through the leg, so a later stop need not be a copy). * * Phase 1c-1 (2026-10-10, plan `.cursor/task-plans/2026-10-10-western-1c-first-stop-plan.md`): the stub became the real * first stop, LANTERN WAKE (types lanternWake.ts). Its station keeps every tile of the stub (the timetable and the step * mapping hang off them), so the translation is now named for what it is, the docked frame's offset to Lantern Wake's * station (LANTERN_WAKE_FRAME_DX/DZ); the old WESTERN_ISLE_SHIFT_* names stay as aliases. The stop id stays * 'western-isle' (nothing to migrate); its name is "Lantern Wake". */ export declare const LANTERN_WAKE_FRAME_DX = 1970; export declare const LANTERN_WAKE_FRAME_DZ = -32; export declare const WESTERN_ISLE_SHIFT_X = 1970; export declare const WESTERN_ISLE_SHIFT_Z = -32; export declare const WESTERN_ISLE_TRACK_Z: number; /** The stub's causeway, the last 22 tiles of the line, stepping down to the waterline (its sea end the leg's x0). */ export declare const WESTERN_ISLE_SEA_END_X = 2097; export declare const WESTERN_ISLE_CAUSEWAY: { readonly minX: number; readonly maxX: 2097; readonly minZ: number; readonly maxZ: number; }; export declare function westernIsleCausewayHeight(x: number): number; export type WesternTrainBox = { minX: number; maxX: number; minZ: number; maxZ: number; }; export declare const WESTERN_ISLE_PLATFORM: WesternTrainBox; export declare const WESTERN_ISLE_PLATFORM_PIECES: (readonly [number, number])[]; export declare const WESTERN_ISLE_GAP_ROW: { readonly minX: number; readonly maxX: number; readonly z: number; }; export declare const WESTERN_ISLE_SEA_KERB: { readonly minX: number; readonly maxX: number; readonly z: number; }; /** The rock cap the line runs into (the home knoll's box, moved), and the portal on its east face. */ export declare const WESTERN_ISLE_KNOLL: WesternTrainBox; export declare const WESTERN_ISLE_MOUTH: { readonly x: number; readonly z: number; readonly style: "westportal-e"; }; /** The rock cap's portal at Lantern Wake (an id of the station's `lw-station-` family since phase 1c-1). */ export declare const WESTERN_ISLE_MOUTH_ID = "lw-station-mouth"; /** The stub's ground: the knoll's west foot to the causeway's start, a few rows round the station (all laid on the strip's sea). */ export declare const WESTERN_ISLE_LAND: { readonly minX: number; readonly maxX: number; readonly minZ: number; readonly maxZ: number; }; /** Where an admin /tp lands on the stub: the platform's middle. */ export declare const WESTERN_ISLE_STAND: { readonly x: number; readonly z: number; }; export declare function inWesternIsleStub(x: number, z: number): boolean; /** Every train counts from this instant (a fixed date, so a restart never moves a train). */ export declare const WESTERN_TRAIN_EPOCH_MS: number; /** Cruising speed (tiles a second) and the rate it gets up to it and slows from it. */ export declare const WESTERN_TRAIN_TOP_SPEED = 6; export declare const WESTERN_TRAIN_ACCEL = 0.5; /** The bell rings this long before a departure; the step plates shut this long before it. */ export declare const WESTERN_TRAIN_BELL_BEFORE_MS = 15000; export declare const WESTERN_TRAIN_DOORS_SHUT_BEFORE_MS = 5000; /** The whistle and the bell are heard this far (tiles) from the loco. */ export declare const WESTERN_TRAIN_SOUND_RANGE = 40; export declare const WESTERN_TRAIN_MOVING_TEXT = "The train is moving."; export declare const WESTERN_TRAIN_DOORS_SHUT_TEXT = "The doors are shut: the train is about to leave."; export declare const WESTERN_TRAIN_ABOARD_COMBAT_TEXT = "There is no fighting aboard the train."; export declare const WESTERN_TRAIN_ALIGHT_MOVING_TEXT = "The train is moving. Wait until it stops at the platform."; /** A stop's arriving announcement goes to its riders this long before the train stands there. */ export declare const WESTERN_TRAIN_ANNOUNCE_BEFORE_MS = 10000; export declare const WESTERN_TRAIN_MEMBERS_ONLY_TEXT = "Only members may step off here. Stay aboard: the train runs on to the next stop."; export type WesternBore = { id: string; /** The line's x down the middle, the first row and how many rows it runs. */ x: number; z0: number; length: number; /** Tiles of floor either side of the line (the walls are the next tile out). */ halfWidth: number; floorHeight: number; /** A wall sconce every this many rows down each side, staggered. */ sconceEvery: number; /** Entity id prefix of its rails and sconces: `-rail-`, `-sconce-w-`. */ idPrefix: string; /** * What each wall shows, stretch by stretch (slice 2-1): rows of a wall in no stretch are plain stone. None given is bore * A's look, sea windows down both walls. Not part of the circuit's key: the look can change without a new version. */ walls?: readonly WesternBoreStretch[]; /** A dressed bore (slice 2-1): lantern posts down both walkways and banners between the windows (westernBoreDressing). */ dressed?: boolean; /** The service siding (the design sheet's passing bay): a short second line on one walkway with buffer stops and crates. */ siding?: { side: 'w' | 'e'; z0: number; z1: number; }; /** A bore-end portal drawn on these end walls (the client's stand-in for the K3 `wlboreportal`): 'n' the z0 end, 's' the far end. */ portals?: readonly ('n' | 's')[]; /** * The halls built against a wall (slice 2-2's Forge Halt; frontend tunnelVault.ts): over their rows the vault lays no cover * or raised rock past that wall (the camera may stand in the hall), and the wall has no face at the doorways. Not part of * the circuit's key. */ halls?: readonly WesternBoreHall[]; }; /** A hall against one wall of a bore, rows z0 to z1, and the doorways (rows, inclusive) cut through that wall into it. */ export type WesternBoreHall = { side: 'w' | 'e'; z0: number; z1: number; doorways: ReadonlyArray<{ z0: number; z1: number; }>; }; /** * The looks a stretch of bore wall can have (slice 2-1, the approved undersea bore sheet): `sea` the warm blue windows of * bore A, `cold` the northern sea's pale green windows (ice floes overhead, a seal), `warm` the east side's kelp and a * wreck's ribs, `ore` no window, a glinting seam in the rock (the client's stand-in for the K3 `wloreseam`), `plain` bare * stone (a wall kept clear for a hall's doorways, slices 2-2 and 2-3). */ export type WesternBoreWallLook = 'sea' | 'cold' | 'warm' | 'ore' | 'plain'; export type WesternBoreStretch = { side: 'w' | 'e'; z0: number; z1: number; look: WesternBoreWallLook; }; /** One window (or ore seam) in a bore wall: rows z0 to z1 (z1 fractional: WESTERN_BORE_WINDOW_SPAN on), and its look. */ export type WesternBoreWindow = { side: 'w' | 'e'; z0: number; z1: number; centreZ: number; look: Exclude; }; /** A window every this many rows down each wall, the east wall half a step behind the west's. */ export declare const WESTERN_BORE_WINDOW_EVERY = 40; /** Rows along the wall a window spans. */ export declare const WESTERN_BORE_WINDOW_SPAN = 3.6; export declare const WESTERN_BORE_A: WesternBore; /** A bore's floor tiles, walls excluded (bore A's is WESTERN_TUNNEL_BOX). */ export declare function westernBoreBox(bore: WesternBore): WesternTrainBox; /** Does a wall's row hold a sconce (backend placeWesternBore: west at offset 3, east at 3 + half, every sconceEvery)? */ export declare function westernBoreSconceRow(bore: WesternBore, side: 'w' | 'e', z: number): boolean; /** What a wall shows at a row: its stretch's look, bore A's sea when the bore lists none, else plain stone. */ export declare function westernBoreWallLookAt(bore: WesternBore, side: 'w' | 'e', z: number): WesternBoreWallLook; /** * The windows (and ore seams) down a bore's walls: every WESTERN_BORE_WINDOW_EVERY rows, the east wall's half a step * behind the west's so one shows on the far wall wherever the camera looks, each nudged along until it clears that * wall's sconces, none within a window's length of either end; then each takes its stretch's look, and one that would * straddle two looks or stand in a plain stretch is left out. Bore A's are exactly the windows it has had since * 2026-10-11 (frontend tunnelVault.ts drew them before slice 2-1 moved the sum here). */ export declare function westernBoreWindows(bore: WesternBore): WesternBoreWindow[]; /** One placed piece of a bore's dressing (westernBoreDressing): entity id, model style, world tile. */ export type WesternBoreProp = { id: string; style: string; x: number; z: number; }; /** Walkway tiles off the line: lantern posts this far out (the rake is 2 either side), banners next to the wall tile. */ export declare const WESTERN_BORE_LANTERN_LATERAL = 4; export declare const WESTERN_BORE_LANTERN_EVERY = 28; /** * A dressed bore's props (slice 2-1, the approved undersea bore sheet; existing kit as stand-ins until the bore batch's * Blender pieces land): brass lantern posts (westlantern) down both walkways, staggered; a blue banner (westbanner) on * the tile in front of each wall midway between its windows or seams; and the service siding: a second line on one * walkway (westtrack) with a buffer stop (westbuffer) at each end, service crates, a control box and a signal post (the K1 kit). Nothing on the rake's * five tiles, the wall tiles (the sconces), in front of a window, or on another prop; the backend places exactly this list. */ export declare function westernBoreDressing(bore: WesternBore): WesternBoreProp[]; /** Where an admin /tp lands in a bore: the west walkway, a few rows in from its first end. */ export declare function westernBoreStand(bore: WesternBore): { x: number; z: number; }; /** The loading cover a rider sees when the train carries them onto a leg from far away (AREA_TRANSITIONS ids). */ export type WesternTrainCover = { area: 'western-line' | 'western-kingdoms-train'; title?: string; }; /** * One straight leg of a circuit. `surface` legs climb a causeway out of the sea at their x0 (the home line's profile, * heading west); `bore` legs run level on their bore's floor. The lateral axis is (dz, -dx): docked z minus the track row, * so the platform (docked z < the track row) is on the left of the direction of travel. */ export type WesternTrainSegment = { id: string; kind: 'surface' | 'bore'; /** The first c on this leg and how many tiles it runs. */ c0: number; length: number; /** World tile of c0 on the track row, and the unit direction of travel. */ x0: number; z0: number; dx: number; dz: number; /** A bore leg's bore. */ bore?: WesternBore; /** What a rider sees when the train carries them onto this leg from another region or farther than the view ring. */ cover: WesternTrainCover; /** Tiles the client draws a piece past the leg's start and end (into the sea or the rock that hides it). */ drawBefore: number; drawAfter: number; }; export type WesternTrainSegmentDef = Omit & { drawBefore?: number; drawAfter?: number; }; /** c of the nose when the train stands at the isle stub (the nose on the platform's west end, as at home). */ export declare const WESTERN_ISLE_STOP_C: number; /** c of the nose when the train stands at the platform (loco's nose at x 30). */ export declare const WESTERN_TRAIN_PLATFORM_C: number; /** The surface leg's x range the rake is drawn on (the mouth hides it to the west, the sea to the east). */ export declare const WESTERN_TRAIN_SURFACE_DRAW: { readonly minX: 18; readonly maxX: number; }; /** The yaw (radians, three.js about +y) that turns the docked frame (heading -x) to this leg's heading. */ export declare function westernTrainSegmentYaw(seg: WesternTrainSegment): number; /** * The stops, in the order the train reaches them. `home` is the station whose rake IS the docked frame (the Western * Entrance's platform): the only stop with the 'boarding' phase, the docked rake's own plates. `steps`: the stop has its * own step plates on its own platform (westernStopSteps): riders step off there and people on that platform board there, * while the train stands with its doors open. */ export type WesternTrainStop = { id: string; name: string; c: number; dwellMs: number; enabled: boolean; note: string; home?: boolean; steps?: boolean; /** The id prefix of the stop's own step plates (default `-step`): `-`. */ stepPrefix?: string; /** Only members may step off here (James: members-only stops later); a non-member rides on. */ membersOnly?: boolean; /** What riders are told: `next` as the train leaves the stop before this one, `arriving` shortly before it stands here. */ announce?: { next?: string; arriving?: string; }; /** A closed place reached only by this stop's train (a hall off a bore): someone saved in it while the stop is not running wakes at home. */ pocket?: WesternTrainBox; }; /** Duration (ms) of a run of D tiles from a stop to a stop: up to speed, cruise, slow to a stand. */ export declare function westernTrainRunMs(distance: number, v?: number, a?: number): number; /** Tiles covered after t ms of a run of D tiles. */ export declare function westernTrainRunTiles(distance: number, tMs: number, v?: number, a?: number): number; export type WesternTrainLeg = { stop: WesternTrainStop; startMs: number; departMs: number; runTiles: number; endMs: number; }; export type WesternTrainTimetable = { cycleMs: number; legs: WesternTrainLeg[]; }; /** * A whole circuit: its legs, stops, how many trains run it and the timetable they keep. The SERVER runs one * (WESTERN_TRAIN_CIRCUIT) and sends its `key` with the clock (messages trainCircuit); the client draws and times the * circuit with that key (westernCircuitForKey), so a game deployed before the backend is released never draws trains * the server is not running. A circuit, once on master, is frozen: a change to its track, stops, dwells or train count * is a NEW version (defineWesternCircuit), and the old one stays in WESTERN_TRAIN_CIRCUITS for clients of an older server. */ export type WesternTrainCircuit = { version: number; /** `v-`: what the server sends, what the client looks up. */ key: string; segments: readonly WesternTrainSegment[]; length: number; stops: readonly WesternTrainStop[]; trainCount: number; /** Tiles a second a train cruises at, and the rate (tiles a second, each second) it gets up to it and slows from it. */ topSpeed: number; accel: number; timetable: WesternTrainTimetable; /** The home station (its rake is the docked frame) and the leg it stands on. */ home: WesternTrainStop; homeLeg: WesternTrainSegment; /** Every running stop's own step plates (not the home platform's). */ stopSteps: readonly WesternStopStep[]; /** The bores its legs run through, in leg order. */ bores: readonly WesternBore[]; }; /** Only the track: what the position sums need (a circuit, or one being defined). */ type Track = Pick; /** * Build and check a circuit. Throws on a circuit the line cannot run: legs that are not unit steps along x or z, a * surface leg not heading west (the causeway profile is the home line's), stops off the track or on the same c, no home * stop or more than one, a home stop whose rake is not the docked frame itself, a train count outside 1-8. */ export declare function defineWesternCircuit(def: { version: number; segments: readonly WesternTrainSegmentDef[]; stops: readonly WesternTrainStop[]; trainCount: number; topSpeed?: number; accel?: number; }): WesternTrainCircuit; /** * VERSION 1: the line as it ran from 2026-10-10 (the moving train) and 2026-10-10 (Lantern Wake): the home platform's * surface leg, bore A south under the sea, Lantern Wake's leg west into its rock cap, two trains. Frozen: never edit. */ export declare const WESTERN_TRAIN_CIRCUIT_V1: WesternTrainCircuit; /** Bore B, the Hold Line: the sea on its west wall (the coast side), the western cliffs' rock and ore on its east. */ export declare const WESTERN_BORE_B: WesternBore; /** Bore C, the Crown Line: cold northern windows across the top, the warm east-side sea down its east wall after that. */ export declare const WESTERN_BORE_C: WesternBore; /** The legs' covers: what a rider sees when the train carries them into each new bore. */ export declare const WESTERN_HOLD_LINE_COVER: WesternTrainCover; export declare const WESTERN_CROWN_LINE_COVER: WesternTrainCover; /** * VERSION 2 (slice 2-1): version 1's three legs, then bore B north and bore C south, three trains (James, 2026-10-11: * "three trains"; one way round). The Dwarf Hold and the Forge Halt, pre-registered by 2-1, opened by slices 2-3 and 2-2. * FROZEN since the phase 2 integration put it on master with both halts open (2026-10-11, key v2-bc34d3bf, cycle 485.2 s, * pinned in train-circuit-test.mjs): any later stop, leg, dwell or train count is version 3. */ export declare const WESTERN_TRAIN_CIRCUIT_V2: WesternTrainCircuit; /** * VERSION 3 (James, 2026-10-18: "make the train journey faster / speed of train perhaps"): version 2's line, stops, dwells and * three trains, run faster. Cruising speed doubles (6 to 12 tiles a second) and the pull away and the braking are three times * as strong (0.5 to 1.5), so a lap of the whole loop takes about two thirds of the time it did. Only the speed is new; a * change to a stop, a dwell or the track after this is version 4. */ export declare const WESTERN_TRAIN_CIRCUIT_V3: WesternTrainCircuit; /** Every circuit this build knows, oldest first: a client follows whichever of them its server runs. */ export declare const WESTERN_TRAIN_CIRCUITS: readonly WesternTrainCircuit[]; /** The circuit this build's SERVER runs (the client's default before the server has said). */ export declare const WESTERN_TRAIN_CIRCUIT: WesternTrainCircuit; /** Every bore of every known circuit (lighting and sounds: a bore the server has not cut is never reached). */ export declare const WESTERN_BORES: readonly WesternBore[]; /** In a bore (its floor or its wall tiles), of every known circuit or the bores given. */ export declare function inWesternBore(x: number, z: number, bores?: readonly WesternBore[]): boolean; /** The version a key names (`v3-...` is 3), or null for a key that is not one. */ export declare function westernCircuitVersionOf(key: string | null | undefined): number | null; /** * The circuit a server runs, from the key it sent: no key is a server from before the version (slice 2-0), which runs * version 1; a key this build knows is that circuit; anything else is null (a newer server than this page, or a circuit * changed without a new version): the client then draws no moving train and asks for a reload. */ export declare function westernCircuitForKey(key: string | null | undefined, known?: readonly WesternTrainCircuit[]): WesternTrainCircuit | null; /** * How this build stands with the server's circuit: `same` (the one it would run), `older` (the server runs an older * circuit this build still knows: follow it), `newer` (the server runs a later version than any this build knows: reload), * `unknown` (a version this build knows with different numbers: someone changed a circuit without a new version). */ export declare function westernCircuitAgreement(key: string | null | undefined, own?: WesternTrainCircuit, known?: readonly WesternTrainCircuit[]): { status: 'same' | 'older' | 'newer' | 'unknown'; circuit: WesternTrainCircuit | null; }; /** What a client tells its player when it cannot follow the server's circuit. */ export declare const WESTERN_TRAIN_RELOAD_TEXT = "The Western Line has changed since this page loaded. Reload the page to see the trains."; export declare const WESTERN_TRAIN_SEGMENTS: readonly WesternTrainSegment[]; export declare const WESTERN_TRAIN_CIRCUIT_LENGTH: number; /** How many trains run the circuit, evenly spaced in time (James: "1-3 trains running constantly"). */ export declare const WESTERN_TRAIN_COUNT: number; export declare const WESTERN_TRAIN_STOPS: readonly WesternTrainStop[]; export declare const WESTERN_TRAIN_CYCLE_MS: number; export declare function wrapWesternC(c: number, circuit?: Track): number; export declare function westernTrainSegmentAt(c: number, circuit?: Track): WesternTrainSegment; /** A point on a leg (c may run past its ends: the client extrapolates a piece into the sea or the rock). */ export declare function westernTrainPointOn(seg: WesternTrainSegment, c: number, lateral: number): { x: number; z: number; }; /** The world point of track coordinate c (wrapped) and a lateral offset (docked z - track z). */ export declare function westernTrainWorldPoint(c: number, lateral: number, circuit?: Track): { x: number; z: number; segment: WesternTrainSegment; }; /** The ground under the track at c on a leg: a bore's floor, or the causeway stepping down to the waterline, then the sea. */ export declare function westernTrainGroundHeight(seg: WesternTrainSegment, c: number): number; /** Metres: the deck a rider stands on at c (the ground plus the kit's deck height). */ export declare function westernTrainDeckY(seg: WesternTrainSegment, c: number): number; /** A docked tile (rider or piece) to its c, given the nose's c. */ export declare function westernDockedC(noseC: number, dockedX: number): number; /** The world tile of a docked tile when the nose stands at integer c (the server's step). */ export declare function westernRiderWorldTile(noseC: number, dockedX: number, dockedZ: number, circuit?: Track): { x: number; y: number; }; /** * A world tile back to the docked frame of a train whose nose is at c (a rider's click on the moving deck), or null when * the tile is not on the rake. */ export declare function westernWorldToDocked(noseC: number, x: number, z: number, circuit?: Track): { x: number; y: number; } | null; /** The compass side of the track a stop's platform is on (the docked platform side, turned with the leg). */ export declare function westernStopPlatformSide(stop: WesternTrainStop, circuit?: Track): 'north' | 'east' | 'south' | 'west'; /** How far (tiles, Chebyshev) a rider may be carried in one step before it counts as a jump needing the cover: the view ring. */ export declare const WESTERN_TRAIN_JUMP_TILES: number; /** * A rider's tile carried from one server step to the next: a JUMP (the loading cover first) when it lands in another * region of the grid OR farther than the view ring (two bores in the same region, slice 2-0), with the cover of the leg * it lands on; null for an ordinary step. */ export declare function westernRiderJump(prevNoseStep: number, noseStep: number, dockedX: number, dockedZ: number, circuit?: Track): { from: { x: number; y: number; }; to: { x: number; y: number; }; segment: WesternTrainSegment; cover: WesternTrainCover; } | null; /** The cycle: for each running stop in order, its dwell then the run to the next running stop (wrapping). */ export declare function westernTrainTimetable(stops?: readonly WesternTrainStop[], length?: number, topSpeed?: number, accel?: number): WesternTrainTimetable; export type WesternTrainState = { train: number; /** The nose's track coordinate, continuous, wrapped to [0, circuit). */ noseC: number; /** The integer step the server moves riders by. */ noseStep: number; moving: boolean; phase: WesternTrainPhase; /** The stop it stands at, or null while running. */ stopId: string | null; /** While standing: ms until it leaves. */ msToDepart: number | null; /** Ms until it next stands at the home platform (0 while it is there). */ msToPlatform: number; /** Where in the cycle (ms), for the sounds' edge detection. */ cycleMs: number; /** The stop it stands at or is running to, and ms until it stands there (0 while standing). */ nextStopId: string; msToNextStop: number; }; /** Where train `train` (0-based) is at server time `nowMs`, on a circuit (the server's by default). */ export declare function westernTrainAt(nowMs: number, train?: number, circuit?: WesternTrainCircuit): WesternTrainState; /** Every train of a circuit at `nowMs`. */ export declare function westernTrainsAt(nowMs: number, circuit?: WesternTrainCircuit): WesternTrainState[]; /** The stop a train stands at, or the next running stop it reaches. */ export declare function westernNextStop(state: WesternTrainState, circuit?: WesternTrainCircuit): WesternTrainStop | null; /** The running stop after this one (wrapping). */ export declare function westernStopAfter(stopId: string, circuit?: WesternTrainCircuit): WesternTrainStop | null; /** A stop's name as said mid-sentence ("for the Western Entrance"). */ export declare function westernStopNamePhrase(stop: Pick): string; /** * The closest two trains come on a circuit (tiles from one's nose to the tail ahead of it, along the line), sampled over * a cycle; Infinity with one train. The line's own test wants at least 20. */ export declare function westernTrainMinGap(circuit?: WesternTrainCircuit, stepMs?: number): number; /** The train standing at the home platform at `nowMs`, or null. */ export declare function westernTrainAtPlatform(nowMs: number, circuit?: WesternTrainCircuit): WesternTrainState | null; /** Ms until the next train stands at the platform (0 if one is there). */ export declare function westernTrainNextArrivalMs(nowMs: number, circuit?: WesternTrainCircuit): number; /** The refusal text for the step plates while no train can be boarded. */ export declare function westernTrainNoBoardingText(nowMs: number, circuit?: WesternTrainCircuit): string; /** * The station's word on the next train (the station hub, 2026-10-10: the All Aboard board's click and the station * master's "Next train?"): a train standing with its doors open, shut, or the next one due. */ export declare function westernStationNextTrainText(nowMs: number, circuit?: WesternTrainCircuit): string; /** The running stops in the order a train reaches them, from the home station round (slice 2-4: the boards and the guide). */ export declare function westernLineStopOrder(circuit?: WesternTrainCircuit): WesternTrainStop[]; /** * The line's way round, for the boards, the station master and the guide (slice 2-4): the running stops in order and home * again, then any stop the circuit lists but does not run yet (a halt still being dug: the train runs straight through). */ export declare function westernLineRouteText(circuit?: WesternTrainCircuit): string; /** What the All Aboard board says: the line's rules from the timetable, the way round, then the next train. */ export declare function westernStationNoticeText(nowMs: number, circuit?: WesternTrainCircuit): string; /** Can the step plates be used at `nowMs` (a train standing, more than the shut time to go)? */ export declare function westernTrainDoorsOpen(nowMs: number, circuit?: WesternTrainCircuit): boolean; /** The platform tile in front of the nearest step plate to a docked x (where someone left on the docked rake is put). */ export declare function westernPlatformTileNear(x: number): { x: number; y: number; }; /** * One step plate of a stop with its own platform: the home plate's docked tiles carried by the leg to where the train * stands at that stop. `x`/`z` the plate's world tile, `platform` the world tile a rider steps down to, `doorway` the * DOCKED tile someone boarding there is put on (their tile is always kept in the docked frame aboard). */ export type WesternStopStep = { stopId: string; car: string; id: string; x: number; z: number; platform: { x: number; y: number; }; doorway: { x: number; y: number; }; }; export declare function westernStopSteps(stop: WesternTrainStop, circuit?: Track): WesternStopStep[]; /** Every running stop's own plates (not the home platform's), on the server's circuit. */ export declare const WESTERN_STOP_STEPS: readonly WesternStopStep[]; export declare function westernStopStepAt(x: number, z: number, circuit?: WesternTrainCircuit): WesternStopStep | null; export declare function westernStopStepById(id: string | undefined, circuit?: WesternTrainCircuit): WesternStopStep | null; /** The train standing at a stop (not the home platform) at `nowMs`, or null. */ export declare function westernTrainAtStop(nowMs: number, stopId: string, circuit?: WesternTrainCircuit): WesternTrainState | null; /** The train at a stop with its doors open (more than the shut time to go), or null. */ export declare function westernStopDoorsOpen(nowMs: number, stopId: string, circuit?: WesternTrainCircuit): WesternTrainState | null; /** * Ms until the next train stands at a stop (0 while one stands there), from the timetable; Infinity for a stop that is * not running. The station master's sum for the home platform is westernTrainNextArrivalMs. */ export declare function westernStopNextArrivalMs(nowMs: number, stopId: string, circuit?: WesternTrainCircuit): number; /** Why a stop's plates refuse at `nowMs`. */ export declare function westernStopNoBoardingText(nowMs: number, stopId: string, circuit?: WesternTrainCircuit): string; /** * A stop of any known circuit whose closed pocket (a hall reached only by its train) holds this tile and which the given * circuit does not run: someone saved there wakes at home (the stop was switched off, or the server runs an older circuit). */ export declare function westernClosedPocketAt(x: number, z: number, circuit?: WesternTrainCircuit, known?: readonly WesternTrainCircuit[]): WesternTrainStop | null; export {}; //# sourceMappingURL=westernTrain.d.ts.map