screens
PURPOSE — The full React route surface of Starship Survivors. Every URL the player or a developer can land on resolves to one of three buckets: gameplay screens (the live mission and its pre-/post-run rails), metagame screens (hub, shop, ships, profile, missions, prologue), and dev screens (admin, playground, viewers, benchmarks). The roll-up exists to disambiguate where a screen lives, what taxonomy it belongs to, and which detail page covers it; behavior is documented per-screen.
OWNS
- The route taxonomy itself — which screens are gameplay vs metagame vs dev — and the rule that gameplay screens are the only ones the player traverses during a run, metagame screens are the only ones the player traverses outside a run, and dev screens are gated by URL knowledge or a build flag.
- The two-folder physical split: gameplay + in-run-adjacent + dev screens live under
starship-survivors/src/starship-survivors/screens/(game-side); hub/shop/profile/missions/prologue + dev viewers + analytics live understarship-survivors/src/metagame/screens/(metagame-side). - Three nested subdirectory groupings:
screens/playground/(Ship Playground tab panels and shared infra),screens/ships/(Ships screen inspector + tabs + popovers), andscreens/weapon-workbench/(Weapon Workbench panes, editors, overlays).
READS FROM
metagame/app/routes.tsx— the canonical route table that maps every URL to a screen import; see app.metagame/app/App.tsx— the bootstrap render-gate that mounts the router; see app.react-router-domRoute/Navigatefor the legacy-path redirects (/games/starship-survivors/ships/:hull→/ships?tab=select,/games/starship-survivors/mods→/ships?tab=select,/collection→/ships?tab=select,/games/starship-survivors/loot-bag→/, catch-all*→/).
PUSHES TO
- Each screen’s per-page docs, which detail its stores, services, signals, and DOM ownership.
DOES NOT
- Document per-screen behavior — see the linked detail pages.
- Define the router or app shell — see app.
- Cover non-route React UI (modals, banners, HUD overlays) — those live in components and on the engine canvas.
Signals fired / Signals watched — none at the roll-up level. Screens interact with engine, services, and stores per their own pages; the router itself emits no signals.
React Router setup
The app uses react-router-dom v6 BrowserRouter mounted by App after bootstrap. The route table is a flat <Routes> block in metagame/app/routes.tsx; there are no nested layout routes, no lazy imports, and no loaders / actions — every screen component is imported eagerly and rendered as a Route element. Legacy paths use <Navigate replace> redirects, and a final * catch-all sends unknown URLs back to /. The pre-router NebulaViewerScreen bypass (checked against window.location.pathname inside App before the router mounts) is the only entry that skips bootstrap entirely.
Three navigation surfaces sit beside the router:
BetaGameScreen— internal route element that lazily assembles a defaultRunDefinitionbefore renderingGameScreen, so/betaworks without going through Hub.PerfTestRedirect(in app) — mounted inside the router and gated byPERF_FLAGS.perftest; navigates to the gameplay route on mount.DevKeys(in app) — globalkeydownlistener that issuesnavigate(...)for Ctrl+Shift navigation chords; resolves the play route by assembling a run-def on the fly.
Gameplay screens
Live mission and the rails immediately around it. The only screens reachable while a run is in flight (GameScreen) or in the post-run reward chain.
| Screen | Route | Page |
|---|---|---|
GameScreen | /games/starship-survivors/play, /beta | GameScreen |
RevealScreen | /games/starship-survivors/reveal | RevealScreen |
ShipPullScreen | /games/starship-survivors/ship-pull | ShipPullScreen |
LootBagScreen | (legacy — /games/starship-survivors/loot-bag now redirects to /) | LootBagScreen |
RunStatsScreen | /games/starship-survivors/stats (direct-URL only post-v5.122) | RunStatsScreen |
LevelSelectScreen | /games/starship-survivors/levels | LevelSelectScreen |
ShipsScreen | /games/starship-survivors/ships?tab=select|artifacts | ShipsScreen |
The canonical post-run flow as of v5.122 is Game Over → /reveal → /ship-pull → Hub. RunStatsScreen is no longer in the live flow but remains reachable by URL.
The ShipsScreen subdirectory hosts the tab implementations: SelectTab, ArtifactsTab, UpgradesTab, Inspector, ShipLivePreview, ShipInfoPopover, ArtifactInfoPopover, useDragDrop, upgrades-sort.
Metagame screens
Hub, shop, profile, missions, prologue, and the analytics + asset viewers. All live under src/metagame/screens/.
| Screen | Route | Page |
|---|---|---|
HubScreen | / | HubScreen |
ShopScreen | /shop | ShopScreen |
ProfileScreen | /profile | ProfileScreen |
MissionBoardScreen | /games/starship-survivors/board | MissionBoardScreen |
PrologueScreen | /prologue | PrologueScreen |
See also the metagame screens roll-up at screens for shell, store, and service wiring shared across these.
Dev screens
Admin tools, scenario launcher, performance probes, asset viewers, and the live-mission workbenches. All gated by URL knowledge or a build-time flag (PerfDashboardScreen short-circuits to a stub outside import.meta.env.DEV; AdminScreen returns an access-required stub for non-admin profiles; BossTestScreen is a vestigial placeholder).
| Screen | Route | Page |
|---|---|---|
DevHomepage | /dev | DevHomepage |
AdminScreen | /admin | AdminScreen |
PerfDashboardScreen | /dev/analytics | PerfDashboardScreen |
PerfBenchmarkScreen | /perf-benchmark | PerfBenchmarkScreen |
NebulaViewerScreen | /nebula-viewer (pre-router bootstrap bypass) | NebulaViewerScreen |
BackgroundsViewerScreen | /backgrounds-viewer | BackgroundsViewerScreen |
ShipPlaygroundScreen | /ship-playground | ShipPlaygroundScreen |
WeaponWorkbenchScreen | /weapon-workbench | WeaponWorkbenchScreen |
BossTestScreen | /games/starship-survivors/boss-test (vestigial) | BossTestScreen |
ShipPlaygroundScreen is the live-mission tuning workbench; its tab panels and shared infra are documented under screens/playground/: ShipsTab, ModsTab, WeaponsTab, EnemiesTab, LevelTab, VfxTab, FxTab, PhysicsTab, BossTab, BossGauntletTab, PlanetsTab, ArtifactsTab, UpgradesTab, ModsTab, TestRunnerTab, plus shared infra PlaygroundShared, PlaygroundUpdateGuard, knob-registry, data-adapters, history.
WeaponWorkbenchScreen is a portal-mounted forge editor; its panes, editors, and overlays are documented under screens/weapon-workbench/: ForgeLibraryPane, ForgePane, ComponentEditor, LayerStackEditor, AnchorEditor, AnchorOverlay, DraggableHandleOverlay, LiveShaderEditor, UniformSchemaEditor, PreviewSampleInputsEditor, NewComponentModal, PaletteWidget, ShapePicker, TimelineScrubber, fixtures.
Pattern notes
- Gameplay vs metagame is a physical split, not just a routing convention.
src/starship-survivors/screens/holds every screen that touches the engine (live missions, post-run reveals, the live-mission workbenches) and every screen the player can only reach by playing the game.src/metagame/screens/holds every screen that doesn’t touch the engine at all (hub, shop, profile, missions, prologue, viewers, dashboard).LevelSelectScreenandShipsScreenlive game-side because they consume engine-side data tables and produce aRunDefinition;MissionBoardScreenlives metagame-side because it picks postings out of the metagame data pool. - All routes are eagerly imported. No
React.lazy, no route-level code splitting — the entire screen tree is in the initial JS bundle. - Three legacy redirects collapse old ship/mod routes into the unified Ships screen.
:hull,/mods, and/collectionallNavigate replaceto/games/starship-survivors/ships?tab=select. - The
/betastandalone entry exists so the PWA can launch directly into a run with a default ship, bypassing Hub. It synthesizes aRunDefinitionfromdart_common+planetIndex: 0inside the route element itself. NebulaViewerScreenis the only pre-bootstrap route.Appcheckswindow.location.pathnamebefore mounting the router and renders the viewer directly, skipping telemetry, asset preload, and player-store init.- The dev surface is intentionally not behind a feature flag — it relies on URL knowledge plus per-screen gates (admin role,
import.meta.env.DEVfor the perf dashboard, build-time tree-shake for the perf-test path). The catch-all redirect to/prevents stumbling onto dev routes by accident.