New
Apps 1,895Makers 1,890This week 1,690
Promote your app−30%
2views in
the last 30 days

Vibe

Browser space shooter where every enemy is an instrument — the soundtrack is the fight

Built with Claude Code

by edwardfalk · Unclaimed · from SESweden · added Oct 29, 2026
no ratings0 comments

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.

Vibe gameplay

Controls

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

How the music works

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
  • You are the Dude, in a bathrobe with a White Russian, looking for his carpet. He walks on your hi-hat's eighth notes, and the more they hurt him, the less he abides.
  • Grunts keep their distance, stepping back when you get close and advancing when you run.
  • Stabbers wind up on beat 2, lock on beat 3 and lunge on the "and" of 3: a ring counts the eighths and a lane shows where they'll go. Shoot one before the lock and its stab is off; after it, dodge.
  • Rushers are stuntmen on rockets who steer only on the beat: dash aside and they shoot past. Shot or too close, they light, count down on the beat and blow up with a crash on beat 1 or 3, hurting anything near and lighting any rusher in reach. Your shots knock them along, so bat one into a crowd.
  • Tanks are big, slow bouncers who turn only on beat 1. Their armour is on the side facing you and their back is bare: get behind one to plant your time bomb, which counts down on the beat and kills him. Stand in front of one and he shoves you; brush his side and he elbows you away.
  • Everyone talks. Enemies shout lines like "KILL HUMAN!" and "SLICE AND DICE!", each in its own synthesized voice, on the beat, and the mix dips the game under them so they're heard.

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).

Tuning

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.

Tech

  • p5.js in instance mode for drawing, a WebGL shader for the sky, Web Audio for sound, and two speech engines, SAM and espeak-ng, rendering the voices in a Web Worker.
  • Plain ES modules with no build step, served as static files on GitHub Pages.
  • Unit tests with Vitest, and browser tests with Playwright, including checks that the kick and enemy shots land on the beat. GitHub Actions runs lint, the unit tests and the browser tests on every pull request and every push to main.

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.

Run it locally

pnpm install
pnpm run dev        # http://localhost:5500
pnpm run test       # unit tests, then browser tests
pnpm run lint

How this was built

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.

Licence

The game's own code is MIT.

It ships two speech engines under their own terms:

  • espeak-ng is GPL-3. SOURCE.md there identifies its source.
  • SAM carries no licence grant; it ships at the author's accepted risk.

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#games · #shooter · #music