CoOp:Anything
Search any game and see how much of it you can play with friends: every co-op mod, its stage, quality and community rating.
A western frontier with one life. Take bounties, explore the trail, and return to town.
GamesHTML · JavaScriptGitHub @coltandrewsOnlineOwner 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
Dust & Iron: a top-down western shooter built with Three.js and Rapier.
Taken from the repository README
Loading the full README.
Read the full README ↗A western with one life: two towns, a desert and a pine forest, outlaw camps, a gang boss, hunting, saloons and dice, in one shared online world for up to 20 people. Pick a name and spawn in; next time, continue as that rider. Built with Three.js, Rapier, and plain JavaScript modules.
Play at dustiron.vercel.app.
Fastest (no install): open dist-single/dustiron.html through any local static server, for example:
npx serve dist-single # then open the URL it prints
# or
python3 -m http.server -d dist-single 8080
Three.js and Rapier load from the jsDelivr CDN, so you need an internet connection.
Development (hot reload):
npm install
npm run dev
After editing anything in src/, rebuild the single-file version with npm run single.
The game server is plain Node (22 or newer) with no extra packages. It serves the game and runs the shared world: outlaws, camps, health, duels and money moved between riders.
Try it on your own machine:
npm install # three and rapier, which the server also uses
npm run server # http://localhost:8080
Open http://localhost:8080 in two browser windows (one private window works), type a name in each under Ride online, and you will see each other in Mercy Crossing. The world is saved in data/world.json.
?server=wss://example.com on the page URL points a statically hosted copy (Vercel, dist-single) at a server elsewhere.
Online rules
/y yell, /g world, /w Name whisper, /r reply; click a name to whisper. The rider list and ping are under the money.Deploy to Cloudflare (one shared world, sleeps when nobody plays, about $5–7 a month):
Needs the Workers Paid plan ($5/month), which includes Containers. The Worker serves the game page from Cloudflare's edge, and starts the game server container only when someone rides online; the server shuts itself down after 15 minutes with nobody online. The world is saved in the Worker's Durable Object storage, so it survives sleep and redeploys.
From GitHub (no Docker needed on your machine): in the Cloudflare dashboard, Workers & Pages → Create → Import a repository, pick this repo and branch, then set
npm run build:webnpx wrangler deployFrom your own machine (needs Docker Desktop running):
npx wrangler login
npm run deploy
The game is then at https://dustiron.<your-subdomain>.workers.dev. The first rider after a quiet spell waits a few seconds while the server wakes. instance_type in wrangler.jsonc sets the server size (basic is 1/4 CPU and 1 GiB; standard-1 doubles the CPU if the world lags).
Deploy to Fly.io (sleeps when nobody plays, about $3–5 a month):
fly launch --no-deploy --copy-config # pick an app name; keep fly.toml
fly volumes create dustiron_data --size 1
fly deploy
The machine stops when nobody is connected and starts again on the next visit (a few seconds). The world file lives on the volume, so it survives restarts and deploys.
| Action | Key |
|---|---|
| Move | W A S D |
| Aim | Mouse or trackpad |
| Shoot | Left click (hold for repeat fire) |
| Dodge roll | Space (brief invulnerability) |
| Reload | R |
| Dead Eye | Hold Shift (slow motion, needs meter) |
| Switch weapon | 1 2 3 or Q |
| Camera zoom | Mouse wheel |
| Talk or use a shop | E or Enter |
| Use a bandage | H |
| Smoke a cigarette or cigar | B |
| Chat (online) | Enter or T; /s say, /y yell, /g world, /w Name whisper, /r reply |
| Duel or dice with a rider (online) | G, then Y / X to answer |
| Map | M or Tab (pauses the fight) |
| Pause | Esc |
| Mute | N |
| Frame rate readout | I |
| Tuning panel | ` (backquote) |
Horses belong to their rider: others see them standing or ridden but cannot mount them. A browser tab in the background stops sending its rider's position (browsers pause hidden pages), so that rider stands still for everyone else until the tab comes back.
npm test
npm run build
npm run single
Tests cover life resets, map discovery, transactions, single bounty payments, saved combat state, finite reloads, and camp navigation. Use Chrome to check movement, aiming, menus, and visual changes.
src/
main.js boot and the fixed 60 Hz loop (time scale, interpolation)
game.js life loop, saving, Dead Eye, hit-stop, explosions
life.js seeded world data, inventory, jobs, map discovery, purchases
storage.js versioned browser saves, death records, old-save migration
frontier.js town buildings, walking civilians, roads, and desert
encounters.js camp placement, local path grids, and combat snapshots
town-actions.js talks, shops, and bounty menus
tuning.js every feel number in one place
input.js keyboard and mouse state
camera.js angled follow camera, look-ahead, trauma shake
render.js renderer, lights, shadow box that follows the player
physics.js Rapier world, collision groups, ray casts, interpolation
player.js movement, dodge roll, shooting, health and regen
weapons.js weapon data and the shared gun state machine
enemy.js bandit types, perception and the AI state machine
cover.js cover-point scoring
nav.js 0.5 m grid A* with path smoothing
props.js crates, barrels, explosive barrels, fences, debris
projectiles.js visible enemy bullets
level.js seeded camp layouts and scenery
models.js code-built low-poly models
character.js procedural animation and corpses
fx.js pooled particles, tracers, light flashes
audio.js synthesized sound effects (no audio files)
ui.js HUD, reticle, cards
map.js world map (M): explored land, roads, landmarks, and jobs
wilds.js desert and forest scenery, merged per chunk
town-pine.js Pine Hollow
wildlife.js animal simulation (browser offline, server online)
hunting.js animal models, skinning, online puppets
vices.js drink and tobacco effects
sky.js day, night and rain
net.js browser side of the server connection
net-world.js server-run outlaws, props and events in the browser
net-ui.js joining, chat, duels and dice
remote-players.js other riders
protocol.js message shapes shared with the server
server/
index.js HTTP + WebSocket server, game loop, saving
hub.js accounts, sessions, authority over health and money
sim.js the shared world: camps and outlaws, headless
duels.js dice.js rider-versus-rider games
store.js world.json on disk
ws.js dependency-free WebSocket
tools/bundle.mjs builds dist-single/ without npm