Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/agent-docs-and-simulation-coverage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@typeonce/ritmo": patch
"@typeonce/ritmo-browser": patch
"@typeonce/ritmo-render": patch
"@typeonce/ritmo-pixi": patch
"@typeonce/ritmo-math": patch
"@typeonce/ritmo-devtools": minor
"@typeonce/oxlint-plugin-ritmo": patch
---

**Everything a game's agent needs now ships with the packages, and `ritmo-devtools lint` reports simulation modules the lint rules miss.**

- **Breaking: `ritmo-devtools lint` fails on an uncovered simulation module.** Every module the entry loads that the `ritmo/keep-simulation-headless` override in `.oxlintrc.json` does not cover is reported as `uncovered-simulation-module`, and the command exits 1. Add the module (or its folder) to the simulation override's `"files"`, or stop importing values from it. Modules loaded only inside `lintTarget` are not checked. Requires Node 22.15 or newer (`engines.node` is now `>=22.15`).
- **An agent skill ships with `@typeonce/ritmo`** in `skills/ritmo/SKILL.md`, for every change: where the docs are, and principles for where a game's code and state belong. Link it into the folder the game's agent reads skills from, for example `ln -s ../../node_modules/@typeonce/ritmo/skills/ritmo .agents/skills/ritmo`. `SETUP.md` in `@typeonce/ritmo` is the one-time setup: the base packages and checks every game uses, the add-ons, and linking the skill.
- **Every package ships its `CHANGELOG.md`.** The upgrade notes for 0.8.0 and 0.9.0 moved from the repository's `MIGRATION.md` into the `@typeonce/ritmo` changelog.
- **JSDoc corrections.** Examples no longer provide randomness or time as services (use the `Random` resource and `Clock`), the `Command` module example declares its commands, inspector docs state that `added`/`changed` reads report records since the inspector's previous evaluation, and every example uses prefixed names (`"Game/Position"`). Guidance that lived only in the repository's guides (spawn order, `ReadonlyValue` helpers, re-entering a state, `thisTick` and plugin systems, service effects and rollback) is now in the JSDoc.
- Package READMEs link other packages' READMEs by GitHub URL, so the links work on npm.
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@
- Packages never draw. Drawing, particles, and effects stay in games.
- Bridge code that hands a renderer or the platform what it needs (nodes, positions, input, timing) and glue that would otherwise repeat in every game belong in the support packages.
- Hand the game the data it needs to draw (like `Touch`'s `view()`), never the drawing itself.
- A package earns its place when the host platform or an integration boundary defines what it owns, the repeated logic is infrastructure (not gameplay), and games vary it through typed inputs, descriptors, and callbacks without casts or explicit generics. Feature bundles (a platformer HUD, a browser runtime that wires input, rendering, and state together) stay in games.
- A plugin is a function `(Game, options) => System | Schedule` that returns ordinary systems the game places in its own schedules, like `RenderSync.system(Game, ...)` and `InputCapture.system(Game, ...)`. No plugin objects, registries, or composition steps; a plugin's descriptors are declared by the game or exported as a `Schema.fragment(...)`.
- Generic contracts have generic names (`NodeRegistry`); adapters put the implementation in the name (`PixiNodeRegistry`) and export only themselves. The host provides an adapter with `Game.Runtime.service`; systems declare the generic service.
- Core and generic package modules never call a platform API (`performance`, `window`, `document`, timers, file system, network). A platform detail is a generic contract in the owning package with platform implementations injected (like `NodeRegistry` / `PixiNodeRegistry`, `HostClock` / `BrowserHostClock`, `FixedLoop.TickSource` / `BrowserTickSource`). A default may use only what JavaScript itself guarantees in every engine. The compiler enforces this: package configs get only the ES2022 library, so a DOM or Node global does not compile; a host package that needs DOM types lists `"DOM"` in its own `lib`, as `packages/devtools` does for `Monitor`.
- Simulation code reads time from `Clock` and randomness from `Random`; host time (`HostClock`) is for hosts, tools, and debug timing, never for systems.
- Engines may approximate `Math.sin`, `cos`, `atan2`, `exp`, `log`, `pow`, `hypot`, the other transcendental functions, and `a ** b`, and they differ across browsers and CPUs. Package code and simulation code use `Ops` from `@typeonce/ritmo-math` instead (or `Math.sqrt(x * x + y * y)`).
- `pnpm lint` runs the repo's own oxlint plugin (`packages/oxlint-plugin`) over package sources, examples, and scripts (see `.oxlintrc.json`); the simulation rules cover every package source and the examples' simulation files. A rule that should not apply takes `// oxlint-disable-next-line ritmo/<rule> -- <reason>`.
- A new pattern that games must follow or avoid, and that types and devtools cannot catch, becomes a rule in `packages/oxlint-plugin`, with tests from real code. Its message says what goes wrong and the exact API to use instead.

## Docs
- A game's agent sees only what npm ships: each package's `src` JSDoc, `README.md`, `CHANGELOG.md`, `SETUP.md` in core, and the skill in [`packages/core/skills/ritmo`](./packages/core/skills/ritmo/SKILL.md). Guidance a game needs goes there, never in a repo-only file.
- The root `README.md` is the only doc for humans. `AGENTS.md`, `ARCHITECTURE.md`, and `RELEASING.md` are for work on this repo.
- Package READMEs link other packages' docs by their GitHub URL (`https://github.com/typeonce-dev/ritmo/blob/main/packages/<name>/README.md`), never by a relative path or into `examples/`, which do not ship.
- A changeset for a breaking change carries its fix (a short diff or the exact replacement), so the shipped `CHANGELOG.md` is the upgrade guide.
- [`packages/core/SETUP.md`](./packages/core/SETUP.md) is the one-time setup (base packages, checks, add-ons, linking the skill); the root README's starter prompt links it. The skill is for every change: where the docs are, and principles that change where code and state go. Anything a JSDoc, README, or lint message already says stays out of both.

## Core Principles
- Type safety is the first and absolute priority.
- Public APIs must be as strict as possible.
Expand Down
Loading
Loading