# Getting started

# Getting started

## Set up

Ferret is a pnpm workspace (`packages/*`, `examples/*`, `tools/*`). Babylon.js, Havok, recast-navigation and hls.js come in as development dependencies; esbuild bundles everything, so there is no other build step.

```bash
pnpm install
pnpm typecheck      # tsc --noEmit over every package
pnpm test           # vitest: unit tests of every package
pnpm build          # tools/build.mjs: dist/web, dist/beroun, dist/lib
pnpm serve          # tools/serve.mjs [port] [dir]: a static server for dist/web
```

`pnpm test:e2e` runs the Playwright tests against the built samples. `pnpm docs` builds this site into `dist/docs`.

## What a build produces

| Output | What it is |
|---|---|
| `dist/web/<sample>/` | each sample as a web page: open `index.html` through `pnpm serve` |
| `dist/beroun/<sample>/` | the same sample as an OS Beroun app: `manifest.json`, `icon.svg`, the page and the bundle |
| `dist/lib/ferret.js` | the engine as one script that exposes `Ferret` and `BABYLON` globals |
| `dist/lib/ferret/` | the release: engine, Babylon, loaders and the WASM files (Havok, recast), for apps that load the engine from OS Beroun's shared library |

The samples show what each part is for: `greybox` (a character in a grey-box level), `npc` (NavMesh walkers, doors, levers), `showcase` (media, UI, transformations) and `physics` (the realistic-physics capabilities).

## A first game

A game is a canvas, `createGame`, a level and a start call. This is the shape of `examples/greybox`:

```ts
import { createGame } from '@ferret/game';
import { PlayerController, spawnCharacter } from '@ferret/character';

const game = createGame({
  canvas: document.getElementById('c') as HTMLCanvasElement,
  storageKey: 'my-game',                       // one key per game in a browser
  input: { actions, bindings },                // see "Input and UI"
});
const { world, platform, scene } = game;

// ...build the level's meshes into `scene`; static meshes with checkCollisions are solid

const { entity } = spawnCharacter(world, 'hero', new BABYLON.Vector3(0, 1, 0));
const player = entity.add(PlayerController, { camera: { view: 'first' } });
game.display.trackCamera(player.rig.camera);   // the field of view follows the screen's aspect

world.events.on('character:jump', () => platform.log('jump'));
game.start();                                  // render loop + fixed-step simulation
```

`createGame` gives you the platform, the Babylon engine and scene, the `World`, the `Display`, the `InputService` and the `PhysicsService`. Anything else is a service you add to the world.

## Where to go next

- The world (skill `ferret`): entities, components, services, events and the fixed step.
- Levels and packages (skill `ferret-levels`): how a level is described and loaded.
- Physics overview (skill `ferret`): how to get realism where a game wants it.
- Commands (skill `ferret`): every debug command a tool or an AI agent can call.

## Build this documentation

```bash
pnpm docs                         # dist/docs
pnpm serve 8080 dist/docs         # then open http://localhost:8080
```

The guides are the Markdown files in `docs/`; the API pages are read from the TypeScript sources. See Writing the docs (skill `ferret`).
