PURPOSE

Mission node selection screen. Presents a list of hardcoded starter mission nodes, lets the player pick one, assembles a RunDefinition from the session store’s ship selection plus the chosen node, writes it back to the session store, and navigates to the gameplay route.

OWNS

  • The LevelSelectScreen React component (default route render).
  • The MissionNode interface used internally to describe display rows.
  • The MISSION_NODES constant — five hardcoded starter nodes (sector_1a, sector_1b, sector_2a, sector_2b, sector_3a) with id, label, missionType, heat, biome, timerSeconds, and desc.
  • The TYPE_COLORS map from mission type string to hex color (explore, deliver, defend, defeat, steal, heist, escort, capture).
  • The local selectedNode state (mission node id string).
  • The HeatDots subcomponent that renders ten dots, filled up to the heat value, colored green / yellow / red by tier.
  • The hexToRgb helper that parses a #rrggbb string into a comma-joined r,g,b string for inline rgba backgrounds.
  • The handleLaunch callback that assembles the run definition and navigates.

READS FROM

  • useSessionStoreselectedShipId (passed into the assembled run definition).
  • react-router-domuseNavigate for programmatic navigation.
  • ../services/assembleRunServiceassembleRunDef to build the RunDefinition from ship id and node fields.

PUSHES TO

  • useSessionStore.setRunDef — writes the assembled RunDefinition into the session store before navigation.
  • Router — navigates to /games/starship-survivors/play on launch.
  • The home route / via a Link in the header.

DOES NOT

  • Does not read from or write to a progression or metagame store; the node list is hardcoded in this file.
  • Does not generate nodes from a sector graph or other procedural source.
  • Does not validate the ship selection — if selectedShipId is falsy the run definition is still assembled with whatever the assemble service produces.
  • Does not gate launch behind any unlock, currency, or fuel check.
  • Does not persist the last-selected node across mounts; selectedNode defaults to the first node every time.
  • Does not handle missions with mission types outside the TYPE_COLORS map specially; the fallback color is hardcoded to the explore green.
  • Does not surface biome to the player in the UI even though it is part of the node data and is passed to the assemble service.

Signals

  • Click on a mission node button — sets selectedNode to that node id and re-renders the list with the selected styling.
  • Click on the LAUNCH MISSION button — invokes handleLaunch, which looks up the selected node, assembles the run, stores it, and navigates.
  • Click on the HOME link — routes back to /.

Entry points

  • LevelSelectScreen — named export, mounted by the app router for the level-select route.

Pattern notes

  • Hardcoded data table at module scope (MISSION_NODES) — flagged in the comment as temporary until progression / metagame generates nodes.
  • TYPE_COLORS includes mission types not present in the current MISSION_NODES list (steal, heist, escort, capture) — anticipates future node types without code changes.
  • Heat color tiers are inline in HeatDots rather than constants: <=3 green, <=6 yellow, otherwise red.
  • Timer display is suppressed when timerSeconds === 0 (used by the boss-arena node).
  • Selected-state styling derives the row background from the type color via hexToRgb plus 0.1 alpha, and the border switches from a low-alpha white to the full type color.
  • Launch button is fixed to the bottom of the viewport with a gradient backdrop; the page reserves pb-24 so list content can scroll behind it.
  • All styling is a mix of Tailwind utility classes and inline style objects; the screen’s color palette is local rather than pulled from a theme module.