Contributing
Moonspell is open source under the MIT License: the engine and game template, the examples, the skills, the server with Nova and the worker runs, the edge Worker, the contracts, the specs and these docs. The Moonspell phone app and the bundling CLI are private (What is open and what is private). Contributions to any public part are welcome.
How to contribute
- For anything bigger than a small fix, open an issue first and describe the change. It saves building something that cannot be merged.
- Fork the repository and create a branch from
main. - Keep the change focused: one fix or one feature per pull request.
- Run the checks for every folder you touched (below) and say in the pull request what you ran.
- A maintainer reviews it.
The root CONTRIBUTING.md says the same in short.
The public tree
| Path | What it is |
|---|---|
templates/crescent-game/ | The engine (src/engine/), the starter game Sunset Sprint (src/game/), the example games (examples/), and the CLAUDE.md, AGENTS.md, .claude/skills/ and docs/ a coding agent reads. Every game repo starts as a copy of it. See Engine overview |
agent/ | Nova, the chat agent (eve). See Nova and the worker |
src/workflows/ | The game-run and cover workflows |
src/lib/ | Server logic: the sandbox and run script (daytona.ts), games, repos, realtime tokens, credits, community builds, sign-in |
src/app/ | Next.js routes: the app API (api/app/), internal routes (api/internal/), the web app ((app)/), the shared-game page (g/), the game page (w/), well-known files |
src/web/ | The web app's client code |
edge/ | The Cloudflare Worker in front of the server. See Live progress |
db/ | Postgres migrations and migrate.mjs |
contracts/, spec/ | What the three apps share, and every app behaviour with a column per app. See Three apps, one product |
scripts/ | Operational scripts: the sandbox snapshot, starter upload, backfills, asset generation, playtests. Those that export games need the private CLI |
playtests/ | Playtest scripts for older games that predate playtest.json |
docs/, docs-site/ | These docs, and the Docusaurus site that renders them |
.scratch/ | Plans and issues (below) |
Checks before a pull request
All of these are real scripts in the repo's package.json files.
| You changed | Run | Where |
|---|---|---|
| The engine, the template, an example | npm run typecheck, npm test, npm run export:web | templates/crescent-game/ |
| The server, Nova, the workflows, the web app | npm run typecheck, npm run lint, npm test, npm run build | repo root |
| The edge Worker | npm run typecheck (and npm test at the root, which runs its tests) | edge/ |
| The backend scaffold | npm run typecheck, npm run smoke against wrangler dev | the scaffold's backend/ |
| Contracts | npm run contracts, then npm run contracts -- --check | repo root |
| Feature specs | npm run parity | repo root |
| Docs | npm --prefix docs-site run build | repo root |
A change to how a game looks or plays should also be played in a browser with npm run web in the template. More detail per part is in Testing.
Plans and issues
Bug reports and ideas go in the repository's issues. Larger pieces of work are planned in Markdown under .scratch/:
- one folder per feature,
.scratch/<feature-slug>/; - the plan is
.scratch/<feature-slug>/PRD.md; - issues are
.scratch/<feature-slug>/issues/<NN>-<slug>.md, numbered from01; - each issue has a
Status:line near the top:needs-triage,needs-info,ready-for-agent,ready-for-human,wontfix, ordonewith a line saying how it was verified.
What is planned next for the engine is in the Roadmap.
Rules
A game is written once and plays on the web, iOS and Android. What differs per platform belongs in the engine (*.web.ts files, Platform.OS checks), never in a game and never in one app. If a game needs a platform workaround, the fix goes into the engine so every game gets it. See Platform layer.
The template is the production template. The hosted Moonspell worker makes every new game from templates/crescent-game/, and on each run it copies the template's engine, skills, docs, examples, CLAUDE.md and package files into existing games, for every file their builder never changed. A change there reaches every game on its next build. So:
- keep changes additive and backwards compatible;
- do not rename or remove scripts, skills, files or exports that games may use;
- do not change engine behaviour that games rely on without a plan in
.scratch/; - keep the template's own docs and skills in step with the code they describe.
Game data lives on the game's own backend. Leaderboards, rooms and saves use the backend scaffold in templates/crescent-game/.claude/skills/realtime-backend/scaffold/backend/, never a third-party data service. See Backend overview.
The app's native surface is fixed. A game cannot add native code: the template's package.json pins the native modules the Moonspell app ships. Pure JavaScript packages are fine.
Generated files are never edited by hand. For example src/web/generated/: change contracts/ and run npm run contracts.
Docs are true or they are not written. Every name, prop, command and path on a page matches the source. Code samples come from, or are checked against, templates/crescent-game/src and examples/. Pages are MDX: keep placeholders and braces inside code. Short sentences, plain words, no emoji.
Design is monochrome. Black, white and grays, in the docs, the web app and the engine's default UI.