How to make a co-op browser game players join with a link
Net Forge, the open-source multiplayer browser game engine built for AI coding agents, is published on npm under @netforge with source at github.com/netnetdev/net-forge.
Run npm create netforge@latest my-coop -- --template survivor --yes, then npm run play, and open the same link in another tab (or on a phone on your network, after starting with --host 0.0.0.0): everyone who opens it joins your run, up to four players. On the hosted service the Invite link carries the room id (?room=<id>) so friends join that exact room. The co-op rules (revives, shared XP, bosses that scale with the party) are declarations in src/game.ts that you can change.
npm create netforge@latest my-coop -- --template survivor --yes
cd my-coop
npm run play -- --host 0.0.0.0With --host 0.0.0.0, phones and laptops on the same network can open the link through your computer's address. Every template is a co-op or versus game in rooms; the survivor-like is the one built around helping each other.
What you get
| Part | Where | Notes |
|---|---|---|
| Rooms and invite links | template client and room host | Locally every tab joins the open room. On the hosted service a link with ?room=<id> joins that room. One room holds 4 players. |
| Co-op revive | players.downed | Downed for a few seconds, crawl to a teammate, who revives you by standing close. |
| Shared progress | players.share | Half of every XP gem goes to teammates within 20 m, so the party levels together. |
| Boss scaling | players.bossHealthPerPlayer | Bosses grow per extra player (40% in the template). |
| Late joiners | engine rule | A player who joins mid-run is never paid for progress made before their run started. |
| Touch controls | template client | Drag on the left half to move, a DASH button, tap a card. |
1. Start it and invite someone
npm create netforge@latest my-coop -- --template survivor --yes
cd my-coop
npm run play -- --players 2--players 2 opens two tabs in the same room so you can try co-op alone. For a friend on your network, run with --host 0.0.0.0 and send the Invite link with your computer's address in place of 127.0.0.1.
2. Tune how the party plays together
The co-op rules live in the players block of game({...}):
import { game } from "@netforge/engine";
export default game({
template: "survivor",
style: "lowpoly",
places: { field: { chunks: "places/field", spawn: [0, 1, 0] } },
field: { halfSize: 75, pillars: [[14, 14, 2], [-14, 14, 2], [14, -14, 2], [-14, -14, 2]] },
players: {
prefab: "style.lowpoly.hooded_adventurer",
max: 4,
weapon: "ember_nova",
xp: { base: 2, growth: 2, exponent: 2.6 },
magnet: 4,
hitIframes: 0.7,
share: "nearby",
reviveBuff: { seconds: 5, damage: 1.3, speed: 1.15 },
bossHealthPerPlayer: 0.4,
downed: { seconds: 10, crawl: 0.35, selfRevives: 1, respawn: 5 },
},
});downedsets how long a fallen player bleeds, how fast they crawl, how many free get-ups they have and how soon they respawn beside a teammate.selfRevives: 0, respawn: 0makes it hardcore.reviveBuffrewards the player who helps: more damage and speed for a few seconds.share: "nearby"keeps the party together; a player who wanders off levels alone.
3. Give the party a shared goal
Earn rules and systems can count what the whole party does. This rule fires once per run for every player when the party clears seven waves:
import { earn } from "@netforge/engine";
earn.rule("night_watch", { when: "wave.cleared", n: 7, pay: 20, oncePer: "run" });Locally the payout is play money; the rule fires so you can see it in the HUD and in npm test.
4. Check co-op with the bots
npm testThe playtest runs four bots together and checks that waves clear, players level and nobody is down in the first minute. Four bots playing three minutes of the stock template level to 9 and clear 1,350 enemies, at 0.27 ms of server time per tick (Apple M2 Pro, Node 22).
How it works
Each room is one authoritative world. The host steps the simulation at 30 Hz, takes each player's inputs from a queue and sends every player a delta snapshot of what is near them 20 times a second. Your own character is predicted in the browser with the same simulation code and corrected by the next snapshot when they disagree; teammates and enemies are interpolated. Because the server owns every hit and every revive, nobody's tab can decide the outcome for the room. See Netcode and prediction.
To put the room on the internet rather than your network, see Deploy and host your game. The full file list is on the survivor-like template page.
Alternatives
- Colyseus is an open-source authoritative game server for Node.js, built around rooms with matchmaking, lobbies and binary delta state sync, with client SDKs for the web, Unity, Godot, Defold and more. Pick it when you have a client already and want a mature room server. See Net Forge and Colyseus, and for a 2D co-op game on Phaser with a Colyseus server, Net Forge vs Phaser + Colyseus.
- Godot exports to the web as WebAssembly with WebGL 2, and has its own high-level multiplayer API. Pick it when you want an editor-first workflow and a native build too.
Pick Net Forge when you want the whole co-op game, rooms included, from one command.
FAQ
How do players join the same game?
They open the same link. In local play the host puts every player in the open room until it is full (4 for the survivor-like). On the hosted service the Invite link carries the room id (?room=<id>) and puts friends in that exact room.
Can people on phones join?
Yes. The templates have touch controls, and npm run play -- --host 0.0.0.0 lets devices on your network reach your computer.
What happens if someone joins halfway through a run?
They drop into the current run and play at once. The engine never pays a late joiner for progress made before their run started, so joining late cannot be used to collect rewards.
Do I need a server?
For local play, no: npm run play runs the room host on your computer. To host a game for people elsewhere, see Deploy and host your game.
What if only one person is playing?
The game plays solo; the director scales the swarm by the number of players. The arena shooter, card battler, platformer and kart racer also add seat bots that fill empty places and never earn.