🚇/Docs

Career Missions

Create custom career challenges with win conditions

The career API lets you create custom missions with star-based goals. Players can play your missions from the career map, earning stars by completing your defined objectives.

Register a Mission#

javascript
const api = window.SubwayBuilderAPI;

api.career.registerMission({
    id: 'my-mod.speed-run',
    cityCode: 'NYC',
    name: 'NYC Speed Run',
    description: 'Build a profitable network in record time!',
    tier: 'starter', // 'starter' | 'growth' | 'mega'
    stars: [
        {
            id: 'star1',
            label: 'Build 5 stations within 5 game-days',
            shortLabel: '5 Stations',
            icon: '🚉',
            metric: api.career.METRICS.STATIONS_COUNT,
            target: 5,
            operator: api.career.OPERATORS.GREATER_OR_EQUAL,
            howTo: [
                'Open the BUILD panel at the bottom',
                'Click on the map to place stations',
                'Focus on high-demand areas'
            ],
            actionPanel: 'construction',
            actionLabel: 'Start Building'
        },
        {
            id: 'star2',
            label: 'Run 8 trains simultaneously',
            shortLabel: '8 Trains',
            icon: '🚃',
            metric: api.career.METRICS.TRAINS_COUNT,
            target: 8
        },
        {
            id: 'star3',
            label: 'Achieve $250K daily profit',
            shortLabel: '$250K Profit',
            icon: '💰',
            metric: api.career.METRICS.DAILY_PROFIT,
            target: 250000
        }
    ]
});

Star Definition Properties#

PropertyTypeRequiredDescription
idstringYesMust be 'star1', 'star2', or 'star3'
labelstringYesFull description of the goal
shortLabelstringYesCompact label (e.g., "10 Stations")
iconstringNoEmoji icon for the goal
metricstringYesMetric to track
targetnumberYesTarget value to reach
operatorstringNoComparison operator (default: '>=')
howTostring[]NoStep-by-step instructions
actionPanelstringNoPanel to open: 'construction', 'routes-list', 'demand-stats'
actionLabelstringNoLabel for the action button

Available Metrics#

Use api.career.METRICS.* for type-safe metric names:

ConstantValueDescription
STATIONS_COUNT'stations_count'Number of stations
TRAINS_COUNT'trains_count'Number of active trains
ROUTES_COUNT'routes_count'Number of routes
TRACKS_COUNT'tracks_count'Number of track segments
TOTAL_PASSENGERS'total_passengers'Passengers served today
RIDERSHIP_PERCENTAGE'ridership_percentage'% using transit
DAILY_PROFIT'daily_profit'Today's profit
TOTAL_REVENUE'total_revenue'Today's revenue
TOTAL_DEBT'total_debt'Sum of all bonds
MONEY'money'Current cash
`PLAYTIMEMINUTES``'playtimeminutes'`Real-world minutes
ELAPSED_DAYS'elapsed_days'In-game days

Geographic Metrics#

These require params with bounding boxes:

ConstantDescription
`PASSENGERSBETWEENREGIONS`Passengers from one region to another
`PASSENGERSFROMREGION`Passengers originating from region
`PASSENGERSTOREGION`Passengers traveling to region
`STATIONSINREGION`Stations within bounding box

Pre-defined NYC Regions#

Use api.career.REGIONS.NYC.* for common neighborhoods:

Brooklyn:

  • BUSHWICK, WILLIAMSBURG, BEDSTUY, GREENPOINT, DUMBO, DOWNTOWN_BROOKLYN

Manhattan:

  • `LOWERMANHATTAN`, `FINANCIALDISTRICT, TRIBECA, SOHO, EAST_VILLAGE`
  • `MIDTOWN`, `TIMESSQUARE`, `UPPEREASTSIDE`, `UPPERWEST_SIDE, HARLEM`

Queens:

  • `LONGISLANDCITY, ASTORIA`

Using Geographic Metrics#

javascript
// Track passengers between regions
{
    id: 'star1',
    label: 'Transport 1,000 passengers from Bushwick to Manhattan',
    shortLabel: '1K Bushwick→Manhattan',
    metric: api.career.METRICS.PASSENGERS_BETWEEN_REGIONS,
    target: 1000,
    params: {
        originBbox: api.career.REGIONS.NYC.BUSHWICK,
        destBbox: api.career.REGIONS.NYC.LOWER_MANHATTAN
    }
}

// Count stations in a region
{
    id: 'star2',
    label: 'Build 3 stations in Bushwick',
    shortLabel: '3 Bushwick Stations',
    metric: api.career.METRICS.STATIONS_IN_REGION,
    target: 3,
    params: {
        bbox: api.career.REGIONS.NYC.BUSHWICK
    }
}

// Custom bounding box: [minLng, minLat, maxLng, maxLat]
{
    id: 'star3',
    metric: api.career.METRICS.PASSENGERS_FROM_REGION,
    target: 500,
    params: {
        bbox: [-73.95, 40.70, -73.90, 40.75]
    }
}

Comparison Operators#

Use api.career.OPERATORS.*:

ConstantValueDescription
`GREATEROREQUAL`'>='Value >= target (default)
GREATER'>'Value > target
`LESSOREQUAL`'<='Value <= target
LESS'<'Value < target
EQUAL'=='Value == target
NOT_EQUAL'!='Value != target

Mission Tiers#

TierRequired StarsDescription
starter0Available immediately
growth4+Unlocked after 4 stars
mega10+Unlocked after 10 stars

Query Missions#

javascript
// Get your mod's missions
const myMissions = api.career.getMyMissions();

// Get all missions (including other mods)
const allMissions = api.career.getAllMissions();

// Get missions for a specific city
const nycMissions = api.career.getMissionsForCity('NYC');

// Unregister a mission
api.career.unregisterMission('my-mod.speed-run');

Example: Debt-Free Challenge#

javascript
api.career.registerMission({
    id: 'my-mod.debt-free',
    cityCode: 'CHI',
    name: 'Chicago Debt-Free',
    description: 'Build a transit empire without drowning in debt.',
    tier: 'growth',
    stars: [
        {
            id: 'star1',
            label: 'Build 10 stations',
            shortLabel: '10 Stations',
            icon: '🏗️',
            metric: api.career.METRICS.STATIONS_COUNT,
            target: 10
        },
        {
            id: 'star2',
            label: 'Keep total debt under $100K',
            shortLabel: 'Debt < $100K',
            icon: '📉',
            metric: api.career.METRICS.TOTAL_DEBT,
            target: 100000,
            operator: api.career.OPERATORS.LESS_OR_EQUAL,
            howTo: [
                'Avoid taking bonds when possible',
                'Build incrementally',
                'Focus on profitable routes first'
            ]
        },
        {
            id: 'star3',
            label: 'Serve 5% of the population',
            shortLabel: '5% Ridership',
            icon: '👥',
            metric: api.career.METRICS.RIDERSHIP_PERCENTAGE,
            target: 5,
            actionPanel: 'demand-stats',
            actionLabel: 'View Demand Map'
        }
    ]
});

How It Works#

  1. Registration: Your mission is added to the career registry
  2. UI Integration: Mission appears with a purple "MOD" badge
  3. Progress Tracking: Game automatically tracks progress
  4. Custom Instructions: Your howTo steps appear in the UI
  5. Action Buttons: Quick-action buttons open specified panels

Notes:

  • Mission IDs should use reverse-domain style (e.g., my-mod.mission-name)
  • Each mission can have 1-3 stars
  • Stars are evaluated in real-time and persisted to career profile
  • If no howTo is provided, game generates default instructions