# How to make a co-op tower defense game in the browser

> Start the COGSPIRE tower defense template with one command: up to four players build and upgrade towers on one shared board against twenty waves. Change the road, towers, creeps and waves in src/game.ts; targeting, gold, co-op and netcode come with it.

Net Forge, the open-source multiplayer browser game engine built for AI coding agents, is published on npm under `@netforge` with source at https://github.com/netnetdev/net-forge.

Source: https://forge.netnet.capital/docs/guides/tower-defense-browser-game  
Last updated: 2026-10-23. Checked against @netforge/engine 0.2.0.

Run `npm create netforge@latest my-td -- --template tower-defense --yes` and you have a co-op tower defense: creeps walk a road in waves, up to four players build towers beside it with their own gold, every kill pays its builder a bounty and the rest of the team a share, and the team shares the lives. The road, the towers, the creeps and the waves are declarations in `src/game.ts`.

```sh
npm create netforge@latest my-td -- --template tower-defense --yes
cd my-td
npm run play
```

`--template tower` and `--template td` are accepted as the same template.

## What you get

| Part | Where | Notes |
|---|---|---|
| Board and road | `towerBoard({...})` | Tile waypoints from edge to edge; blocked tiles nobody builds on. A tile is 2 m. |
| Towers | `tower({...})` | 1 to 8 towers of kind `bolt`, `splash`, `frost` or `chain`, each with upgrade levels. Towers aim at the creep furthest along the road. |
| Creeps and bosses | `prefab({...})` | Health, speed, gold bounty and the lives a leak costs; `boss: true` adds a health bar. |
| Waves | `waves({...})` | Groups by wave number, with growth, gaps and delays. More builders make creeps tougher (+30% health per extra player). |
| Co-op economy | template | Bounties to the builder, shares to the team, a ready vote that skips the breather for a little gold. |
| Server cost | measured | Four bots for four minutes reach wave 8 at 0.026 ms per tick on average, p99 0.098 ms (Apple M2 Pro, Node 22). |

## 1. Start it

```sh
npm create netforge@latest my-td -- --template tower-defense --yes
cd my-td
npm run play -- --players 2
```

Click a tile to build the tower picked in the bar (keys 1 to 4), click a tower to upgrade or sell it, and press Space to call the next wave. On touch, tap a tile to aim and tap again to build.

## 2. Draw a new road

```ts title=src/game.ts
import { towerBoard } from "@netforge/engine";

towerBoard({ size: [20, 12], path: [[0, 5], [6, 5], [6, 1], [13, 1], [13, 10], [19, 10]], lives: 20, gold: 100 });
```

Each step of the path changes x or y, never both, and the road starts and ends on the board's edge. Longer roads with more turns give towers more time; a straight road is hard.

## 3. Add a tower and a creep

```ts title=src/game.ts
import { prefab, tower } from "@netforge/engine";

tower("sky_harpoon", { model: "style.lowpoly.rocket", kind: "bolt", cost: 120, damage: 60, rate: 0.4, range: 6 });
tower("bolt_post", {
  model: "style.lowpoly.turret",
  kind: "bolt",
  cost: 40,
  damage: 8,
  rate: 1.5,
  range: 3,
  levels: [{ cost: 45, damage: 14 }, { cost: 80, damage: 24, range: 3.5 }],
});
prefab("ironclad", { model: "style.lowpoly.robot_walker", health: 160, speed: 0.9, value: 14, damage: 3 });
```

Then bring the creep into the waves with a group such as `{ prefab: "ironclad", from: 8, count: 2, grow: 0.5, gap: 2 }`. `splash` towers take a `radius`, `frost` towers a `slow` and `slowSeconds`, `chain` towers a number of `chains`.

## 4. Test it

```sh
npm test
```

The playtest seats four builders and requires that they kill creeps, clear wave 3 and fire an earn rule within four minutes without losing the spire before wave 4. A road that is too short or a wave that is too strong fails here with the check that broke.

## How it works

Tower defense runs as a rules genre: a deterministic module the room server steps at 30 Hz, with integer state and a seeded random word. Your cursor is predicted so pointing never waits; builds, upgrades, sells and the ready vote are actions the server validates against your gold, the tile and who owns the tower. Creeps are networked entities the client interpolates. The same netcode, playtest and store serve every template. See [Make a turn-based multiplayer game](https://forge.netnet.capital/docs/guides/turn-based-browser-game.md) for rules genres in general and the [tower defense template page](https://forge.netnet.capital/docs/templates/tower-defense.md) for every file.

## Alternatives

- **[Phaser](https://docs.phaser.io/)** is a free, open-source 2D framework with WebGL and Canvas rendering and a large set of examples. Pick it for a single-player 2D tower defense with sprite art where you write the pathing and targeting yourself.
- **[Godot](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)** has a scene editor and navigation tools and exports to the web as WebAssembly with WebGL 2. Pick it when you want to design levels in an editor.

Pick Net Forge when you want the co-op version, with a server that owns the gold and the waves, already working.

## FAQ

### Can several people build on the same board?

Yes, up to four. Each builds with their own gold; kills pay the tower's builder a bounty and the rest of the team a share.

### How do I make the game harder?

Raise the waves' health growth, counts and `grow`, or lower starting gold and lives. A shorter prep time and breather make it faster.

### Do towers target the closest creep?

They target the creep furthest along the road within range, which is the usual tower defense rule and keeps leaks rare.

### Can I add a boss wave?

Yes. Declare a prefab with `boss: true` and add a group such as `{ prefab: "boilerback", from: 10, every: 10, count: 1, delay: 8 }` for a boss every tenth wave.

### Can creeps take a path the players draw?

The road is declared in `towerBoard({ path })`. Players build beside it, not on it.
