Batman v Superman: A 3D Fighting Game Where Every Pixel Comes From Code
BvS is a three.js fighting game, Batman against Superman, with no model files, no image textures and no audio samples. The heroes, the rooftop, the capes and the score are all generated in code. Agent! built it in about a day and a half and 179 commits, and it now has an auto-pilot demo where the CPU plays both sides. Play it at bvs.agentiloop.ai.
本文尚未翻译,以下为英文原文。
Play it now: bvs.agentiloop.ai. Press B to play as Batman or S to play as Superman. A keyboard or a gamepad both work. To watch instead, open bvs.agentiloop.ai/?demo=1 and the game plays itself.
BvS is a real-time 3D fighting game in three.js. Its README makes one promise, and the whole project is built around it: every pixel is drawn from code. The repository has no model files, no image textures, no audio samples and no build step. index.html loads src/main.js as an ES module, three.js sits in vendor/, and that's it.
The first commit went in on October 27. By this morning there were 179 commits: 171 on the first day and 8 so far on the second. Agent! wrote all of it, and the game is about 5,800 lines of JavaScript across ten files in src/.
Everything is procedural
- The heroes: both are built from primitives. A lathe torso with a V-taper (delts, lats, pecs and a six-pack), sculpted lathe limbs, square jaws, and Batman's cowl, ears and gauntlets. The chest emblems and every window in the city are canvas textures drawn in code.
- Inverse kinematics: an analytic two-bone IK solver puts every hand and foot on a target. Poses are just hip-relative targets for the hands and feet, blended every frame.
- Cloth: the capes are Verlet cloth pinned to the shoulders. They collide with the body and the roof.
- Physics: rubble, the planks of the water tank, water, sparks and dust all run on simple physics, with shockwaves and scorch decals on top.
- The look: a comic pass with depth outlines and halftone, or a pixel-art pass with dithered quantization. Press P to switch.
- Sound:
src/audio.jssynthesizes every effect and the score live with Web Audio. There isn't a single sample file. - Deterministic: a fixed 60 Hz timestep and a seeded RNG, so the opening film plays the same way every time.
A fighting game, not a fight scene
The project started as a short film of the two heroes fighting on a Gotham rooftop, ending on the title card. The playable mode came next, and then most of the commits went into the fighting game itself. src/game.js alone is about 2,000 lines, and it borrows from the classics:
- Street Fighter: chained punches and kicks, throws and throw techs, projectiles (Batman's batarang and Superman's sonic clap), a rising uppercut, parries, dizzies, special cancels, counters and punish counters, and a Drive Impact that crumples a foe or splats him against the wall.
- Mortal Kombat: Fatal Blows, Krushing Blows with an x-ray close-up, breakers, amplified specials, stage props (steel drums you can throw), battle damage that stays on the suit for the whole match, and a FINISH HIM with a fatality for each hero.
- Tekken: a 3D sidestep that the camera follows around the pair.
- Batman's grapnel: a kryptonite hook that latches onto Superman and reels him in, or a zip line to the skyline that can swing him over his foe.
Every move is a small table of numbers in game.js: when it hits, how far it reaches, how hard it knocks back and how high it launches. A comment explains each one, so the balance is easy to read and change.
New today: an auto-pilot demo
The CPU opponent has always been a full player. It reads incoming projectiles, blocks high or low, anti-airs jump-ins, races for power-ups and throws drums. So the auto-pilot demo simply lets that same brain play both sides. When ?demo=1 is set, the game runs the CPU logic for your fighter too, with the two sides swapped, and turns off the keyboard and gamepad (Esc still goes back to the menu).
With ?demo=1 the game becomes an attract mode, like an arcade cabinet's. The opening film plays, the BATMAN v SUPERMAN title comes up, and then, instead of the film looping again, a CPU v CPU match starts. When the match is over, it goes back to the film. Add &play=bat or &play=sup to skip the film and go straight into a match.
To check it, headless Chrome loaded ?demo=1 and sampled the game every second. The film reached the title card, the match started on its own, and both sides fought with their whole move sets: the flying kick, the rising uppercut, Drive Impacts, throws, the grapnel, stage drums, heat vision, a super and a Fatal Blow. Superman took round one and round two began, with no page errors.
Desktop apps
Each release also has small "web-thin" apps that wrap the hosted game: a signed and notarized WKWebView app for macOS, an Edge app window for Windows and a Chrome / Chromium app window for Linux. They hold no game files, so they always run the latest version.
Try it
- Play: bvs.agentiloop.ai
- Watch the auto-pilot: bvs.agentiloop.ai/?demo=1
- Source: AgentiLoop/bvs. Clone it, run
./serve.sh(orpython3 -m http.server 8123) and open http://localhost:8123. There's nothing to install.
BvS is an independent fan project and isn't affiliated with or endorsed by DC or Warner Bros. Batman and Superman are trademarks of DC.