Newspaper templates

Newspaper templates

MemberReturnsSummary
api.registerNewspaperTemplates(templates)voidAppend newspaper templates to the global list the newspaper service merges into its template pool.

Newspaper Templates#

registerNewspaperTemplates#

api.registerNewspaperTemplates(templates: any[]): void

Append newspaper templates to the global list the newspaper service merges into its template pool.

The service appends the list to the base templates every time it draws an article. The list is never cached, so templates registered at any point in the session take part in the next draw. Entries are not validated. The fields the service reads, the metadata options, the requiredGameState filters and the template variables are in the tables on the Newspaper templates reference page. The list is emptied on reloadMods. Logs [Modding API] Registering <n> custom newspaper templates (development builds only).

Parameter templates (any[]): template objects to append; must be an array.

Errors:

  • templates not an array: logs [Modding API] Invalid templates - must be an array, appends nothing.
  • exception: logs [Modding API] Error registering newspaper templates:.

Side effects: window.__customNewspaperTemplates created or appended.

Changed: Mod templates are merged at every draw instead of being cached with the base templates, so late registrations are picked up and a removed mod's templates do not persist; the list is cleared on reloadMods (PR #1090).

js
api.registerNewspaperTemplates([{
  headline: '{{CITY}} Opens {{NEWEST_STATION}}',
  content: 'Day {{DAY}}: {{STATIONS}} stations and {{ROUTES}} routes.\nThe treasury holds {{TREASURY}}.',
  metadata: { category: 'expansion', tone: 'celebratory', weight: 8, requiredGameState: { minStations: 5, financialStatus: 'stable' } },
}]);

Template Fields#

FieldTypeEffect
headlinestringHeadline text; template variables are replaced in it. Also the seen-key: unseen headlines are preferred, and seen headlines (kept in localStorage under subway-builder-seen-templates) are drawn again only when every template that passed the filters has been seen.
contentstringArticle body; \n separates paragraphs; template variables are replaced in it.
metadataobjectOptions below.

Metadata Options#

OptionTypeEffect
category'milestone', 'expansion', 'delay', 'financial', 'political', 'human_interest', 'investigation', 'opinion', 'crisis', 'comedy'Only 'comedy' changes selection (see below). 'crisis', 'delay', 'financial' and 'investigation' rank stations and routes by warnings first for the variables.
tone'celebratory', 'critical', 'neutral', 'investigative', 'humorous', 'concerned', 'satirical', 'urgent'Not read by selection. 'critical', 'urgent' and 'concerned' rank stations and routes by warnings first for the variables.
weightnumberWeight in the weighted random pick among the surviving templates; omitted or 0 counts as 5.
requiredCitystringCity code; the template is used only in that city. Scores 2 for specificity.
isTutorialbooleantrue excludes the template from automatic articles.
requiredGameStateobjectFilters below; every one given must pass.

A 'comedy' template is dropped while the treasury is under $10M, while the system is overcrowded (see isOvercrowded) or has fewer than 5 stations, and otherwise survives a 50% roll. When the comedy checks drop every applicable template, the draw uses all of them.

Required Game State Options#

OptionTypePasses when
minStations, maxStationsnumberStation count is at least / at most the value.
minRoutes, maxRoutesnumberRoute count is at least / at most the value.
minTrains, maxTrainsnumberActive train count is at least / at most the value.
minPassengers, maxPassengersnumberTotal passengers are at least / at most the value.
minDays, maxDaysnumberDay number is at least / at most the value.
minHubs, maxHubsnumberHub count (stations with more than one route) is at least / at most the value.
maxStationWaitingnumberThe largest waiting count at any station is at least the value. The count is yesterday's peak when observed, else the last observed day's, else the current count.
hasHubbooleanChecked only when true: some station has more than one route.
hasNoPassengers, hasNoTrains, hasNoStationsbooleanChecked only when true: the count is 0.
isOvercrowdedbooleanChecked only when true: a route has a warning, a station has 100 or more waiting, or yesterday's passengers exceed 80% of system capacity.
isBrokebooleanChecked only when true: treasury under $10M.
isRichbooleanChecked only when true: treasury over $1M. Between $1M and $10M both isBroke and isRich pass.
financialStatusstringTreasury band matches: 'bankrupt' (under $0), 'broke' (under $10M), 'scraping by' (under $100M), 'stable' (under $1B), 'thriving' (under $10B), 'wealthy' (under $100B), 'absurdly rich' (under $1T), 'obscenely wealthy' (under $10T), 'economy-breaking' (above).
dailyRidershipGrowthstringGrowth band matches: 'explosive', 'growing', 'stable', 'declining' or 'dead'.
ratiosobject{ min?, max? } per ratio: trainsPerStation, passengersPerTrain, capacityUsage (0 to 2), stationsPerRoute, moneyPerDay, stationsPerDay, passengersPerDay, moneyPerStation, passengersPerStation, routesPerStation.

