manifest.sys — feature index

Feature Map

Canonical index of every screen, panel, overlay & sub-view · feature_map() in the dev console

Use this when you need to answer where does this feature live?, which component renders this pane?, or is there already a place for this, or am I creating a new one? The companion markdown lives at feature-map.md; the styling source of truth is style-guide.md + /style-guide/.

00 · Overview

Top-level routing happens in src/App.tsx and is driven by state.screen (one of 'title' | 'map' | 'docked' | 'denied' | 'transit' | 'gameover', defined in src/state/types.ts). Persistent chrome stacks on every non-title screen; overlays and modals stack on top.

Quick reference

ResourcePath
Top-level routingsrc/App.tsx
Game state shapesrc/state/types.ts
Reducersrc/state/reducer.ts
Static game datasrc/data/
Pure game logicsrc/engine/
Component CSSco-located: src/components/Foo.tsx + Foo.css
Style specstyle-guide.md, style-guide/index.html (/style-guide/)

01 · Window Taxonomy

Every visible UI surface, grouped by its window class. One row per pane — tabs inside a tabbed window are listed individually, not folded into the parent.

ClassDefinition
ScreenFull-canvas window. Mutually exclusive with other screens. Driven by state.screen.
PaneOne tab inside a tabbed screen.
Sub-surfaceInternal region of a screen with its own chrome (rails, strips, rosters).
OverlayFloats above the active screen, persists across screens, dismissed by the user.
ModalFloats above, blocks input, decision-driven dismissal.
Persistent chromeAlways rendered, not a window.

1a · Screens

PaneFilestate.screenGame systems housed
TitleScreensrc/components/TitleScreen.tsxtitleMain menu — new game, load, options. Bypasses TopBar / overlays.
StarMap (map mode)src/components/StarMap.tsxmapTravel / pathfinding, scan / survey, plot routing. Sub-surfaces in §1c.
StarMap (transit mode)src/components/StarMap.tsxtransitSame SVG canvas as map, but the TransitConsole bottom strip replaces FlightPlanStrip. Ship sprite animates the edge.
DockPanelsrc/components/DockPanel.tsxdockedTwo-column docked view — wraps StationPanel (left) + ShipPanel (right). Tabs in §1b.
DeniedPanelsrc/components/DeniedPanel.tsxdeniedHostile / story-locked station rejection. Faction system surfaces error here.
GameOverPanelsrc/components/GameOverPanel.tsxgameoverEnd-of-run summary.
Transit has no standalone screen.  state.screen === 'transit' is served by StarMap in transit mode — the live transit UI is the TransitConsole bottom HUD (a StarMap sub-surface, §1c), not a separate component. The old TransitScreen.tsx was dead / orphaned code and has been deleted; don't recreate it.

1b · Panes (tabs)

StationPanel  — left column of DockPanel

File: src/components/StationPanel.tsx. A .station-hero header (station art + faction emblem + standing bar) sits above a two-level tab nav: four primary groups (Trade / Services / People / Info) and, when a group has more than one tab, a secondary .station-subtabs row. Each tab's visibility depends on station.shipyard, station.outfitting, etc.

GroupPaneTab keyGame systems housed
TradeStationPanel.marketmarketBuy / sell goods. Row click opens GoodInfoModal.
TradeStationPanel.jobsjobsContract board — accept/deliver generated, time-limited delivery contracts (outward = frontier, homeward = premium runs to the start region). Cargo-consuming hand-in; deadline countdowns; "days since home" + Agri-Guild standing-decay readout. Owned by contracts.ts.
ServicesStationPanel.shipyardshipyardDock services + browse / buy ships (tab labelled Dock).
ServicesStationPanel.loadoutloadoutLoadout — installed modules and the station locker as plain lists (slot badge + name + stats + Stow / Sell / Install). Single home for inspecting & swapping the current fit; no ship-image overlay.
ServicesStationPanel.outfittingoutfittingOutfitting — buy new modules from the station catalogue (install / trade-in).
ServicesStationPanel.gathergatherMining tab (shown only when station.gatherables is non-empty) — single rig-driven MINE button per deposit; yield and ore-tier access scale with the installed mining module.
PeopleStationPanel.commscommsMission board — accept / hand-in story steps. Faction rep gating. The Log (L) tracks all in-progress missions.
PeopleStationPanel.crewcrewHire / dismiss crew.
InfoStationPanel.infoinfoStation details, description, environment (atmosphere / temp / gravity). Faction identity + standing live in the hero header.
Lore-only stations. beacon / derelict / anomaly categories skip the normal tab strip entirely and render a single lore view (.lore-only-view) — history blurb + tag pills — instead.

