API Reference

API Reference

Every member below lives on window.SubwayBuilderAPI. The pages name it api:

js
const api = window.SubwayBuilderAPI;

Every example on these pages assumes that line. Each page is generated from the game's TypeScript declarations and their JSDoc; the examples run in the game's test suite against the real API.

PageMembersCountSummary
hooksapi.hooks32Lifecycle hooks: on* registrations that return an unsubscribe function.
actionsapi.actions23Game actions: money, pause and speed, fares, bonds, station names and the demand-bubble scale.
gameStateapi.gameState39Getters for the running game: stations, routes, tracks, trains, fares, demand, clock, money, bonds, statistics, map colors, buildings and streets, blueprint costs, station groups and save identity.
uiapi.ui26Mod UI: placement components, toasts, theme, CSS colors, toolbar and floating panels, and map layer visibility.
mapapi.map10Map customization: MapLibre sources and layers, per-city tile and routing overrides, per-layer overrides, and default layer visibility.
trainsapi.trains4Train type registry. Register, patch and read the TrainTypeStatsItem records that define both trains and the track types that share their ids.
stationsapi.stations4Station type registry. Register, patch and read the StationTypeStatsItem records that set a station's walk catchment, transfer radius, walk speed and extra dwell.
buildapi.build12Build automation: blueprint track placement, construction, routes and trains, through the store actions the game itself uses.
demandapi.demand8Demand editing: demand points and pops (commuter groups) in the loaded city.
popTimingapi.popTiming14Commute timing: the time-of-day ranges that weight when pops leave home and work, the student and airport dampenings, and the hour-to-demand-tier table.
storageapi.storage5Per-mod key-value persistence backed by a JSON file per mod id in the Electron main process.
registerCityapi.registerCity, api.cities5Register a city in the city picker list.
modsapi.mods2Registry of mods whose scripts executed without throwing.
tutorialapi.tutorial2Read-only tutorial state kept in sync by the tutorial start and end triggers.
utilsapi.utils14Shared libraries and helpers: game constants, the map, city data loading, React, Lucide icons, UI components, Recharts, i18n, and the binary city-data encoders.
schemasapi.schemas6Zod schemas for the city data file formats. Validate generated files with safeParse.
Constantsapi.modifyConstants, api.modifyColors, api.modifyPathfindingRules3Deep-merge overrides into the game rules object RULES and push a snapshot to the sim host worker when one is running. Full text below the table.
Newspaper templatesapi.registerNewspaperTemplates1Append newspaper templates to the global list the newspaper service merges into its template pool.
Typesshared data types61Data types returned by gameState getters and carried by hook payloads.

Constants: Deep-merge overrides into the game rules object RULES and push a snapshot to the sim host worker when one is running. The top-level RULES object keeps its identity; every nested object on an override path is replaced by a merged copy, so a nested reference taken earlier (const cc = api.utils.getConstants().CONSTRUCTION_COSTS) goes stale.

MemberReturnsSummary
api.versionstringAPI version string; the literal 1.0.0.
api.reloadMods()Promise<void>Clear mod-registered state, re-execute every enabled mod through the mod loader, and resolve when the loader reports completion.

API Structure#

