A from-scratch, zero-dependency browser run-and-gun in the classic mold: one-hit deaths, weapon pods, exploding bridges, minibosses, three stages — with free mouse aim, gamepad and touch support, rebindable controls, difficulty levels, New Game+ loops, a leaderboard, and drop-in network co-op. All graphics are procedural pixel art and all audio is synthesized with Web Audio. No assets, no build step, no libraries — the server is ~300 lines of stdlib Python.
Year 2131. A seed-ship fell out of a clear sky and buried itself in Korai Island. For nine days, nothing came out. Then the garrison stopped answering, and the satellites saw the soldiers walking in perfect, silent rows.
The swarm wears people. Reach the nest. Kill what grows there.
The VIVID graphics mode (outlines, glows, contact shadows, screen-shake juice) is on by default; a one-key toggle in Options restores the flat retro look.
![]() |
![]() |
| 1 · Jungle garrison | 2 · The Nest |
![]() |
![]() |
| 3 · The Seed-Ship | The Core Mind |
![]() |
![]() |
| Hit-stop & shockwaves | Drop-in co-op |
python server.py
then open http://localhost:8137/ — the console also prints the LAN address for player two.
(Opening index.html directly works too, but only for solo play.)
The first browser to open the URL is Player 1 and hosts the game. The second becomes Player 2 (blue bandana) and can drop in mid-mission. Anyone after that spectates. No accounts, no lobbies: sharing the URL is the whole netcode. The title screen's bottom-left LINK indicator shows each window's role.
python play_online.py
starts the server plus a free Cloudflare quick tunnel and prints two links:
yours (localhost — open it FIRST so you host) and a public
https://….trycloudflare.com link for your friend. No signup, no router
changes, nothing for your friend to install. Notes: the public URL changes
every run, anyone holding it can join (or spectate), and the remote player
feels roughly their ping as input delay — fine on decent connections.
Internet play needs
cloudflared.exenext toplay_online.py(it's not committed to this repo). Grab the single binary from the cloudflared releases;play_online.pyprints the same link if it's missing. Plainserver.py(LAN / same-network co-op) needs nothing extra.
| Input | Action |
|---|---|
| A / D | Run |
| W (or Space) | Jump — somersault included |
| S | Prone / (+W) drop through platforms |
| Mouse | Aim — full 360° |
| Left click | Fire |
| O | Options: rebind keys, fire mode |
| Enter | Start / pause / advance story |
| M | Mute |
Fire mode (in options): TAP = one shot per click, classic. HOLD = every weapon autofires while the button is held.
One hit kills you. You start with 3 lives... unless you know a certain code — it works on the title screen in both its arrow-key and WASD spellings.
Shoot the flying pods (weapons persist across stages; dying resets you to the rifle): R rifle · M machine gun · S five-way spread · L piercing laser · F flamethrower · H homing missiles · B 8-second barrier · 1 extra life.
1 — Jungle: the possessed garrison. Runners, snipers, turrets, shielded husks (shoot them low, steep, or from behind), two collapsing bridges, an armored-truck arena — then the fortress wall: gun ports first, core second.
2 — The Nest: skitterers, acid spitters, diving wasps, egg sacs, burrowers that stalk you underground, the larva queen — and the Heart, guarded by two spitting maws.
3 — The Seed-Ship: everything at once inside the living hull, ending at the Core Mind: shoot down its four shield orbs, then hunt the teleporting eye. When it dives across the floor, go prone.
Beat it and the campaign loops harder (score carries). Difficulty select is on the title screen (arrows / dpad / tap the line). Scores are per player, with a local best and a server-side top list.
window.__contra exposes state and helpers (warp, god, step, key,
setMouse, fire, beginStage, setBind, setFireMode) for automated
testing. server.py is a pure relay; all game logic lives in the clients.