ShipPanel  — right column of DockPanel

File: src/components/ShipPanel.tsx. A fixed-width sidebar (flex: 0 0 clamp(380px, 36%, 480px)) with no tabs — an always-on summary that stacks the readouts, crew roster, and cargo list.

SectionGame systems housed
ReadoutsCargo / fuel / crew / engine / scanner / hull readouts, mass & speed.
CrewHired crew roster + upkeep.
CargoInventory list with quantities + value.
Modules are not shown in ShipPanel. Install / inspect / swap lives on the station's Services → Loadout sub-tab (StationPanel.loadout). The old ShipPanel schematic tab and its drag-drop ShipSchematic overlay were retired in the declutter to give modules a single, list-based home.

StoryPanel  — Star Map .starmap-nav-dock tabs (L key)

File: src/components/StoryPanel.tsx. Not a standalone window — it renders in the lower section of the Star Map's navigation sidebar (.starmap-nav-dock, §1c) as the Missions / Factions / Codex tabs alongside the Roster. [L] jumps to the Missions tab. Accepts a controlled tab prop + showTabs={false} so the sidebar's tab strip drives it.

PaneTab keyGame systems housed
StoryPanel.missionsmissionsActive steps, ready-to-hand-in, chain progress, story-flag unlocks.
StoryPanel.factionsfactionsAll four factions at a glance — current rep, rank, trade modifiers, progress to next rank, and each faction's rivalry/ally relations (drives reputation spillover).
StoryPanel.codexcodexPublic FIELD RECORDS (visit-unlocked lore dossiers) + story-gated CLASSIFIED intel (secrets, sealed until their reveal flag fires).
Missions and Codex live in the Star Map nav sidebar only — they used to be tabs in ShipPanel, then a full-screen overlay, then a toggled right-rail panel. Now they're the lower tabs of the persistent .starmap-nav sidebar (Roster · Missions · Factions · Codex) — the single home. Don't add them back elsewhere.

1c · Sub-surfaces (Star Map zones)

StarMap.tsx is a two-column shell (.starmap-layout), mirroring the docked layout: a map canvas (.starmap-root, left, flexible) + a persistent navigation sidebar (.starmap-nav, right, clamp(340px,32%,420px)). The old floating Intel / roster / bottom-strip windows were folded into the sidebar.

PaneSub-componentClass rootGame systems housed
StarMap.FilterChipsFilterChips.starmap-corner-hud, .starmap-filterbar, .starmap-filters(On canvas.) Interactive faction-filter chips (All / per-faction / Neutral / Hostile). Dims non-matching nodes. Collapsed by default behind a .starmap-filter-toggle ("FILTERS") that reveals the chip row; a cyan .starmap-filter-badge shows the active-filter count while collapsed.
StarMap.ZoomControlsinline.starmap-zoom(On canvas.) Zoom in/out, percentage, reset (RST).
StarMap.StationNode (×N)StationNode.starmap-node(On canvas.) Per-station glyph: ring (category vs. faction), pulse on current, dashed ring on plotted, hostile / dimmed / unknown variants. Lane-locked variant (.is-lane-locked): a discovered node reachable only through a hard-locked lane renders desaturated with a dashed alert ring. Labels gate by zoom (LABELS_MIN_ZOOM, 120%) + priority states (current / selected / hovered / plotted / on-route); survey badges (L1–L7) show only on hover/selection.
StarMap lanes (edges)inline EDGES.map.starmap-edge(On canvas.) Connection lines. Lane-lock variants: .is-toll (amber dashes) and .is-locked (alert dashes), with a midpoint .starmap-edge-lock tag (e.g. TOLL 120c, BLOCKADE) and a <title> reason. Lock state comes from engine/lanes.ts; a paid-off one-time toll reverts to a plain lane.
StarMap.NavContextinline.starmap-nav-contextSidebar top. Stacked & scrollable context: TransitConsole in transit, else IntelPanel (selected or current station) + FlightPlanStrip (when a route is plotted) + IdleHint fallback.
StarMap.IntelPanelIntelPanel.starmap-intelStation survey readout (scan-gated rows, survey-progress bar, SCAN / CENTER / DOCK). Inline in the sidebar; close (×) only for an explicitly-selected station. Body shows core facts; trade rows + description collapse behind a .intel-more-toggle (MORE/LESS, default collapsed).
StarMap.FlightPlanStripFlightPlanStrip.starmap-flightWaypoint trail, 5-stat totals (+ a TOLL stat when the route crosses a paid lane), next-leg row, JUMP button. A .flight-block "LANE LOCKED" banner with the reason replaces the route when no open path exists (button → NO ROUTE); insufficient toll credits → NO CREDITS. Reflowed to a column in the sidebar.
StarMap.TransitConsoleTransitConsole.starmap-transit-consoleOrigin → destination, progress bar with ship marker, ETA / elapsed, risk pips, drive status.
StarMap.IdleHintIdleHint.starmap-idle-hintHint shown in the context area when there's no current/selected station.
StarMap.NavDockinline + SectorRoster / StoryPanel.starmap-nav-dockSidebar bottom — always visible, tabbed. A .starmap-dock-tabs strip switches between Roster (searchable station list; click selects + plots + focuses) and Missions / Factions / Codex (renders StoryPanel, §1b). [L] jumps to Missions. Roster tab only with a current station, not in transit. The "Sector Roster" heading is a .starmap-dock-toggle that collapses/expands the list (open by default); collapsed (.is-collapsed) the dock shrinks to its heading strip and the freed space goes to the nav-context above.
Context priority — in transit, only TransitConsole shows. Otherwise Intel (selected-or-current) and the plotted-route FlightPlanStrip stack together in the scrollable context area, so SCAN/DOCK and JUMP stay reachable.