ts
window.SubwayBuilderAPI = {
    version, reloadMods,
    hooks: { onGameInit, onDayChange, onStationBuilt, /* 32 on* hooks */ },
    actions: { setMoney, addMoney, setPause, setSpeed, addFareGroup, issueBond, /* ... */ },
    gameState: { getStations, getRoutes, getTrains, getBudget, getDemandData, /* ... */ },
    ui: { showNotification, addButton, addToolbarPanel, addFloatingPanel, registerComponent, /* ... */ },
    map: { registerSource, registerLayer, setTileURLOverride, setLayerOverride, queryRoute, /* ... */ },
    trains: { registerTrainType, modifyTrainType, getTrainTypes, getTrainType },
    stations: { registerStationType, modifyStationType, getStationTypes, getStationType },
    build: { placeBlueprintTracks, buildBlueprints, createRoute, buyTrains, /* ... */ },
    demand: { addDemandPoint, addPops, updatePop, removePops, setPersistence, /* ... */ },
    popTiming: { getCommuteTimeRanges, setCommuteTimeRange, getDemandLevel, /* ... */ },
    storage: { get, set, delete, keys, scoped },
    registerCity, cities: { setCityDataFiles, getCityDataFiles, registerTab, getTabs },
    mods: { isLoaded, getLoadedMods },
    tutorial: { isActive, getApproach },
    utils: { React, icons, components, charts, i18n, buildings, walkGraph, getMap, loadCityData, /* ... */ },
    schemas: { DemandDataSchema, DemandPointSchema, PopSchema, RoadsGeojsonSchema, RoadPropertiesSchema, RunwaysTaxiwaysGeojsonSchema },
    modifyConstants, modifyColors, modifyPathfindingRules,
    registerNewspaperTemplates,
};
TaskPage
React to game eventshooks
Read stations, routes, money, ridershipgameState
Change money, speed, fares, bondsactions
Add buttons, panels, notificationsui
Tune game rules and pathfindingConstants
Add a cityregisterCity and the custom cities guide
Add train or station typestrains, stations
Build track and routes from codebuild
Edit demand or commute timingdemand, popTiming
Persist mod settingsstorage
Translate mod textutils i18n
Look up a returned object's fieldsTypes
Hot reload and troubleshootingDebugging

TypeScript Support#

No type package ships. A mod script runs through new Function, so import statements are syntax errors in it; write a mod in TypeScript only with a build step that emits plain JavaScript. The Types page lists the returned object shapes, and each reference page gives every member's signature.

version#

api.version: string

API version string; the literal 1.0.0.

js
console.log(`Modding API ${api.version}`);

reloadMods#

api.reloadMods(): Promise<void>

Clear mod-registered state, re-execute every enabled mod through the mod loader, and resolve when the loader reports completion.

Cleared before the scripts re-run: every hooks.on* registration list and the onError reporter subscriptions, every mod UI component, custom map layers, sources and styles, speed overrides (restored to the original values), commute window and dampening overrides, custom newspaper templates, mod-registered cities, custom city tabs and every mod's demand.setPersistence opt-in. The loader also empties the loaded-mod registry before re-executing. Kept: registered train types and station types, tile URL, layer and routing service overrides, city data files and default layer visibility, the lifecycle markers, the tutorial state, and every storage file. After the mods re-execute the loader replays onMapReady, onGameInit, onCityLoad, onDemandChange and onGameLoaded once each for the events that already happened in the current game; onGameInit replays only in a new-game session. The Reload Mods shortcut (Cmd/Ctrl+Shift+R by default) calls this function.

Returns: Promise<void>. Promise that resolves after the modding-api-reload-complete event with no error detail.

Throws:

  • loader does not report within 10000 ms: the promise rejects with Mod reload timed out.
  • loader reports an error: the promise rejects with an Error carrying the loader message.
  • clearing state throws: the promise rejects with that error, after logging [Modding API] Error during state clear: and notifying Failed to clear mod state.

Errors:

  • a mod script throws during reload: the loader records an execution error and continues; the promise still resolves.
  • a mod script cannot be fetched during reload: the loader records an initialization error and continues; the promise still resolves.

Hooks fired:

  • onMapReady (replayed when the map is loaded)
  • onGameInit (replayed when the current game started as a new game)
  • onCityLoad (replayed when a city is loaded)
  • onDemandChange (replayed when demand is loaded)
  • onGameLoaded (replayed when a save is loaded)

Side effects: in development builds logs [Modding API] Initiating hot reload... and [Modding API] State cleared for hot reload; shows the notification Mods reloading...; dispatches modding-api-reload-request on window.

Changed: reloadMods now also clears onTutorialStart and onTutorialEnd registrations, the onError reporter subscriptions, commute window and dampening overrides, custom newspaper templates and custom city tabs, and clears the new demand persistence opt-ins (PR #1090).

js
await api.reloadMods(); // DevTools console: re-runs every enabled mod, like Cmd/Ctrl+Shift+R