INPUT / Controls & Input
Controls & Input
Keyboard, gamepad, browser, replay, smoke, and runtime flag reference.
Controls & Input
Super Mango accepts keyboard input everywhere, native gamepad input on desktop builds, deterministic replay input for CI, and a browser-safe keyboard path for the WebAssembly cabinet on GitHub Pages.
Player Controls
| Action | Keyboard | Desktop gamepad | Notes |
|---|---|---|---|
| Move left / right | A / D or Left / Right arrows |
D-Pad Left / Right or left stick X | The player accelerates toward the target speed instead of snapping instantly. |
| Run | Left Shift or Right Shift | Right bumper / R1 | Run changes max speed and uses a lower-air-control jump arc once airborne. |
| Jump | Space | A / Cross | Fresh presses are buffered briefly before landing; releasing jump early cuts the jump short. |
| Grab / climb up | W or Up arrow |
D-Pad Up or left stick Up | While overlapping a vine, ladder, or rope. |
| Climb down | S or Down arrow |
D-Pad Down or left stick Down | Only while attached to a climbable surface. |
| Drift while climbing | A / D or Left / Right arrows |
D-Pad Left / Right or left stick X | Uses reduced climb drift speed. |
| Jump off climbable | Space | A / Cross | Leaves the climbable and starts a normal jump. |
The desktop gamepad path uses SDL’s SDL_GameController mapping layer, so Xbox, DualShock, DualSense, and other mapped controllers report a consistent button layout. The analog stick uses an 8000-unit dead zone to avoid idle drift.
Menu and Overlay Controls
| State | Keyboard | Gamepad | Behaviour |
|---|---|---|---|
| Gameplay | Esc | Start | Pause or resume. |
| Pause overlay | Esc | Back | Exit the terminal overlay/run. |
| Game over | Enter or Space | Start | Restart from the current level flow. |
| Level complete | Enter or Space | Start | Load next_phase if configured; otherwise exit the run. |
| Terminal overlays | Esc | Back | Exit without advancing. |
The overlay text is snapshotted in Overlay Snapshots so docs drift checks catch stale control copy.
Browser / WebAssembly Input
The GitHub Pages cabinet uses the WebAssembly build generated by make web. Keyboard controls match the native build. Desktop gamepad polling is intentionally disabled under __EMSCRIPTEN__ because Emscripten/SDL can expose a virtual controller with noisy axes that overrides keyboard input in browsers.
The browser shell calls into the game through the WebAssembly input bridge in src/input/game_web_input.*. That bridge keeps a small key-state table synchronized with browser key events and flushes stale keys when focus changes, so a held key should not remain stuck after tab switches or canvas focus loss.
Runtime Flags for Input and CI
| Flag | Use |
|---|---|
--debug |
Enables FPS, CPU frame time, memory, hitboxes, and event log overlay. |
--sandbox |
Loads levels/00_sandbox_01.toml directly. |
--level <path> |
Starts gameplay from a specific TOML file and skips the start menu. |
--smoke-test-frames N |
Runs exactly N frames and exits for bounded CI smoke checks. |
--seed N |
Seeds rand() for deterministic smoke and replay behaviour. |
--replay-script <name> |
Injects out/replays-smoke/<name>.replay as deterministic SDL key events. |
Replay scripts are generated by tools/run_scripted_smoke.py and consumed by src/input/game_replay.c. They are test fixtures, not a player-facing scripting API.
Related Pages
- Build System — Make targets and CI smoke commands.
- Player Module — movement, physics, animation, hitbox, and climb logic.
- Level Design — TOML schema and per-level physics overrides.