AGENTS.md ยท diff
git:20261015.165f112 to git:20261026.b8239cd
24 added, 22 removed. Audit A to B.
- # paprika3D (the three.js toolset for coding agents)
+ # paprika3d (the three.js toolset for coding agents)
- This is the paprika3D plugin: an MCP server whose `game_*` tools let a coding agent open, look at, play, measure and fix
- three.js, React Three Fiber and WebGL pages in headless Chrome on a paused, seeded clock. Use it on any such page you
- write or change (a game, a product viewer, a simulation, a shader demo), before saying it is done. The page needs no
- changes to be opened, looked at and driven.
+ This is the paprika3d plugin: an MCP server, `paprika`, whose tools let a coding agent open, look at, play, measure and fix
+ three.js, React Three Fiber and WebGL pages in headless Chrome (or Firefox: `open`'s `browser`) on a paused, seeded clock. Use it on any such page you
+ write or change (a game, a product viewer, a simulation, a shader demo). The page needs no changes to be opened, looked
+ at and driven. Build the first version whole and as impressive as you can, risks welcome: these tools make debugging
+ and polishing it cheap.
When the user says "use paprika3d to playtest" (or "playtest it", "look at it", "check the scene"), run the loop below.
- ## The loop: open, look, act, eval
+ ## The loop: open, look, interact, eval
- 1. **Open:** `game_open` with `cwd` (the project folder) and `url: "index.html"` (the folder is served) or
+ 1. **Open:** `open` with `cwd` (the project folder) and `url: "index.html"` (the folder is served) or
`command: "bunx vite"`. Read the `Loaded:` and `Failed to load:` lines.
- 2. **Look:** `game_look`. Read `Never visible:`: an object of 0.07 units in a scene 8 units wide is at the wrong scale;
+ 2. **Look:** `look`. Read `Never visible:`: an object of 0.07 units in a scene 8 units wide is at the wrong scale;
`behind the camera` or `outside the view` is a framing problem. Open the picture it saves.
- 3. **Act:** for each interaction the request names, `game_act` (keys, mouse, touch or `__game.act` actions, frame by
- frame) and read the state before and after. `game_clock` steps time.
- 4. **Eval:** `game_eval` runs JavaScript in the page with `scene`, `camera`, `renderer`, `find(name)` and
+ 3. **Interact:** for each interaction the request names, `interact` (keys, mouse, touch or `__game.act` actions, frame by
+ frame) and read the state before and after; a `{ wait }` step steps time.
+ 4. **Eval:** `eval` runs JavaScript in the page with `scene`, `camera`, `renderer`, `find(name)` and
`stats(target)` in scope, to check sizes, materials and positions or try a change before writing it into the source.
- 5. Fix, then look again. `game_perf` when performance matters; `game_optimize` only when a check says the frame is over
+ 5. Fix, then look again. `perf` when performance matters; `optimize` only when a reply says the frame is over
budget or the user asks.
- For a game with exact rules (scoring, collisions, turn order, stated numbers), lock a contract with `game_contract`
- and run `game_check` after each change. Never edit `game-contract.json` by hand: its hash is kept outside the project.
-
## The `window.__game` convention
- Any page can be opened and looked at. To read and check a game's state, the page sets, once loaded:
+ Any page can be opened and looked at. To read and set a game's state, the page sets, once loaded:
```js
window.__game = {
describe(), // name, controls, units
- observe(), // the state as plain JSON (the keys of game-contract.json's schema)
+ observe(), // the state as plain JSON
act(input), // one input: { key, down? } or { action, ...args }
- setState(partial), // sets any of the schema's keys at once
+ setState(partial), // sets any of observe()'s keys at once
};
```
- It starts playing on load (no title screen, no click to start), takes time only from `requestAnimationFrame` /
- `performance.now` and randomness only from `Math.random`; paprika3D fakes and seeds both. Keys listen on `window` and
+ It starts playing on load (no title screen, no click to start, nothing over the first frame), takes time only from `requestAnimationFrame` /
+ `performance.now` and randomness only from `Math.random`; paprika3d fakes and seeds both. Keys listen on `window` and
match `event.key`.
## More
- The full method, templates (plain three.js, React Three Fiber, Rapier) and rules: `skills/threejs-game/SKILL.md`,
- with `references/contract.md`, `references/geometry.md` and `references/optimize.md` beside it.
- - `game_open` puts `geo.js` (booleans, hull, extrude, revolve, seeded scatter) in the project.
+ with `references/geometry.md` and `references/optimize.md` beside it.
+ - The `open` tool puts `geo.js` (booleans, hull, extrude, revolve, seeded scatter) and `fx.js` (sound effects, canvas
+ textures, particle bursts, a first-load stage, texture coordinates, placement rules) in the project.
- Runs are saved in `<project>/paprika3d/runs/`; add `paprika3d/` to the project's `.gitignore`.
+ - Publishing (`publish`, a preview, invite-only) is only for when the user asks for a paprika3d.app link. Never read,
+ print or paste `~/.config/paprika3d/credentials.json` or `PAPRIKA3D_PUBLISH_KEY`: `publish` reads the key itself, and
+ whatever you print lands in the transcript.