1d · Overlays

PaneComponentTriggerGame systems housed
Controls / helpControlsOverlay? or / keyKeyboard + mouse reference.
Story / Missions is no longer an overlay — it now lives in the Star Map's .starmap-nav sidebar (§1c).
Esc precedence on the map — missions log → Intel panel → plotted route (handled in StarMap.tsx); the controls overlay handles its own Esc in App.tsx.

1e · Modals

PaneComponentTriggerGame systems housed
EventEventModalReducer sets state.activeEventRandom encounters. Blocks input; 1 / 2 / 3 to pick a response.
CommsCommsModalReducer sets state.activeComms — opening (START_GAMEintro.ts), accept→briefing, complete→debrief, dock-tab Talk (OPEN_COMMScharacter.idle)Interactive story transmissions — complete, stationary, left-aligned lines with space/click to advance and number keys for replies. Choices display consequences, persist flags/effects, and enter the captain log. Standard dialogue uses an avatar panel; pivotal evidence cutscenes promote a wide still with an evidence caption and omit the redundant portrait. Speakers resolve via resolveSpeaker (data/staff.ts): named characters/*.json or synthetic generic:… clerks.
ArrivalArrivalModalAfter transit → map with currentStationId setArrival flow — DOCK / MINE / EXPLORE / STAY IN ORBIT. Faction-rep gating.
Good infoGoodInfoModalClick a market row in StationPanel.marketGood details + lore tip.

1f · Persistent Chrome

Rendered on top of every non-title screen. Not windows — never call them "panels".

ElementComponentFileGame systems housed
Top barTopBarsrc/components/TopBar.tsxDay · credits · fuel (segmented bar) · hull (segmented bar) · location · [M] DOCK (map only) · SAVE · MENU.
Error boundaryErrorBoundarysrc/components/ErrorBoundary.tsxWraps the shell — renders a fallback on thrown error.
Scanlines + small-viewport warninginlinesrc/App.tsxPure visual overlay; no logic.

1g · Proposed — new homes for orphaned systems

These game systems exist in the engine / data but have no canonical window today — they're either scattered inline across unrelated panels or invisible after the moment they fire. Each row below is a proposed new pane; none of these are implemented yet. Documenting them as the agreed home prevents the next ad-hoc inline render from deepening the scatter.

Proposed paneStatusWhat it would showSource
StoryPanel.log proposed Reverse-chronological event history — events fired, choices taken, outcomes. Currently events vanish after RESOLVE_EVENT. Needs reducer to keep a bounded state.eventHistory array on each RESOLVE_EVENT.
StoryPanel.gathering (optional, lower priority) proposed Resources gathered, cooldowns, eligible nodes. state.gatheringHistory (new) + station.gatherables lookups.
PriorityStoryPanel.factions shipped (see §1b), implemented with the reputation-spillover system. StoryPanel.log is medium. StoryPanel.gathering is optional.
When you implement one of these, move the row from §1g into §1b in the same change.

02 · Shared Components

Canonical implementations of UI patterns that appear in multiple panes. Located at src/components/shared/. Do not duplicate these inline — import from shared/. If you find a pattern rendered in 2+ panes with cosmetic drift, promote it here.

ComponentClass prefixConsumersRenders
ObjectiveList.obj-*StoryPanel · StationPanel.comms · StationPanel.jobs · ShipPanelMission objective checklist with progress + done states.
CodexList.codex-*StoryPanel.codexPublic FIELD RECORDS — discovered lore dossiers + undiscovered titles list.
ClassifiedList.classified-*StoryPanel.codexStory-gated CLASSIFIED intel — revealed secret bodies + sealed teaser rows. Gated by secrets.ts reveal flags; in-game only, never on public pages.
MissionStepCard.mission-step-*StoryPanel.missionsMission step card — chain badge, title, description, objectives, reward. Variants: default / ready-handin / auto-complete / new-mission.
ChainRow.mission-chain-*StoryPanel.missionsChain progress row with status pill (LOCKED / IN PROGRESS / COMPLETE), faction, step count, optional prereq.
StoryFlagRow.mission-flag-*StoryPanel.missionsSingle unlock row in the UNLOCKS section.
StatBar.stat-bar-*TopBar (fuel + hull) · ShipPanel (cargo / fuel / crew / speed / scanner / hull)Segmented stat indicator. Supports fixed colour, tier mode (auto low/mid/ok colour by pct), and blinkOnCritical (≤ 10%). Replaces the previous FuelBar / HullBar / Bar.
Shared modal chrome — the .modal-overlay / .modal-panel classes live in src/styles/global.css (not a shared/ component) and are the single backdrop + panel pattern consumed by every modal: EventModal, GoodInfoModal, ArrivalModal, ControlsOverlay. Don't hand-roll a new overlay backdrop; reuse these.
Promotion rule — when the same data is rendered with cosmetic drift in 2+ components, extract a shared/Foo.tsx + Foo.css with a single foo-* class prefix, replace the duplicates, and add a row to this table.

03 · Engine Modules

Pure modules under src/engine/. No React imports. Each pane consumes zero or more of these to compute display values.

ModuleOwnsConsumers
travel.tsPath-finding (incl. findOpenPath — lane-lock-aware BFS), distance, fuel cost, station lookupStarMap, FlightPlan, Transit
lanes.tsPer-lane locks (pass / blockade / toll / rep) keyed by sorted endpoint pair. isLaneOpen / getLaneToll / lanePassToSet / laneLockReason / routeTollTotal. Toll lanes stay passable; one-time tolls buy a passFlag.StarMap (lane render + reachability), reducer (START_TRAVEL gate + toll charge)
economy.tsPricing, stock, supply/demand modifiersStationPanel (market)
shipStats.tsEngine speed, fuel efficiency, cargo capacity, scanner depth, cargo riskTopBar, StarMap, ShipPanel
events.tsEvent rolls + risk evaluationStarMap (transit), EventModal
environment.tsThermal / radiation hazardsreducer.applyArrivalProcessing
story.tsStory step graph, station accessibility, story-gated stations/goods/modules/shipsStarMap, StationPanel.comms, StoryPanel
contracts.tsDynamic job board — seeded contract generation/refresh/expiry, cargo-consuming hand-in, home-region rep decayStationPanel.jobs, reducer (day-advance)
reputation.tsCentral reputation writer — applies a rep change plus rival/ally spillover (matrix in balance.json), returns the change-list for the multi-faction toastreducer (trade/events), contracts, story
objectives.tsDerives per-step objective listsshared/ObjectiveList
hexGrid.tsHex maths legacy

04 · Static Data

All under src/data/. Loaded at build time. Every entity follows the same convention: one JSON file per entity, aggregated into an array by a thin .ts wrapper using import.meta.glob. No data is inline in TypeScript.

WrapperJSON globDrives
stations.tsstations/*.jsonEvery node on the star map; market exports/imports; gatherables.
lanes.tslanes/*.jsonPer-lane lock overrides. Only locked lanes get a file (endpoints + lock); every other connection (derived from station connections) defaults open. Consumed by engine/lanes.ts.
ships.tsships/*/info.jsonShipyard inventory + archetypes + gameplay stats.
modules.tsmodules/*.jsonOutfitting catalogue (engines, fuel tanks, scanners, etc.).
goods.tsgoods/*.jsonTradeable items + categories.
factions.tsfactions/*.jsonFaction list, colour, reputation thresholds. Also exports rep-tier logic.
crew.tscrew/*.jsonHireable crew templates.
characters.tscharacters/*.jsonStory speakers (name, role, station, faction, glyph, avatar, idle Talk dialogue) for CommsModal. Exports CHARACTERS + CHARACTERS_BY_ID + getCharacter.
staff.ts(resolver)Station + dock tab → NPC. getTabCharacter(station, post) returns the named station.staff character or a generic faction clerk; resolveSpeaker resolves generic:… ids. Drives NPCHeader.
story.tsstory/*.jsonMission chains, objectives, dialogue.
lore.tslore/*.jsonPublic codex dossiers (FIELD RECORDS) unlocked by visits / events. Exports both LORE_ENTRIES (array) and LORE_BY_ID (Record).
secrets.tssecrets/*.jsonStory-gated CLASSIFIED codex entries. Each has a revealFlag; isSecretRevealed() checks it against storyFlags. Bodies lifted from STARWIND_LORE.md §10.
stationInventory.tsPure filter logic. Resolves station services against storyFlags + factionRep.
balance.tsbalance.json (single file)Tunable gameplay constants — tier margins, stock curves, price drift, base event chance, planet bias, engine multipliers, travel scale, starting credits. economy/events/shipStats/travel/initialState import BALANCE instead of hardcoding magic numbers.
Rule: static data lives in *.json. If you find inline data in a .ts file under src/data/, split it into per-entity JSON files and reduce the .ts to an import.meta.glob wrapper. The existing wrappers are the template. balance.json is the one deliberate single-file exception (a flat config, not entities) — add new tunables there.

4a · Data editor (/editor/ — dev-only)

A password-gated editor for tweaking the static-data JSON (and balance.json) against the running game, for balancing. Dev-only: it lives under npm run dev and is deliberately excluded from vite build (not in rollupOptions.input), so it 404s on a deployed site.

PieceWhereRole
Editor SPAeditor/index.html + src/editor/Login gate → seven modes (Files / Map / Flags / Story / Economy / Doctor / Reputation). Files = sidebar + GUI form editor (Raw-JSON toggle) + Save (⌘S); the rest are read-only analytical views.
Map modesrc/editor/MapView.tsxInteractive SVG star map: drag nodes (writes x/y), Connect mode toggles links, add/delete stations. Click a lane (edge) to set/clear its lock (pass / blockade / toll / rep) — writes/deletes a lanes/*.json file (keyed by sorted endpoints). Locked/toll edges render in alert/amber with a midpoint tag.
Flags modesrc/editor/FlagsView.tsxRead-only index of every story flag (from STORY_CHAINS + LANES + the STORY_GATED_* maps): where it's set, required, and what it gates. Flags orphans ("no story source" / "set, never read"); click a source to open the chain.
Story modesrc/editor/StoryGraphView.tsxMission graph: each chain's steps in flow order with trigger / completion / rewards, the flag gate that unlocks the chain, and the flags + content each step unlocks.
Economy modesrc/editor/EconomyView.tsxGoods × stations trade matrix (Export/Import per cell) with tier / price / min-rep; flags one-sided goods (no exporter or no importer).
Doctor modesrc/editor/DoctorView.tsxCross-file integrity sweep: broken refs, orphan goods/ships/modules, story trigger/goods/station/faction refs, gate & secret flags with no source, speaker↔character mismatches, stations unreachable from Verdant.
Reputation modesrc/editor/ReputationView.tsxFaction relationship matrix (rival/ally spillover from balance.json) + station ownership + every story step that grants rep, per faction.
Schemassrc/editor/schemas/*.schema.jsonOne strict JSON Schema (draft-07, additionalProperties:false) per data type — the validation "standard". schema.ts maps each file path to its schema.
Form generatorsrc/editor/SchemaForm.tsxRecursive, schema-driven widgets: objects, arrays, enums→selects, numbers/booleans, optional add/remove, $ref, free-form params as raw-JSON islands, "unknown field" drift rows.
Validationsrc/editor/schema.ts (Ajv)Validates on every edit; Save blocked while invalid. Files without a schema fall back to the raw editor.
Related panelsrc/editor/refs.ts (right sidebar)Cross-reference graph: References → (live from the edited value) and Referenced by ← (static index over all files via import.meta.glob), grouped by category, click to open, broken refs flagged. Driven by x-ref schema annotations.
BackendeditorPlugin() in vite.config.ts (apply: 'serve')Auth + read/write API at /api/editor/*, path-allowlisted to src/data/**.json.
AuthEDITOR_PASSWORD in .env.local (gitignored, no VITE_ prefix → server-side only)Password mints an in-memory session token; every read/write requires it.

Schemas cover all 10 entity types plus balance.json; every existing data file validates clean. Saving writes the real source JSON on disk (canonical 2-space); Vite HMR then reloads any open /game/ tab. See .env.local.example to enable.

Two different /editors. The dev-only data editor above (Vite, localhost) is unrelated to the deployed admin console at starwind.darkvision.dev/editor (§4b). Different runtimes, different jobs — the dev one edits source JSON, the prod one shows players/saves.

4b · Telemetry server + admin console (deployed)

A standalone Node service (server/, Fastify + node:sqlite) on the OVH box. Not part of the game build or static rsync — it runs as its own systemd service; nginx serves the static game and reverse-proxies /api/* + /editor to it.

PieceWhereRole
Telemetry ingestserver/src/routes/telemetry.mjsPOST /api/sync (save + version + last-played mirror), POST /api/heartbeat (presence). Validated, rate-limited, size-capped.
Admin APIserver/src/routes/admin.mjsLogin (signed httpOnly cookie) + players list / save view / delete.
Admin consoleserver/public/editor.html/editorPlayer table: callsign · online dot · version · last played · save size; save viewer + download.
Data storeserver/src/db.mjsOne SQLite file (WAL), one row per player, latest save inline. Repository pattern → Postgres-swappable.
Game clientsrc/net/telemetry.tsPlayer ID + callsign (captured on TitleScreen first New Game), throttled save push + 30s heartbeat. Fire-and-forget.
Deployserver/deploy/ + server/README.mdsystemd unit, nginx config, updated webhook deploy script.

Saves are a mirror: localStorage stays the source of truth for playing; the server copy exists for the console. No cross-device restore.

4c · Public guide (generated)

The player-safe documentation portal at /guide/ is generated from docs/public/*.md and docs/catalog.json. scripts/generate-docs.mjs emits a landing page, clean chapter routes, and a static search index during predev and prebuild.

PieceWhereRole
Catalogdocs/catalog.jsonOrdered documentation lookup and public/maintainer audience allowlist.
Public sourcedocs/public/*.mdCanonical spoiler-free player guide.
Generatorscripts/generate-docs.mjsSafe Markdown rendering, navigation, table of contents, pagination, and search records.
Auditscripts/docs-audit.mjsIDs/slugs, sources, links, audience boundary, generated coverage, and search coverage.
Shared clientpublic/guide.css + public/guide.jsReference-page layout, responsive chapter rail, and in-browser search.

Generated guide HTML and public/guide/search-index.json are ignored build output. Maintainer runbooks never enter dist/.

05 · Keyboard Map

Handled in App.tsx (handleKey) unless noted. ? / / always toggles ControlsOverlay.

KeyScreen(s)Action
MmapDock at current station
MdockedUndock back to map
K · S · UmapAlias for dock
JmapJump to plotted destination (handled in StarMap.tsx)
RdockedRefuel
Lmap / transitJump the nav sidebar to the Missions tab (handled in StarMap.tsx)
1 · 2 · 3EventModalPick response option
EscEventModalDecline (encounters & opportunities only)
EscmapDeselect station → clear plotted route (cascading, in StarMap.tsx)
? · /anywhereToggle ControlsOverlay
`non-titleDEBUG_CHEAT action dev

The canonical list rendered to the player lives in src/components/ControlsOverlay.tsx. Keep this table and that array in sync.

06 · Screen Transitions

                ┌──────────┐
                │  title   │
                └────┬─────┘
                     │ start / load
                     ▼
                ┌──────────┐                ┌─────────────┐
   undock ◀────┤   map    ├─── jump ─────▶ │   transit   │
                │          │                │             │
                │   ▲      │ complete       │  (StarMap   │
                │   └──────┼────────────────┤   in        │
                │          │                │   transit   │
                │  dock    │                │   mode)     │
                └────┬─────┘                └─────────────┘
                     │
                     ▼
                ┌──────────┐
                │  docked  │
                └────┬─────┘
                     │
              hostile / locked
                     ▼
                ┌──────────┐
                │  denied  │
                └──────────┘

       hull == 0 / catastrophic event from any state ▶  gameover

07 · When to Update This File

You must update this file (and its markdown twin feature-map.md) when you:

You do not need to update this file for: