An original Splatoon-style 4v4 turf-war shooter that runs in your browser.
Paint the ground, swim through your ink, out-turf the other team.
▶ Play now · Controls · Online · Run locally · How it works · Contributing
- Game modes, 4 v 4. Turf War (most ground painted wins) and Zone Control (hold the live zone to count down from 100 — rotating side zones, penalties, overtime). Play against bots on three difficulty levels.
- Online with friends. Create a private room, share the five-character code, and up to eight players line up in the lobby with their loadouts and looks. Empty slots fill with bots; if someone drops, a bot takes over their squidkid mid-match.
- Squid form. Hold to dive into your ink: swim fast, refill your tank, climb inked walls, dolphin-jump water gaps.
- Twelve weapons, each with its own feel: Spritzer, Twinfire Pistols, Canopy Brolly (shotgun + launchable shield), Popper Blaster, Squall Spinner, Glint Charger, Tideline Bow (tri-arrow, two charge rings), Swell Roller, Swish Brush, Brine Cutlass (charged one-hit blade), Sponge Mitts (ink fists, charged leap, wall cling) and Bilge Bucket. Mix any main with any of 15 subs and 19 specials.
- Seven stages, day or dusk. Tidewater Plaza, Kelpline Terminal, Halyard Marina, Saltpan Basin, Crossroads Market, Lockgate Canals and Terrace Heights, each a real place with its own layout. Some stages change a few pieces for Zone Control.
- Ink that behaves like liquid. Splats spread and settle, fresh ink is glossy and dries, drips run down walls, and swimming leaves a wake in the surface itself.
- A map you can actually read. Hold Tab and the camera cranes up into a tilt-shift diorama of the live stage, with pins for your team and one-click Super Jumps.
- Locker. Choose your squidkid: tentacle style, headgear, face, outfit.
- Everything procedural. Characters, animation, weapons, textures, props, sound effects and music are all generated in code. There are no downloaded assets except two fonts.
| Action | Keyboard / mouse | Gamepad |
|---|---|---|
| Move | W A S D | Left stick |
| Aim | Mouse | Right stick |
| Fire | Left click | RT |
| Squid form | Shift | LT |
| Jump / dodge roll | Space | A |
| Sub weapon (bomb) | Right click / E | RB |
| Special | F | Y |
| Map + Super Jump | Hold Tab or M, then 1–4 or click a pin | View |
| Pause | Esc | Start |
Gamepads work on the hosted (https) version. On a plain http:// LAN address browsers block the Gamepad API.
From the main menu choose Online, then Create a room and send your friends the code (or Join a room and type theirs). The host picks the stage, time of day, match length and whether bots fill empty slots; everyone else picks a team, weapon and look and readies up. The lineup, emotes and ready state are live for everyone in the room.
Rooms run on a tiny relay (a Cloudflare Worker with one Durable Object per room, in server/). It only
forwards messages: every player simulates their own squidkid and streams it, and everyone else draws it through the
same animation system on a smoothed timeline about a tenth of a second behind. How that works, and the tools used to
measure it, are in docs/NET.md.
To play online on your own network, run the relay next to the game:
npm install # once: the relay runs on wrangler
npm run relay # ws://<this machine>:8787A page opened from localhost or a LAN address uses that relay automatically; ?relay=wss://… points it anywhere else.
There is no build step. Any static file server works; the included one also serves to your LAN and sends no-cache headers so module updates are never stale.
git clone https://github.com/jaydendavisnc/inkwave.git
cd inkwave
npm install # Electron + the headless tools
npm start # the desktop app (Electron)
npm run serve # or the web version: http://localhost:8490
npm run package # build the macOS app into dist/ (arm64 + x64)Optional: drop your own music into songs/ (see songs/README.md); otherwise the procedural soundtrack plays.
Useful URL parameters: ?map=halyard&time=dusk picks a stage, &autostart=180 skips the menus into a 180 s match, &autopilot lets a bot drive you.
npm install # once, for the headless tools
npm run check # syntax-check every module
npm run smoke # boot + 8 s of autopilot in headless Chrome, fails on console errors
npm run build # assemble dist/ (game + only the three.js addons it imports)
npm run check-maps # sanity-check every stage layout (and its Zone Control variant)Bot matches run headless and muted for tuning: MAP=halyard MODE=turf SECS=180 npm run botlab (see tools/botlab/README.md).
With the relay running, npm run net-test plays a real match between headless clients and reports what each
screen drew (see docs/NET.md).
- Ink is painted in texture space. Every paintable face owns a region of one 4K atlas; splats are drawn into it on the GPU while a coarse CPU grid keeps the turf score and gameplay queries in sync. The level shader layers the ink over the surface with its own height, gloss and wetness. See
src/world/paint.jsandsrc/world/inkShading.js. - Stages are data. A layout is a list of boxes and ramps for one half of the arena; the other half is the 180° rotation, so both teams always get an identical field. Ambient occlusion is baked offline (
tools/bake-ao.mjs). Seesrc/world/maps.js. - Characters are fully procedural. Geometry, materials, a 60-bone rig and every animation (locomotion, squid form, weapon poses, secondary motion) are code, driven by a spring-based pose system. See
docs/RIG.md. - Systems talk through events. Weapons, actors and the match emit typed events; effects, HUD and audio subscribe. The contract is documented in
docs/EVENTS.mdanddocs/CONTRACTS.md. - Deterministic tooling. The game exposes a freeze/step debug interface so filmstrips, handling measurements and bot simulations are reproducible frame by frame (
tools/film.py,tools/measure-handling.mjs).
Rendering is three.js r186 (vendored, plain ES modules with an import map) with GTAO, bloom and a custom grade pass.
Chrome and Edge are the target; Firefox works. Safari runs but is slower. A discrete or recent integrated GPU is recommended for the High preset; the settings menu has Medium and Low tiers.
Issues and pull requests are welcome. Read CONTRIBUTING.md for the project layout and the checks to run first.
MIT © 2026 Jayden Davis. INKWAVE is an independent project and is not affiliated with Nintendo; Splatoon is a trademark of Nintendo.


