Beyond the Last Orbit
Neon arcade roguelite with a procedurally synthesised heavy-metal soundtrack — enemies sway on the beat, and shots fired on the beat build the multiplier.
Neon arcade roguelite shooter with a procedurally synthesized heavy-metal soundtrack. Enemy formations fly in, sway on every beat and morph into new shapes every few bars. In beat stages, shots fired on the beat build a score multiplier (up to x8); shots off the beat make the music go sour. The beat track along the bottom shows markers converging on the beat and grades every shot PERFECT / GOOD / OFF.
The playfield fills the whole window: height is fixed, width follows the screen (portrait phone to ultra-wide).
Three worlds (Near Earth Orbit, Moon, Mars) × 5 stages, a boss on every fifth stage, then an endless harder loop.
The run: hits and grazes (enemy bullets skimming the ship's core, shown as a dot) build the multiplier, misses drop it. After each stage pick the next node on a branching map (BATTLE, ELITE, CACHE, REPAIR, SHOP, SIGNAL); elites and bosses grant a pick-1-of-3 upgrade draft. Clearing a stage cancels every enemy bullet still on screen into points. Kills drop scrap, spent at SHOP nodes on upgrades, repairs and rerolls; SIGNAL nodes are random events with two choices (escort a freighter, board a derelict, deal with a smuggler, tune into a ghost beat). Upgrades come in common, rare and epic tiers plus curses (an upside with a price); cards name the upgrade they combine with (MAGNET feeds GRAZE CHARGE, SPREAD SHOT unlocks RICOCHET, HEAVY ROUNDS arm SHRAPNEL). Elites fire telegraphed per-world volleys (walls, rings, fans).
- Beat stages: stage 3 of every world is a beat stage — only on-beat shots build the multiplier (up to x8), off-beat shots cost two levels, PERFECT shots fire power shots, and a beat rank S/A earns an upgrade draft (S also doubles the stage bonus).
- Beat Lock (Settings): every stage is a beat stage. For players who want the pure rhythm game; best with sound.
DAILY RUN: one attempt per day on a seed shared by everyone (same map, drafts and enemy rolls), played with the base ship, with its own global table.
Credits earned per run buy cosmetic ship skins and laser styles (SHOP) and permanent upgrades (HANGAR). Credits, upgrades and settings stay in the browser; high scores are also shared on a global leaderboard.
Run
npm install
npm run dev # http://localhost:5173
npm run dev:leaderboard # http://localhost:5174 with a mock global leaderboard
npm run dev:https # https://<lan-ip>:5178, self-signed: needed for tilt steering on a phone (accept the certificate warning once)
npm test # unit tests (Vitest)
npm run build # typecheck + production build in dist/Deploy
.github/workflows/deploy.yml typechecks, tests and builds every push and pull request, and deploys main to GitHub Pages (the build's base path follows the Pages URL, e.g. /<repo>/).
One-time setup after pushing to GitHub: Settings → Pages → Build and deployment → Source: GitHub Actions.
Global leaderboard (Supabase)
Without configuration the game only keeps local high scores. To share them:
- Create a free project at supabase.com.
- SQL Editor → New query: paste and run
supabase/leaderboard.sql(re-run it after upgrading to M16: it widens themodecheck for daily boards). - Project Settings → API Keys: copy the project URL and the publishable key (
sb_publishable_…, safe to ship in the page; never use the secret key). - GitHub repo Settings → Secrets and variables → Actions → Variables: add
VITE_SUPABASE_URLandVITE_SUPABASE_KEY, then re-run the deploy.
For local builds, put the same two values in .env.local. Remove bad rows in the Supabase Table Editor.
Controls
| Action | Keyboard | Touch |
|---|---|---|
| Move | Arrows / WASD (up/down limited to the bottom zone) | Drag anywhere, or tilt the phone (Settings → Tilt steering) |
| Fire | Space | Tap anywhere |
| Pause (resume / end run) | P / Esc | Pause button (top left), or switch away from the tab |
| Menus | Arrows + Space/Enter, Esc back | Tap |
Calibrate your audio/input latency under Settings → Calibrate timing (important with Bluetooth headphones). If the beat markers look early or late against the music, adjust Settings → Visual offset (moves visuals only).
Layout
src/sim— deterministic game simulation (fixed 60 Hz, seeded RNG, no DOM/Pixi)src/audio— Web Audio synth, sequencer, beat clock, rhythm judgesrc/data— tuning (balance.ts), worlds, songs, sprites, cosmeticssrc/view,src/fx— PixiJS rendering, particles, post-FXsrc/scenes— title, run, game over, shop, settings, calibrationsrc/leaderboard,supabase/— global high score client and tabledocs/superpowers— design spec and per-milestone implementation plansdocs/research— background research (roguelite structure, bullet-hell/rhythm hybrids, rhythm timing)
Credits
- Drums: DrumGizmo MuldjordKit by Lars Muldjord, CC BY 4.0 — mixed down to stereo hits.
- Guitar DI notes: FreePats Electric Guitar FSBS (direct), CC0 — played through the game's own amp model.
- Guitar cabinet impulse responses: Jester's Brutal Pack by Jester Dyne Productions, CC0.
Details in public/audio/CREDITS.md.
From the repository's README, rendered at build time.