Usage (CLI)
space-rider Start in normal mode
space-rider --debug Open the debug scenario menu
space-rider --mode <mode> Start a specific debug mode directly
space-rider --help Show help
Controls
| Input | Action |
|---|---|
W / A / S / D or Arrow keys | Steer ship |
F or Shift (browser) | Boost |
Space | Fire pulse cannon |
Q / E | Barrel roll |
P | Pause / resume a run |
M | Mute toggle |
C (browser) | CRT scanline overlay on / off |
V (browser, title screen) | Open a two-pilot split-screen round |
Enter | Launch / relaunch |
Esc | Return to menu / quit |
Ctrl+C | Quit immediately (terminal) |
Arrows + Enter (name entry) | Spell and file a three-character name |
Thumbstick / FIRE / BOOST (touch) | Steer / fire or confirm / boost |
Left stick / A / B / triggers (gamepad) | Steer / fire or confirm / boost / barrel roll |
A gamepad is the browser version's third way in, beside the keyboard and the touch controls, and it feeds the same two inputs both of those do — so nothing about a run knows which one is flying it. It has to report the standard layout before it drives anything: the controls are read by their position in that layout, and a wheel or a flight stick read the same way would steer on whatever axis happened to come first. The left stick takes the dead zone and the eight even sectors the on-screen thumbstick already uses, so one tuning governs a thumb on glass and a thumb on a controller. A is the trigger during a run and the confirm key on the title screen, the debug menu and the game over screen, which is the same reading the on-screen FIRE button takes. Any pad plugged in can fly the run and a second one alongside does no harm, because the slots are read together rather than chosen between. In a split-screen round the whole pad flies pilot 1: the stick steers on that pilot's own keys and A is that pilot's trigger, because one controller is one pair of hands and there is no reading under which half of it belongs to the other seat. That holds for as long as the round is being flown: once both pilots are down, the result panel is a screen waiting on Enter like any other, and A is its confirm key again rather than a trigger with nobody left to fire it. The on-screen FIRE button lands on the same pilot, and comes back on the panel with it, for the same reason. The thumbstick beside it stays out of a round, since a round wants two seats and a touchscreen has no keys for the second one.
M silences the browser version and shows a MUTED indicator: in the footer during a run, and on the bottom border of the menu screens outside one — the title screen, the name entry screen, and the game over screen. Mute is the page's setting rather than a run's — it survives a death, and a split-screen round opened afterwards carries it in — so the screen you press it on says which state you are in. The game over screen matters most of the three, because it is where you arrive straight out of a run and so the likeliest screen to press the key on. The debug scenario menu is the one screen left without the indicator: it is reached only by --debug or ?debug, so it is a developer's screen rather than a session anybody is listening to. The terminal version has no audio, so there the flag only raises the indicator.
The name entry screen reads the same keys as a run, spelling rather than steering: up and down walk the character under the cursor through A-Z, the digits and a space, left and right move between the three slots, and Enter files the score under the name showing. Esc files it as well rather than discarding it - the score was earned before the screen came up, so backing out is a choice about the name - and then leaves for the title screen, where the table is.
The keys that act on the press rather than the hold — P, M, Esc, and the Q and E roll — fire once per press. Holding one down does not repeat it at any of the repeat rates the standard OS sliders offer.
That costs a short deadzone after a hold, because a terminal has no key-up event and silence is the only thing that can stand in for one. P, M and Esc take it flat: having held one, the next press of it is ignored for a beat, so a deliberate second tap needs a moment between them. Nothing is competing for those keys, and a beat is cheap.
The roll is the escape move, so Q and E do not pay that flat rate. Their deadzone is measured off the repeat stream instead, which lasts about twice the gap between repeat characters — a fifth of a second on a normally configured keyboard. Let go after a long hold and the next press rolls, with the roll cooldown left to decide whether it lands. What cannot be recovered is a re-press inside the repeat rate itself: arriving exactly as soon as the next repeat character would have, it is the same stream, and nothing tells them apart.
Silence only counts against a key while the game is listening for it. A terminal that cannot keep up with the repaint blocks the write the game hands it, and the loop with it, so keystrokes queue up and land together when it clears. That pause is the game's, not the player's, and it is discounted rather than read as the key having been let go — so holding the roll on a terminal falling behind still rolls once. A press made inside such a pause is the one thing lost: it cannot be told from the hold carrying on, and the game was frozen for it anyway.
Gaps that pause leaves are not the repeat rate either, so they are not measured as it. On a terminal that blocks on every frame there is no gap left that was timed against a loop actually reading, nothing is measured, and the roll falls back to the same flat deadzone P, M and Esc carry. That is the wide end rather than the narrow one, and on a loop ticking that slowly it is about three frames.
Gameplay
- Dodge obstacles — Red rotating blocks deal 25 shield damage.
- Avoid mines — Blinking red cubes deal 35 shield damage. They take 5 pulse hits to destroy.
- Collect energy orbs — Green glowing orbs restore 10 shield and award 500 points.
- Destroy targets — Shooting obstacles awards 200 points; destroying mines awards 500 points.
- Aim by column — A shot holds the column it was fired down, so line the ship up under the target and pull the trigger. The further out the target, the more its own column drifts outward before the shot arrives, so a long shot wants leading a character or so; the volley's spread covers most of that for you, and it widens with the window as the drift does. The tracer is drawn only while the shot is still inside the tunnel: fire from hard against a wall and it goes dark almost at once, because holding the column carries it out through the wall and nothing spawns out there for it to hit. A dark shot keeps flying and registers nothing while it is dark, so a block you can see with no bolt on it survives. Height is not an aiming axis at all. A shot registers where its tracer is drawn on the target and nowhere else, and a tracer climbs its whole column, so it meets whatever is drawn in that column however high or low in the tunnel the two of you are. What you see is what counts: a bolt drawn through a block destroys it, and one drawn past it does not. The reach is the whole of what the tunnel draws, so anything you can see is something you can shoot; a bolt is retired at that distance and not before it.
- Chain your kills — A second kill within two seconds doubles what it pays, a third triples it, and so on up to
COMBO x8, where the multiplier stops climbing. Further kills still hold the chain open, they just do not raise it. The multiplier shows asCOMBO x3on the HUD and resets after two quiet seconds. Orbs are a pickup rather than a kill and never chain. - Roll out of trouble —
QorErolls the ship for half a second, and nothing can hit it mid-roll. The cooldown runs from the start of the roll, so there is a beat of level flight before the next one. - Take the drops — A mine destroyed by gunfire has about a one in three chance of leaving a powerup, which then drifts toward the ship while the tunnel carries it in. Shield Regen (
+) restores 25 shield. Rapid Fire (!) lets you hold the trigger down for ten seconds rather than tapping it, at three times the cadence a tap sustains. Slow Motion (~) runs the whole world at half speed for five seconds, the ship included, which buys real thinking time without changing the geometry of anything. Ramming a mine destroys it too and drops nothing: that one already cost you 35 shield. - Answer the warning — Every three minutes a
>> WARNING <<banner holds the HUD for three seconds. What follows it is a large mine on the tunnel's axis, closing under its own power and firing back every second and a half. Its shots go to where the ship was when each left, so the answer is to keep moving once one is in the air; a barrel roll turns one aside as it does anything else. Twenty pulse hits bring it down for 5000 points and three pickups, one of each kind. The three hold the spacing they landed in until the explosion over them has cleared, so there is a moment to see that you were paid three before they start drifting in. Let it reach you and it rams for 50 shield and pays nothing, which is the same bargain ramming a mine is. TheBOSS 17/20readout on the HUD is how far through it you are. - Read the warp — Every minute the difficulty steps and the tunnel says so for two seconds, walls and all. Obstacles thicken on that same boundary, so the banner is a few seconds of warning rather than a decoration.
- Survive — The game ends when shield reaches 0.
- Chase your best — Only normal runs count toward the best score. Debug scenarios are diagnostics and never record one.
- Make the table - A run in the top ten is named with three characters before the game over screen, and the table is drawn on the title screen. A score level with one already on the table ranks below it, so the run that set the figure first keeps the row. Debug scenarios never earn one.
- Race the ghost - The grey hollow ship flying with you is your previous run, at the position it held at this point of its own flight. It is the path that was recorded rather than the keys, so it retraces what you flew at any frame rate, and it disappears once you have flown longer than the run it came from. Backing out of a run rather than flying it out leaves the previous ghost in place.
Split Screen
The browser version seats two pilots at one keyboard. V on the title screen opens a round, and index.html?versus goes straight into one. The canvas divides into two halves with a divider between them, and each half is drawn by the same renderer a whole screen is - the same HUD, the same footer, the same tunnel - with the pilot's name over the frame in place of the shared title and that pilot's own keys along the foot of it in place of the shared legend.
| Control | Pilot 1 | Pilot 2 |
|---|---|---|
| Steer | W A S D | I J K L |
| Fire | Space | Enter |
| Boost | F | ; |
| Barrel roll | Q / E | U / O |
Pilot 1's seat is the solo game's own, so a player who has flown alone already knows half of it, and pilot 2's is the same shape moved to the right hand. No key appears in both, which is what lets two hands hold a turn at once. The arrow keys and Shift steer nobody in a round: they are pilot 1's alternates in a solo run, and a control two players cannot agree the owner of is worse than no control.
P pauses the round and M mutes it from either hand, because a paused pilot beside a flying one is a round nobody would accept the result of. C still toggles the CRT overlay, which is the page's rather than the round's. Esc leaves for the title screen the round was opened from. Mute is a setting rather than a property of a run, so a round opens at whatever the page was left muted to, and a rematch opens at whatever the round was left on.
Both pilots launch into the same tunnel. One seed is drawn when the round opens and both halves lay their opening field from it, so the two of them start in the same rocks at the same depths. The fields drift apart from there, because each pilot reaches a given depth at their own speed and a pilot who shoots a mine spends a draw on the drop it may leave. The opening is shared; the flight is each pilot's own, which is what makes the two scores worth comparing.
Everything else is the solo game, twice over: each half keeps its own score, shield, combo, powerups, warp steps, asteroid sections and boss fights, under the rules the whole screen already has. The round ends when neither pilot is still flying, and the higher score takes it - score is what the game measures a run by and most of it is distance, so surviving is what earns it. A dead heat says so. Enter starts a rematch on a fresh seed, which is why the seed is never one a player could learn. A rematch opens a round, so it is held to the same floor the key on the title screen is held to: on a window dragged under it the panel asks for the window back rather than offering a key it would refuse.
A round never reaches the leaderboard. The table has one name to a row and a round has two pilots, so the round's scores are on the round's own panel instead. A pilot can still set the stored best, because a half is a real run flown under the ordinary rules by one player.
The damage shake is the one thing a round does without. The canvas is one object and the offset carries the whole of it, so a crash would shake the tunnel the other pilot is threading - a handicap earned by their rival's mistake. The damage flash each half already draws is what reports a hit there.
A round needs 45 columns a half, so 91 columns of grid, and the title screen offers the key only on a window wide enough to open one. That floor is the width the HUD's three readings want rather than the width the tunnel wants: npm run probe -- versus-half is what measures it. A window dragged narrower mid-round keeps the round, because taking one away from two players in the middle of it is worse than two narrow halves - and a half under the floor shortens its own readings rather than writing them over each other, so the score is still there to read at the 60 column grid floor. The distance loses its unit first, then the whole reading, then the shield's legend, the way each pilot's key list already drops to shorter forms. What the floor gates is opening a round, which is the title screen's key, a ?versus link and the rematch alike.
Debug Modes
Access via --debug (CLI) or ?debug (browser):
| # | Mode | CLI flag / URL param | Description |
|---|---|---|---|
| 1 | Mine Field | mines | Only mines. Pure evasion. |
| 2 | Orb Harvest | orbs | Only orbs. Collect them all. |
| 3 | Collision Course | obstacleCollision | Hit obstacles. Track every impact. |
| 4 | Mine Sweeper | mineCollision | Ram mines. Log collisions. |
| 5 | Chaos Protocol | chaos | Everything at once with permanent boost and auto-fire. |
Navigate the debug menu with arrow keys or number keys, then press Enter to launch.