# Monster collector template (MOSSBOUND)

> MOSSBOUND is a multiplayer monster collector for up to eight players: pick a starter, walk a shared marsh, meet wild creatures in tall grass, battle turn by turn with a team of three, catch the ones you want and bring down a shared boss before dusk. Start it with one command and change it in src/game.ts.

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/templates/monster-collector  
Last updated: 2026-10-23. Checked against @netforge/engine 0.2.0.

MOSSBOUND is a complete multiplayer monster collector: each player picks one of three starters at camp, walks a marsh shared with up to seven others, meets wild creatures in tall grass and battles them turn by turn with a team of three, catching the ones worth keeping. Every player in the marsh wears down the same boss, the warden, which has to fall before dusk.

```sh
npm create netforge@latest my-game -- --template collector --yes
cd my-game
npm run play
```

Walk with WASD, the arrows or the left thumb. Open the link in a second tab and you meet the other keeper in the marsh.

## What you get

| Part | What it does | Where |
|---|---|---|
| The map | Size in tiles, camp, water, blocked tiles, grass zones with encounter rates and creature pools, the warden, dusk, snares | `marsh({...})` |
| Creatures | Up to 24 creatures with an element, base stats that grow 12% a level, 1 to 4 moves and a catch rate | `creature(...)` |
| Moves | Up to 48 moves with element, power and accuracy; effects `drain`, `heal`, `guard` | `move(...)` |
| Elements | A four-way cycle (root, tide, spark, stone); strong hits deal 1.5x, weak ones 0.67x | the engine |
| Battles | Turn order by speed, swaps, snares, flee, XP for the active and benched creatures | the engine |
| Shared boss | One health pool for the whole marsh; everyone who hurt it is credited when it falls | `marsh({ warden })` |
| Netcode | 30 Hz authoritative room; walking is predicted with the room's own tile collision; battles are private to each player | the template package |
| Playtest bots | Four keepers for four minutes: battles won, catches, levels, team wipes, earn | `npm test` |

Measured on an Apple M2 Pro, Node 22: four bots over four minutes (7,200 ticks at 30 Hz) caught 14 creatures, raised a creature to level 6 and fired the catch rules, at 0.002 ms per server tick on average.

## 1. Add a creature and a move

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

move("thorn_curl", { element: "root", power: 0, effect: "guard" });
move("tide_crash", { element: "tide", power: 70, accuracy: 0.8 });

creature("thistlehog", {
  model: "style.lowpoly.fox",
  element: "root",
  hp: 50,
  atk: 52,
  def: 48,
  spd: 46,
  moves: ["leaf_lash", "thorn_curl"],
  catchRate: 0.7,
});
```

`power: 40` is a plain hit. `drain` heals half the damage dealt, `heal` (with `power: 0`) restores `amount` of max health, and `guard` halves the next hit taken. Then put the creature in a grass pool and add its label to `src/names.json`.

## 2. Lay out the marsh

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

marsh({
  size: [30, 20],
  camp: [2, 10],
  starters: ["mossling", "cindertail", "puddlewump"],
  starterLevel: 4,
  water: [[11, 0, 2, 6]],
  blocked: [[19, 0, 1, 8]],
  grass: [
    { at: [4, 2, 6, 5], rate: 0.22, pool: [{ creature: "thistlehog", weight: 3, level: [2, 3] }] },
    { at: [21, 4, 4, 12], rate: 0.18, pool: [{ creature: "bogling", weight: 2, level: [6, 8] }] },
  ],
  warden: { creature: "fenwarden", at: [27, 10], level: 9, hp: 700 },
  dusk: 600,
  snares: 6,
});
```

Rectangles are `[x, y, width, height]` in tiles of 2 m. Put weak creatures near camp and stronger ones toward the warden, and leave a walkable way from camp to every grass zone. The build checks that the camp and warden stand on open tiles and that every pool names a declared creature.

## 3. Add an earn rule

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

earn.rule("ten_wins", { when: "creature.defeated", n: 10, pay: 15, oncePer: "run" });
```

Events are `creature.caught`, `creature.defeated`, `creature.levelup`, `level.five` and `level.ten` (each credits the player), `warden.defeated` (everyone who hurt it) and `run.won` (everyone in the marsh).

## 4. Check it with bots

```sh
npm test
```

## How it works

The collector is a board genre: its rules are a deterministic module in `@netforge/engine/rules`. Every roll (encounters, accuracy, damage spread, snares and the wild creature's move) comes from the room's seeded random number, so a run replays exactly from its inputs. Walking is predicted with the same tile collision the room runs, so it never waits for the server. Battles are private: your team, your opponent and the battle log reach only you, while other players see the creature walking beside you. See [Simulation and ECS](https://forge.netnet.capital/docs/concepts/simulation-ecs.md).

The full guide is [Build a monster collecting game with battles and a party](https://forge.netnet.capital/docs/guides/monster-collector-game.md).

## Alternatives

- **[Godot](https://docs.godotengine.org/en/stable/)** has a tilemap editor, a scripting language and a web export. Pick it for a single-player collector with a hand-built overworld and story.
- **[Phaser](https://docs.phaser.io/)** is a 2D HTML5 framework with tilemaps. Pick it for a top-down 2D collector with pixel art.
- **Net Forge** fits when you want a shared world where players catch and battle side by side, with every roll made on the server and a shared boss fight.

## FAQ

### How do wild encounters work?

Each step into a new tile of tall grass rolls the zone's `rate`. A hit starts a battle with a creature from that zone's `pool`, at a level in its range.

### How is the catch chance calculated?

A snare succeeds with chance `catchRate x (0.25 + 0.75 x the opponent's missing health)`, so weakening a creature first makes it easier to catch.

### Can players battle each other?

Not in this template. Players share the marsh and the warden fight; battles are against wild creatures and the warden.

### How big can a team be?

Three creatures travel with you; more catches go into your lantern. The `amount` upgrade adds extra snares.

### What happens if my whole team faints?

You are sent back to camp with half health. Standing at camp heals your team.
