Chapter 2 of 13
Quick start
Scaffold a project, run it behind a tunnel, play every seat in the Inspector, and see what each file of the project is for.
pnpm create camtable-addon my-game # host mode: static files only, free to host
pnpm create camtable-addon my-game --engine # engine mode: one Worker serves the pages and your engine
cd my-game
pnpm install
pnpm dev # then open the Inspector link it prints
(npm create camtable-addon@latest my-game and npx create-camtable-addon my-game work too.)
pnpm dev puts your addon behind a temporary https tunnel and prints an Inspector link with
its manifest address filled in: a page on the CamTable website where you sign in with Discord and
play every seat of a match in a real room, without a Discord call or the extension (section 11: Testing locally). It
also prints an Install Link, for trying the game in a real call. There is no offline way to try a
game. To share it, deploy it and give out the https manifest URL (section 9: Hosting and section 10: Installing, sharing and updating).
The project contains:
| File | Purpose |
|---|---|
src/game.ts |
The rules, a pure reducer (tapRace). The same object runs in both modes. Also the race’s Game Settings (RACE_SETTINGS, the number of taps to win), which the reducer reads. |
src/addon.ts |
The manifest and every protocol route, built from a few constants. Change ADDON_ID first. |
index.html, src/main.ts, src/ui.ts |
The game page: “Tap Race”, first to ten taps wins. In host mode main.ts calls createHostAuthority(tapRace, { sdk }). |
vite-plugin-addon.ts, vite.config.ts |
Serve the protocol routes in development (with CORS) and write them as static files on build. |
scripts/dev.mjs |
pnpm dev: the addon behind a temporary https tunnel, with the Inspector link and the Install Link for it (section 11: Testing locally). |
public/_headers, public/404.html |
CORS and cache headers, and a real 404, for Cloudflare (other hosts: section 9: Hosting). |
src/engine/worker.ts, wrangler.json, scripts/serve-worker.mjs |
(--engine) The one Worker: static assets from dist/, and your rules behind signed /engine/* routes; pnpm dev runs it locally. |
tests/ |
The reducer, a whole match through it, and every route against the protocol; (--engine) the engine refusing an unsigned request and accepting a signed one. None needs a network. |
The scaffolded README covers the daily commands.