GreatSprites is in preparation. Join early access for two free tests at launch.
GreatSprites Early access Open app

Docs

Instructions for coding agents

A text to give your coding agent, or add to your pipeline's rules, so it puts GreatSprites animations into your game the right way.

Coding agents follow written rules well. Give yours the text below, or add it to your pipeline's rules (an AGENTS.md or your project's instructions), and it adds GreatSprites animations the way the runtime expects: files untouched, the runtime started once, the right loader and height, loops not awaited, memory released per scene.

Every export carries this text as AGENTS.md. In the app, Copy for your coding agent gives the same text with your own animations listed at the end: their folders, clip names, loops and one-shots, moments and memory.

# GreatSprites animations: instructions for a coding agent

You are adding GreatSprites sprite animations to a PixiJS v8 game. Follow these rules as written: the runtime and the files are made to work exactly this way.

## Files

- An export holds `greatsprites/` (the runtime: runtime.js, decode.js, transcoders/), `sprites/<name>/` (one folder per element: element.json, its still picture, one folder per clip), `weight-report.json` (memory per clip) and `example.html` (plays everything; open it over http to check).
- Put `greatsprites/` and `sprites/` in the game's static files (for example `public/`) exactly as they are. Never rename, move, convert or re-encode anything inside them: files are found by their names. Do not run them through an image or asset pipeline.
- AGENTS.md, README.txt, LICENSE.txt and example.html do not need to ship with the game.
- PixiJS v8 with its WebGL renderer (the default) is required: tested on every 8.x from 8.0.5 to 8.22.0. With the WebGPU renderer (`preference: 'webgpu'`) every element shows its still picture and does not animate, so keep the default or set `preference: 'webgl'`. PixiJS v7 and older are not supported.
- The runtime loads only these files; it never calls GreatSprites' servers.

## Start the runtime once

```js
import { Application } from 'pixi.js';
import { GreatSprites } from './greatsprites/runtime.js'; // where greatsprites/ is served

const app = new Application();
await app.init({ resizeTo: window });
const gs = await GreatSprites.init(app, { base: './greatsprites/' });
```

- Call `GreatSprites.init` once per PixiJS application, after `app.init`. `base` is the URL of the `greatsprites/` folder.

## Load and play

```js
const coin = await gs.object('./sprites/coin/', { height: 160 });
coin.position.set(200, 300); // the centre of the art
app.stage.addChild(coin);
await coin.play('win');      // resolves when it is back on its still picture
```

- `gs.object(url, { height })` loads an object or icon, `gs.character(url, { height })` a character. `height` is the height it is drawn at, in stage pixels (defaults: 160 for objects, 448 for characters). Load at the size it is really drawn instead of scaling it up afterwards: far above the loaded height it looks soft.
- An element is a PixiJS Container. Its position is the centre of the art; scale, add and remove it like any display object. Before its first play it shows the first frame of its first clip.
- `element.play(name, { speed, until })` returns a promise that resolves when the clip is back on the still picture (or on the moment named in `until`). It always resolves, also when the element is destroyed. A name the element does not have rejects with the list of its clips (`element.clips`).
- Every clip starts and ends on the same still picture, so any clip can follow any other without a jump. Starting a clip replaces the one playing, at once.
- A loop keeps playing until another clip starts: start it without awaiting it. A one-shot ends on the still picture and stays there.
- Moments: `element.on('<moment>', (moment, clip) => { ... })` fires on the exact frame of that moment; `await element.play('<clip>', { until: '<moment>' })` waits for it. Names are case-sensitive and belong to one clip. With `speed` above 1 the moments still arrive on their frames.
- More copies of an element: load the same URL at the same height again. Copies share one loaded set in memory (fifteen coins cost the memory of one); the same element at two heights is loaded twice.

## Memory

- A loaded element keeps all its clips in GPU memory until it is released. weight-report.json gives each clip's memory on a phone (`phone_mb`) and on desktop (`desktop_mb`).
- GreatSprites recommends about 32 MB of animation GPU memory loaded at the same time on a phone, and about 15 MB of animation download. It is a recommendation: follow the team's own line if it has one.
- Keep loaded what the current scene can show. On a scene change (for example into a bonus game) release first, then load: `element.destroy()` for each copy, then `gs.release('./sprites/<name>/')` once no copy will be shown again. Do it during a transition: loading takes a moment.
- If the game sets a renderer resolution, capping it at 2 (`Math.min(devicePixelRatio, 2)`) keeps sharp phone screens on the smaller stored size.

## Hosting

- Serve over http(s); browsers will not load the runtime's modules or workers from file://.
- Content-Security-Policy: allow `worker-src 'self' blob:`.
- Caching: the page files are named by their content and can be cached for a year (`Cache-Control: public, max-age=31536000, immutable`); `element.json`, `t.json` and `m.json` must be revalidated (`no-cache`). Do not gzip the pages again: they are compressed already.
- On a device without GPU-compressed textures `gs.animated` is false: every element shows its still picture and every play() resolves at once. Never make game logic wait on an animation's length.

## Do not

- Do not rename, move or convert files inside `sprites/` or `greatsprites/`.
- Do not draw an element much larger than the height it was loaded at.
- Do not keep every element of the game loaded at once when that goes over the memory line: load and release per scene.
- Do not fetch anything from greatsprites.com at run time.
- Full documentation: https://greatsprites.com/docs

← Getting startedThe API →