AGENTS.md
The entry point for anyone working in this repo, person or agent. It’s a map: follow the links.
Read first
Section titled “Read first”packages/spec/docs/: the spec. It is the source of truth.apps/website/guides/: the guides for app developers.apps/website/glossary.md: what OCF’s terms mean.
The documentation website (https://opencharacterformat.org/) is built from these files.
Where things live
Section titled “Where things live”| Path | What |
|---|---|
packages/spec/schemas/ |
JSON Schemas (draft 2020-12); engine/ holds call inputs and outputs |
packages/spec/data/ |
Fixed sets as data (effect operations, dice modifiers, change types, stacking policies, error codes, formula context, …) |
packages/spec/docs/ |
Spec docs for implementers |
packages/spec/i18n/ |
Standard text for the spec’s error and rules-issue codes |
packages/spec/tests/ |
Shared conformance test suite |
packages/engine/ |
Reference engine (TypeScript) |
packages/text/ |
Wording helper (TypeScript): engine output to finished text |
packages/packs/ |
The @opencharacter/packs bundle of every official pack |
apps/web-editor/ |
Local pack editor (pnpm editor); private, never published |
apps/website/ |
Documentation website (Astro Starlight, GitHub Pages): guides, glossary, and the spec synced in; private, never published |
packs/<game>/<pack>/ |
One pack (ID <game>-<pack>, version from 0.1.0): pack.yaml, rules/, content/, i18n/, upgrades/. A game folder holds that game’s editions and content packs |
examples/characters/ |
Example character files |
scripts/ |
validate, build:packs, release:check and types |
Commands
Section titled “Commands”| Command | Does |
|---|---|
pnpm install |
Install (Node 22, pnpm 10) |
pnpm lint |
oxlint, then oxfmt in check mode |
pnpm format |
Format everything with oxfmt (TS, JSON, YAML, Markdown) |
pnpm typecheck |
TypeScript, strict |
pnpm test |
Vitest: schema checks, fixed sets vs. schemas, validator tests |
pnpm validate |
Check every pack and example character against the schemas and check every reference |
pnpm types |
Regenerate the TypeScript types in packages/spec/src/types.ts from the schemas (run after changing a schema) |
pnpm editor |
Start the local pack editor (apps/web-editor) at http://127.0.0.1:5173 |
pnpm website |
Start the documentation website (apps/website) at http://localhost:4321/ |
pnpm build:website |
Build the website into apps/website/dist/ and check every internal link |
pnpm build:packs |
Validate, then build every pack’s release (dist/), the @opencharacter/packs bundle and the spec’s text modules |
pnpm release:check |
Compare each pack with its last published release (git tags): published versions unchanged, shape changes covered |
pnpm version-packages |
changeset version, then sync pack.yaml versions |
pnpm release |
Every check plus build and release check. Publishing is disabled until the release flow is enabled |
pnpm check |
Lint, typecheck, test and validate. CI also runs build:packs, release:check and build:website |
Run pnpm check before every commit, and pnpm release and pnpm build:website too when you
change packs, scripts or docs.
- Mechanics in
content/andrules/, text ini18n/. No player-facing string next to mechanics. One file per content item; itsidmatches its path. - No copyrighted rules text from games that aren’t openly licensed. Mechanics-only packs hold the math and names only. Open-licensed packs keep their license and credit line.
- Every pack that starts a sheet offers a random start (
random: trueincreation) beside its guided one: its steps recommend every pick, so an automatic run finishes. Where the book has no random method, the pack picks reasonable odds. - Every pack declares a license in
pack.yaml(and acreditfor CC-BY; acreditandnoticesfor ORC). - No PDF support, no hosted service. The only editor is the local
apps/web-editor. - Packages and packs publish only through the release flow (changesets,
pnpm release); packs stayprivate: trueuntil then. - Commits are small, logical and signed off (
git commit -s, DCO; see CONTRIBUTING.md).
When the format falls short
Section titled “When the format falls short”Model a game with the features the format has; prefer a clever use of them to a hack. When the format can’t express a rule, or a spec change would help, open a GitHub issue (see CONTRIBUTING.md). Don’t change the spec silently.