Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
A browser space shooter where every enemy attack lands on the beat.
Translation pending
GamesJavaScript · HTMLGitHub @edwardfalkOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Browser space shooter where every enemy is an instrument — the soundtrack is the fight
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
A space shooter where every enemy is an instrument.
Enemies attack on the beat, and each type plays a different part of the drum kit. The longer you survive, the more of them join, and the fight turns into the soundtrack.
Play it in the browser. It needs a computer with a keyboard and mouse. Turn the sound on.
Every sound an enemy makes is timed to one shared clock, so together they play a beat:Read the full README ↗A space shooter where every enemy is an instrument.
Enemies attack on the beat, and each type plays a different part of the band. The longer you survive, the more of them join, and the fight turns into the soundtrack.
Play it in the browser. It needs a computer with a keyboard and mouse, or an Xbox controller after one click or key press to start. Turn the sound on.
| Key | Action |
|---|---|
| WASD | move |
| Mouse / arrow keys | aim |
| Click / Space / Shift | shoot |
| E | dash |
| P / M | pause / mute |
| R | restart after game over |
| Xbox controller | Action |
|---|---|
| Left stick / D-pad | move |
| Right stick | aim (until the mouse moves) |
| RT | shoot |
| A / click left stick | dash |
| Start / View | pause, restart after game over / mute |
Every sound an enemy makes is timed to one shared clock, so together they play a beat:
| Who | When | Plays like |
|---|---|---|
| Player | held fire snaps to eighth notes; the first shot of a burst is instant | hi-hat |
| Grunt | fires on beats 2 and 4 | snare |
| Tank | fires on beat 1 of an even bar | kick |
| Stabber | lunges on the "and" of 3 | string stab (off-beat accent) |
| Rusher | explodes on beats 1 and 3 | crash |
A steady kick drum keeps time over a hum, one root note and its fifth, which dips on every beat and grows with the fight. Without them, the enemies' hits are just sounds. With them, you can hear each hit landing on the beat.
The clock (BeatClock) runs on the Web Audio clock (AudioContext.currentTime), not on frame time. The kick (BeatTrack) is scheduled slightly ahead on the same grid, so frame hiccups don't push it off the beat.
New enemy types join as you level up: grunts from the start, then stabbers at level 2, rushers at level 3, the bassist at level 4 and tanks at level 5. Each one is previewed once: halfway through a level, a single enemy of the next type still to come appears (the bassist's at level 3, the tank's at level 4).
Open the game with ?tune in the URL for a panel of live sliders: the kick, the hum, the sky, the mix, the tones' detune, the hero's shot (which sound, its level, how much a burst softens), the hits (their level and how they climb), the band (the grunts' shot and chatter, and each instrument's level), pacing, every character's numbers and look, the deaths, and how often everyone talks. There's also a Level +1 button (a run that used it can't set a high score) and a box that keeps the sound playing through a pause. The panel shows the current values as JSON, ready to paste into js/config.js, where every setting lives.
The voice playground is for the speakers' voices. Type any phrase, pick a speaker, and change its engine (SAM or espeak-ng), its voice and its effect chain. Your changes are saved in your browser. To hear them in play, open the game with ?tune and tick "Playground voices"; "Copy config" gives you the settings to keep in js/config.js.
For how the code fits together, see ARCHITECTURE.md. The game design is in docs/DESIGN.md, and the tests are described in docs/TESTING.md. What's still to do is in docs/ROADMAP.md.
pnpm install
pnpm run dev # http://localhost:5500
pnpm run test # unit tests, then browser tests
pnpm run lint
Vibe started in May 2025 as an experiment in building a game with AI coding agents, and it still is one. The code is written by AI agents, mostly Claude Code, under my direction. I decide what the game should be and play-test every change by ear. Before anything merges it needs a written plan, independent AI reviews and passing tests.
The game's own code is MIT.
It ships two speech engines under their own terms: