# @netforge/engine/rules API reference

> Every export of @netforge/engine/rules, generated from its TypeScript source: 88 functions, classes, constants and types with their signatures and doc comments.

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

Deterministic rules modules for the board genres (tower defense, idle, card battler, monster collector) behind the same `SimAdapter` seam as the action templates.

```ts
import { rulesAdapter } from "@netforge/engine/rules";
```

Generated from `packages/engine/src/rules/index.ts` by `apps/forge-docs/scripts/api.mjs`. Signatures are what the TypeScript compiler reports for the current source; long types are cut and say so.

| Kind | Count |
|---|---|
| Functions | 39 |
| Constants | 22 |
| Types | 27 |

## Functions

### avatarEntity

Entity state for an avatar. Avatar entity ids are the player ids.

```ts check=skip
function avatarEntity(player: number, a: Avatar): EntityState;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### bestTowerTile

The best free tile for a tower of `type` (the most road in reach), with a
per-player tie-break and `jitter` (0 for the sharpest choice). Null when
no free tile reaches the road. Used by the playtest bots and the
client's autopilot alike.

```ts check=skip
function bestTowerTile(g: CompiledTowerGame, occupied: ReadonlySet<number>, type: number, salt: number, jitter?: number): { tx: number; ty: number; } | null;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### cardsGenre

```ts check=skip
function cardsGenre(m: GameManifest): RulesGenre<CardsState> & { readonly game: CompiledCards; };
```

Source: [packages/engine/src/rules/cards.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/cards.ts)

### collectorGenre

```ts check=skip
function collectorGenre(m: GameManifest): RulesGenre<CollectorState> & { readonly game: CompiledCollector; };
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### compileBoard

```ts check=skip
function compileBoard(def: { size: readonly [number, number]; path: readonly (readonly [number, number])[]; blocked: readonly (readonly [number, number])[]; }): CompiledBoard;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### compileCards

```ts check=skip
function compileCards(m: GameManifest): CompiledCards;
```

Source: [packages/engine/src/rules/cards.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/cards.ts)

### compileCollector

```ts check=skip
function compileCollector(m: GameManifest): CompiledCollector;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### compileIdleGame

```ts check=skip
function compileIdleGame(m: GameManifest): CompiledIdleGame;
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### compileTowerGame

```ts check=skip
function compileTowerGame(m: GameManifest): CompiledTowerGame;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### effectiveness

Strong (1), weak (-1) or plain (0): each element beats the next in the cycle.

```ts check=skip
function effectiveness(attack: number, defend: number): number;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### entity

```ts check=skip
function entity(id: number, kind: number, owner: number, x: number, z: number, yawTurn: number, type: number, hp: number, flags?: number, value?: number, aux?: number): EntityState;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### genreFor

The genre for a game manifest; throws GameDefinitionError lines through the genre's compile.

```ts check=skip
function genreFor(m: GameManifest): RulesGenre<unknown>;
```

Source: [packages/engine/src/rules/genres.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/genres.ts)

### hpAt

Max health at a level.

```ts check=skip
function hpAt(base: number, level: number): number;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### idleGenre

```ts check=skip
function idleGenre(m: GameManifest): RulesGenre<IdleState> & { readonly game: CompiledIdleGame; policyInput(s: IdleState, player: number, a: Avatar, tick: number, policy: IdlePolicy): RulesInput; };
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### isRulesBot

```ts check=skip
function isRulesBot(p: number): boolean;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### isRulesTemplate

True when a template plays on a board genre (not engine-sim's action world).

```ts check=skip
function isRulesTemplate(template: string): boolean;
```

Source: [packages/engine/src/rules/genres.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/genres.ts)

### labelledContent

Ids of the content players read labels for (towers, cards...), in declaration order.

```ts check=skip
function labelledContent(m: GameManifest): string[];
```

Source: [packages/engine/src/rules/genres.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/genres.ts)

### marshCenter

A tile's centre in fixed units.

```ts check=skip
function marshCenter(map: Pick<CompiledMarsh, "w" | "h">, tx: number, ty: number): { x: number; z: number; };
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### marshRoute

Tiles from `from` to `goal` (excluding `from`), around blocked tiles; empty when there is no way.

```ts check=skip
function marshRoute(map: CompiledMarsh, from: number, goal: number): number[];
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### marshTile

The tile at a fixed-unit point (marsh centred on the origin), or -1 off the map.

```ts check=skip
function marshTile(map: Pick<CompiledMarsh, "w" | "h">, x: number, z: number): number;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### plantCost

Salt (milli) the next level of plant `i` costs at `level`.

```ts check=skip
function plantCost(g: CompiledIdleGame, i: number, level: number): number;
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### plantSpot

Where plant `i` stands on a plot (two rows of four), metres from the plot centre.

```ts check=skip
function plantSpot(i: number): { x: number; z: number; };
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### playRules

```ts check=skip
function playRules<S>(genre: RulesGenre<S>, manifest: GameManifest, opts: HarnessOptions): RulesPlaytest;
```

Source: [packages/engine/src/rules/harness.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/harness.ts)

### plotCenter

A plot's centre in metres. Rows sit either side of the canal the contract barge waits on.

```ts check=skip
function plotCenter(slot: number): { x: number; z: number; };
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### rand

```ts check=skip
function rand(r: Rng): number;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### randInt

0..n-1.

```ts check=skip
function randInt(r: Rng, n: number): number;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### roadCoverage

```ts check=skip
function roadCoverage(b: CompiledBoard, rangeQ: number): Int32Array;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### roadPoint

Position on the road at progress `d` (Q units), in Q units with the board's corner at 0, and the heading (u16 turn).

```ts check=skip
function roadPoint(b: CompiledBoard, d: number): { qx: number; qy: number; yaw: number; };
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### rulesAdapter

The SimAdapter for a board genre built from a game manifest.

```ts check=skip
function rulesAdapter<S>(genre: RulesGenre<S>, manifest: GameManifest, opts: RulesAdapterOptions): SimAdapter<RulesWorld<S>, RulesInput> & { readonly genre: RulesGenre<S>; readonly manifest: GameManifest; };
```

Source: [packages/engine/src/rules/adapter.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/adapter.ts)

### shuffle

Fisher-Yates in place.

```ts check=skip
function shuffle<T>(r: Rng, list: T[]): T[];
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### statAt

A stat at a level: +12% a level.

```ts check=skip
function statAt(base: number, level: number): number;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### tileAt

The tile under a point in metres, or null off the board.

```ts check=skip
function tileAt(b: Pick<CompiledBoard, "w" | "h">, x: number, z: number): { tx: number; ty: number; } | null;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### tileCenter

A tile's centre in metres, board centred on the origin.

```ts check=skip
function tileCenter(b: Pick<CompiledBoard, "w" | "h">, tx: number, ty: number): { x: number; z: number; };
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### tileKey

Tile key.

```ts check=skip
function tileKey(x: number, y: number): number;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### towerGenre

```ts check=skip
function towerGenre(m: GameManifest): RulesGenre<TowerState> & { readonly game: CompiledTowerGame; };
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### wavePreview

What the next wave brings, by creep type (the HUD's preview).

```ts check=skip
function wavePreview(g: CompiledTowerGame, n: number): { type: number; count: number; }[];
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### waveSpawns

The spawns of wave `n` (1-based), by tick offset into the wave.

```ts check=skip
function waveSpawns(g: CompiledTowerGame, n: number, tickRate: number): Spawn[];
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### works

Per-second rates a works runs at (litres, kg, crystals), before tending.

```ts check=skip
function works(g: CompiledIdleGame, w: Pick<Works, "levels">, might: number): { pump: number; pan: number; kiln: number; };
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### xpNeed

XP to the next level.

```ts check=skip
function xpNeed(level: number): number;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

## Constants

### CardAct

Actions (RulesInput.act).

```ts check=skip
const CardAct: { readonly Play: 1; readonly Attack: 2; readonly End: 3; readonly Draft: 4; };
```

Source: [packages/engine/src/rules/cards.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/cards.ts)

### CollectorAct

Actions (RulesInput.act).

```ts check=skip
const CollectorAct: { readonly Pick: 1; readonly Move: 2; readonly Swap: 3; readonly Snare: 4; readonly Flee: 5; readonly Challenge: 6; };
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### CreepFlag

Creep flags on the wire.

```ts check=skip
const CreepFlag: { readonly Slowed: 1; readonly Boss: 2; readonly Dead: 4; readonly Leaked: 8; };
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### ENTITY_BASE

Entity ids a genre uses start here (avatars take the player ids below).

```ts check=skip
const ENTITY_BASE: 65536;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### IDLE_INPUT

```ts check=skip
const IDLE_INPUT: RulesInput;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### IDLE_MIN_FIRST_EARN

The gate's floor: no earn rule may pay sooner than this after a fresh works starts, with perfect play (seconds).

```ts check=skip
const IDLE_MIN_FIRST_EARN: 180;
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### IDLE_SEATS

```ts check=skip
const IDLE_SEATS: number;
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### IdleAct

Actions (RulesInput.act).

```ts check=skip
const IdleAct: { readonly Rake: 1; readonly Buy: 2; readonly Ship: 3; };
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### LogKind

What a battle log line says happened.

```ts check=skip
const LogKind: { readonly Hit: 1; readonly Miss: 2; readonly Heal: 3; readonly Guard: 4; readonly Swap: 5; readonly Snared: 6; readonly Slipped: 7; readonly Fled: 8; readonly Won: 9; readonly Fainted: 10; readonly Wiped: 11; readonly Level: 12; readonly Met: 13; readonly Warden: 14; };
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### MARSH_TILE

Metres per tile.

```ts check=skip
const MARSH_TILE: 2;
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### MILLI

Milli-units per unit (litres, kg, crystals).

```ts check=skip
const MILLI: 1000;
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### PLOT

Plot layout: four across, two deep, each 12 x 10 m.

```ts check=skip
const PLOT: { readonly w: 12; readonly d: 10; readonly cols: 4; readonly rows: 2; readonly gapX: 1.5; readonly gapZ: 5; };
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### Q

Fixed-point units per tile.

```ts check=skip
const Q: 256;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### RF

Field indices in RULES_SCHEMA.

```ts check=skip
const RF: { readonly x: 0; readonly z: 1; readonly yaw: 2; readonly type: 3; readonly hp: 4; readonly flags: 5; readonly value: 6; readonly aux: 7; };
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RULES_BOT_BASE

Seat bots and only them: player ids at 0xff00 and up (engine-sim's BOT_PLAYER_BASE).

```ts check=skip
const RULES_BOT_BASE: 65280;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RULES_SCHEMA

The wire schema every board genre shares: position (1/64 m), facing, a
type, health, flags and two small values. Units interpolate their
position; everything else steps.

```ts check=skip
const RULES_SCHEMA: EntitySchema;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### rulesInputCodec

50 bits a tick idle, 99 with an action.

```ts check=skip
const rulesInputCodec: InputCodec<RulesInput>;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesKind

Entity kinds on the wire.

```ts check=skip
const RulesKind: { readonly Avatar: 1; readonly Unit: 2; readonly Shot: 3; readonly Structure: 4; readonly Pickup: 5; };
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### Target

Target codes (RulesInput.b): 0 none, 1 the enemy hero, 2 your hero, 10+i enemy unit i, 20+i your unit i.

```ts check=skip
const Target: { readonly None: 0; readonly EnemyHero: 1; readonly OwnHero: 2; readonly EnemyUnit: 10; readonly OwnUnit: 20; };
```

Source: [packages/engine/src/rules/cards.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/cards.ts)

### TILE_M

Metres per tile.

```ts check=skip
const TILE_M: 2;
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### TowerAct

Actions (RulesInput.act).

```ts check=skip
const TowerAct: { readonly Build: 1; readonly Upgrade: 2; readonly Sell: 3; readonly Ready: 4; };
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### UNITS

Fixed-point units per metre for avatars and entities.

```ts check=skip
const UNITS: 64;
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

## Types

### Avatar

A player's avatar (fixed point). The only state a client predicts.

```ts check=skip
interface Avatar {
  x: number;
  z: number;
  yaw: number;
  cosmetic: number;
  flags: number;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### CardsState

```ts check=skip
interface CardsState {
  rng: { s: number };
  ctx: RulesContext;
  tick: number;
  stage: "waiting" | "duel" | "draft" | "done";
  duelNo: number;
  duel: Duel | null;
  countdown: number;
  players: Map<number, CardPlayer>;
  alone: number;
  log: LogLine[];
  finished: number;
  draws: number;
  peakBoard: number;
  activity: number;
  turnsPlayed: number[];
}
```

Source: [packages/engine/src/rules/cards.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/cards.ts)

### CollectorState

```ts check=skip
interface CollectorState {
  rng: { s: number };
  ctx: RulesContext;
  tick: number;
  dusk: number;
  wardenHp: number;
  wardenMax: number;
  wardenDown: boolean;
  wardenHurt: Set<number>;
  keepers: Map<number, Keeper>;
  activity: number;
  battlesWon: number;
  catches: number;
  wipes: number;
  peakBattles: number;
}
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### CompiledBoard

```ts check=skip
interface CompiledBoard {
  readonly w: number;
  readonly h: number;
  readonly path: readonly (readonly [number, number])[];
  readonly cum: readonly number[];
  readonly length: number;
  readonly road: ReadonlySet<number>;
  readonly blocked: ReadonlySet<number>;
}
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### CompiledCards

```ts check=skip
interface CompiledCards {
  readonly table: CardTableDef;
  readonly cards: readonly { readonly id: string; readonly def: CardDef }[];
  readonly starter: readonly number[];
  readonly pool: readonly number[];
}
```

Source: [packages/engine/src/rules/cards.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/cards.ts)

### CompiledCollector

```ts check=skip
interface CompiledCollector {
  readonly marsh: MarshDef;
  readonly map: CompiledMarsh;
  readonly creatures: readonly (CreatureDef & { id: string; el: number; moveIdx: number[] })[];
  readonly moves: readonly (MoveDef & { id: string; el: number })[];
  readonly starters: readonly number[];
  readonly wardenSpecies: number;
  readonly pools: readonly { rate: number; pool: { species: number; weight: number; level: readonly [number, number] }[] }[];
}
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### CompiledIdleGame

```ts check=skip
interface CompiledIdleGame {
  readonly shiftTicks: number;
  readonly tendTicks: number;
  readonly start: number;
  readonly rakeSalt: number;
  readonly rakeTicks: number;
  readonly brinePerSalt: number;
  readonly saltPerCrystal: number;
  readonly packEvery: number;
  readonly contract: number;
  readonly plants: readonly { readonly id: string; readonly def: PlantDef }[];
}
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### CompiledMarsh

```ts check=skip
interface CompiledMarsh {
  readonly w: number;
  readonly h: number;
  readonly blocked: Uint8Array;
  readonly water: Uint8Array;
  readonly grass: Uint8Array;
  readonly camp: readonly [number, number];
  readonly warden: readonly [number, number];
}
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### CompiledTower

```ts check=skip
interface CompiledTower {
  readonly id: string;
  readonly def: TowerDef;
  readonly levels: readonly TowerStats[];
  readonly upgradeCost: readonly number[];
}
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### CompiledTowerGame

Everything a tower defense game declared, compiled (shared by the room, the harness and the client).

```ts check=skip
interface CompiledTowerGame {
  readonly board: CompiledBoard;
  readonly towers: readonly CompiledTower[];
  readonly creeps: readonly { id: string; model: string; health: number; speed: number; value: number; damage: number; boss: boolean }[];
  readonly lives: number;
  readonly gold: number;
  readonly prep: number;
  readonly breather: number;
  readonly share: number;
  readonly waveGold: { base: number; perWave: number };
  readonly refund: number;
  readonly totalWaves: number;
  readonly healthGrowth: number;
  readonly groups: readonly { type: number; from: number; until: number; every: number; count: number; grow: number; gap: number; delay: number }[];
}
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### IdlePolicy

Bot policies: "best" plays the chain as well as the template knows, "human" slower, "clicker" only rakes, "idle" does nothing.

```ts check=skip
type IdlePolicy = "best" | "human" | "clicker" | "idle";
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### IdleState

```ts check=skip
interface IdleState {
  rng: { s: number };
  ctx: RulesContext;
  tick: number;
  players: Map<number, Works>;
  contract: number;
  filled: boolean;
  done: boolean;
  activity: number;
}
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)

### LogLine

```ts check=skip
interface LogLine {
  readonly n: number;
  readonly kind: number;
  readonly who: 0 | 1;
  readonly move?: number;
  readonly dmg?: number;
  readonly eff?: number;
  readonly value?: number;
}
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### Mon

```ts check=skip
interface Mon {
  species: number;
  level: number;
  hp: number;
  xp: number;
  guard: boolean;
}
```

Source: [packages/engine/src/rules/collector.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/collector.ts)

### Rng

mulberry32 on a state word kept in the genre's state (so a restored state continues the same stream).

```ts check=skip
interface Rng {
  s: number;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesAdapterOptions

```ts check=skip
interface RulesAdapterOptions {
  readonly name: string;
  readonly version: string;
}
```

Source: [packages/engine/src/rules/adapter.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/adapter.ts)

### RulesCheck

A genre's own line in the playtest gate: a hard check or a scored part.

```ts check=skip
interface RulesCheck {
  readonly ok: boolean;
  readonly line: string;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesContext

What a genre reads about the players from the adapter.

```ts check=skip
interface RulesContext {
  bonus(player: number, stat: string): number;
  isBot(player: number): boolean;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesGenre

One board genre. `S` is its whole authoritative state: integers, arrays
and maps in insertion order, a PRNG word. Factories build one from the
game's manifest (rules/genres.ts).

```ts check=skip
interface RulesGenre<S> {
  readonly template: string;
  readonly tickRate: number;
  readonly endSeconds: number;
  readonly infoEveryTicks: number;
  create(seed: number, ctx: RulesContext): S;
  spawn(s: S | null, player: number): { x: number; z: number };
  moveAvatar(a: Avatar, input: RulesInput): void;
  join(s: S, player: number): void;
  leave(s: S, player: number): void;
  act(s: S, player: number, input: RulesInput, avatar: Avatar, emit: (e: GameEvent) => void): void;
  tend?(s: S, player: number, avatar: Avatar, emit: (e: GameEvent) => void): void;
  step(s: S, emit: (e: GameEvent) => void): void;
  outcome(s: S): RunOutcome | null;
  view(s: S, player: number | null): Record<string, unknown>;
  entities(s: S, out: EntityState[]): void;
  seats?(s: S, humans: number): number;
  bot(s: S, player: number, avatar: Avatar, tick: number, skill: number): RulesInput;
  stats(s: S): RulesStats;
  activity(s: S): number;
  checks(run: RulesHarnessRun): RulesCheck[];
  progress(run: RulesHarnessRun): number;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesHarnessRun

One harness run's numbers, for a genre's checks.

```ts check=skip
interface RulesHarnessRun {
  readonly seconds: number;
  readonly players: number;
  readonly stats: RulesStats;
  readonly runs: { readonly won: number; readonly lost: number };
  readonly earned: Readonly<Record<string, number>>;
  readonly firstEarnSeconds: number | null;
  readonly firstRunSeconds: number | null;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesInput

One tick of a player's input.

```ts check=skip
interface RulesInput {
  readonly mx: number;
  readonly mz: number;
  readonly cx: number;
  readonly cz: number;
  readonly act: number;
  readonly a: number;
  readonly b: number;
  readonly c: number;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesPlaytest

One run of the playtest, with the genre's numbers kept for its checks.

```ts check=skip
interface RulesPlaytest {
  readonly report: HarnessReport;
  readonly run: RulesHarnessRun;
}
```

Source: [packages/engine/src/rules/harness.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/harness.ts)

### RulesStats

Numbers the headless harness reports (HarnessReport), in the genre's own sense.

```ts check=skip
interface RulesStats {
  readonly kills: number;
  readonly wave: number;
  readonly level: number;
  readonly deaths: number;
  readonly peakUnits: number;
  readonly scorers: number;
  readonly topScore: number;
}
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### RulesWorld

```ts check=skip
interface RulesWorld<S = unknown> {
  readonly role: "server" | "client";
  state: S | null;
  readonly avatars: Map<PlayerId, Avatar>;
  tick: number;
  runTick: number;
  phase: "playing" | "ended";
  outcome: RunOutcome | null;
  endTick: number;
  readonly earn: EarnTracker | null;
  readonly late: Set<PlayerId>;
  progressed: boolean;
  readonly upgrades: Map<PlayerId, Map<string, number>>;
  readonly paid: Map<PlayerId, Set<string>>;
  readonly bots: Set<PlayerId>;
  awards: number;
}
```

Source: [packages/engine/src/rules/adapter.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/adapter.ts)

### RunOutcome

```ts check=skip
type RunOutcome = "won" | "lost";
```

Source: [packages/engine/src/rules/kit.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/kit.ts)

### TowerState

```ts check=skip
interface TowerState {
  rng: { s: number };
  ctx: RulesContext;
  tick: number;
  wave: number;
  phase: "build" | "wave";
  countdown: number;
  lives: number;
  livesMax: number;
  livesBought: Map<number, number>;
  queue: Spawn[];
  waveTick: number;
  creeps: Creep[];
  towers: Tower[];
  players: Map<number, TowerPlayer>;
  nextId: number;
  kills: number;
  leaks: number;
  peak: number;
  won: boolean;
  activity: number;
}
```

Source: [packages/engine/src/rules/tower.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/tower.ts)

### Works

```ts check=skip
interface Works {
  slot: number;
  brine: number;
  salt: number;
  crystals: number;
  made: number;
  packs: number;
  cutAcc: number;
  cut: number;
  levels: number[];
  lastTend: number;
  rakeAt: number;
  shipped: number;
  rakes: number;
}
```

Source: [packages/engine/src/rules/idle.ts](https://github.com/netnetdev/net-forge/blob/main/packages/engine/src/rules/idle.ts)