Among the templates that pass, each requirement scores 1, each ratio 2 and requiredCity 2. Templates more than 2 points below the most specific survivor are dropped before the weighted pick.

Template Variables#

Replaced in headline and content when an article is drawn. Variables on one row are aliases. Ranked stations and routes are sorted by ridership (then route count, waiting and warnings), or by warnings first for the disruption categories and tones above.

VariableReplaced with
{{CITY}}, {{CITY_NAME}}, {{cityName}}City name.
{{DAY}}, {{DAYS}}Day number.
{{DATE}}Calendar date of the day, counted from January 1, 2024 (for example January 15, 2024).
{{STATIONS}}, {{STATION_COUNT}}Station count.
{{ROUTES}}, {{ROUTE_COUNT}}Route count.
{{TRAINS}}, {{TRAIN_COUNT}}Active train count.
{{TREASURY}}, {{BUDGET}}Treasury, formatted ($4.2 million, $1.1 billion).
{{PASSENGERS}}, {{TOTAL_PASSENGERS}}Total passengers.
{{YESTERDAY}}, {{YESTERDAY_PASSENGERS}}Yesterday's passengers.
{{TRACK_KM}}, {{TRACKS_KM}}Track length in km, one decimal.
{{TRAINS_PER_STATION}}, {{PASSENGERS_PER_TRAIN}}, {{STATIONS_PER_ROUTE}}, {{SYSTEM_CAPACITY}}, {{CAPACITY_USAGE}}System ratios.
{{STATIONS_PER_DAY}}, {{PASSENGERS_PER_DAY}}, {{MONEY_PER_DAY}}, {{MONEY_PER_STATION}}, {{PASSENGERS_PER_STATION}}Growth and per-station figures.
{{HUB_COUNT}}Stations with more than one route.
{{FINANCIAL_STATUS}}Treasury band, as in financialStatus.
{{FIRST_STATION}}, {{OLDEST_STATION}}First station in the station list.
{{NEWEST_STATION}}Last station in the station list.
{{BUSIEST_STATION}}Station with the most riders.
{{STATION}}, {{STATION2}}, {{STATION3}}First, second and third ranked station. {{STATION_1}} to {{STATION_4}} and {{stationName}} work the same way.
{{RANDOM_STATION}}Random station among the top 5 ranked.
{{STUCK_STATION}}Station with the most waiting passengers.
{{ROUTE}}, {{ROUTE_1}}, {{ROUTE_2}}, {{ROUTE_3}}Ranked route bullets in the route color. {{routeName}} and {{bullet}} match {{ROUTE}}.
{{LONGEST_ROUTE}}, {{SHORTEST_ROUTE}}Route with the most / fewest stations, as <bullet> Line.
{{MAYOR}}, {{MAYOR_NAME}}The city's mayor, or a default name.
{{AGENCY}}, {{TRANSIT_AGENCY}}The city's transit agency, or a default name.
{{NAME1}}, {{NAME2}}, {{NAME3}}Random person names; also {{NAME_1}} to {{NAME_5}}, {{COMMUTER}}, {{DRIVER}}, {{EXPERT_NAME}} and other _NAME variables.
{{TITLE}}, {{TITLE1}}, {{TITLE2}}, {{TITLE3}}Random job titles.
{{PERCENT}}The busiest station's share of riders (or capacity use) plus or minus 10, as NN%.
{{MINUTES}}Minutes scaled to the longest station queue, with a little noise.
{{RANDOM_MONEY}}A sum scaled to the treasury.
{{COMMUTERS}}<n> commuters, scaled to yesterday's passengers.
{{DISTRICT}}, {{LANDMARK}}, {{STREET_1}}, {{INTERSECTION_1}}, {{PLATFORM}}, {{TUNNEL_NAME}}Random places.
{{ADJECTIVE}}, {{COMPLAINT}}, {{TIME_PERIOD}}, {{BUSINESS}}, {{TIME}}, {{SMALL}}Random filler words and small numbers.