Dev Keyboard Shortcuts
Global keyboard shortcuts for dev and automation navigation, defined in src/metagame/app/DevKeys.tsx. All shortcuts use the Ctrl+Shift+<key> chord to avoid collision with in-game input. Every match calls preventDefault() on the keydown event.
DevKeys is a side-effect-only React component — it renders null. It must be mounted inside the BrowserRouter because it depends on useNavigate and useLocation from react-router-dom. A single window keydown listener is registered on mount and removed on unmount.
Shortcut catalog
17 active shortcuts across three groups.
Navigation (10)
Always-on. Fired regardless of which route is currently active.
| Chord | Action |
|---|---|
Ctrl+Shift+H | Navigate to hub (/) |
Ctrl+Shift+L | Quick-launch: assemble a RunDef from the current selectedShipId in sessionStore, set it, then navigate to /games/starship-survivors/play |
Ctrl+Shift+S | Navigate to shop (/shop) |
Ctrl+Shift+C | Navigate to collection (/collection) |
Ctrl+Shift+P | Navigate to profile (/profile) |
Ctrl+Shift+A | Navigate to admin (/admin) |
Ctrl+Shift+V | Navigate to level select (/games/starship-survivors/levels) |
Ctrl+Shift+T | Navigate to weapon test playground (/ship-playground) |
Ctrl+Shift+R | Navigate to reward reveal (/games/starship-survivors/reveal) |
Ctrl+Shift+D | Toggle the debug overlay flag in engine/core/state |
Shop pulls (4)
Only active when location.pathname === '/shop'. Each tries a data-testid selector first and falls back to scanning all <button> elements for matching text content.
| Chord | Action |
|---|---|
Ctrl+Shift+1 | Solar Legion x1 pull (selector [data-testid="pull-1-solar"], text fallback x1, index 0) |
Ctrl+Shift+2 | Solar Legion x10 pull (selector [data-testid="pull-10-solar"], text fallback x10, index 0) |
Ctrl+Shift+3 | Freebooters x1 pull (selector [data-testid="pull-1-free"], text fallback x1, index 1) |
Ctrl+Shift+4 | Freebooters x10 pull (selector [data-testid="pull-10-free"], text fallback x10, index 1) |
Collection tabs (2)
Only active when location.pathname starts with /collection.
| Chord | Action |
|---|---|
Ctrl+Shift+5 | Navigate to /collection?tab=ships |
Ctrl+Shift+6 | Navigate to /collection (default tab) |
Implementation notes
e.key.toUpperCase()is matched, so both unshifted digits (1-6) and their shifted symbol counterparts (!,@,#,$,%,^) hit the samecasebranches.- The handler short-circuits at the top if either
ctrlKeyorshiftKeyis not held. Everything else falls throughswitch (key)without adefault, so non-bound chords pass through untouched. Ctrl+Shift+Eis intentionally removed — the dedicated settings screen was deleted and settings now live in the in-game cog menu. A comment in the source records the deprecation.Ctrl+Shift+7is documented in the file header for an achievements tab, but nocase '7'exists in the switch — it is a header-only entry.- The
_clickButtonhelper takes(selector, textMatch, nthMatch). CSS selector is tried first viaquerySelectorAll; if there are not enough matches, it scans every<button>on the page and clicks thenthMatch-th element whosetextContent(lower-cased) containstextMatch(lower-cased). - The
useEffectdependency array is[navigate, location.pathname], so the listener re-binds on every route change. Context-sensitive shortcuts always see a freshpath.
Intended use
These chords let Claude or any developer drive the full game UI from the browser console or automation tooling without clicking through menus. The data-testid selectors are the stable contract; the text-content fallbacks exist so the helper still works on buttons that have not yet been tagged.