npm package: @particlemonkey/runtime
Description: ParticleMonkey runtime — load .pmx effect bundles and drive them procedurally in BabylonJS projects.
Latest version: 0.1.0

# @particlemonkey/runtime

Load `.pmx` particle effect bundles and drive them procedurally in [BabylonJS](https://www.babylonjs.com/) projects.

## Install

```bash
npm install @particlemonkey/runtime
```

### Peer dependencies

You must also have these installed in your project:

```bash
npm install @babylonjs/core jszip
```

## Quick start

```ts
import { PM } from '@particlemonkey/runtime';

const pm = new PM({
  scene,                                    // BabylonJS Scene
  urls: '/assets/effects/fire.pmx',        // .pmx or .psx bundle URL(s)
  systems: {
    FireBurst: { cache: 4 },               // pre-allocate 4 concurrent instances
  },
});

await pm.load();

const fire = pm.getSystem('FireBurst');

// Spawn an instance at a world position
const instance = fire.spawnInstance({ position: { x: 0, y: 1, z: 0 } });
```

## API overview

### `PM`

The main entry point. Accepts one or more bundle URLs (or raw `SystemDef[]`) and a map of system names to pool options.

| Method | Description |
|--------|-------------|
| `load()` | Fetch bundles, resolve dependency graph, allocate GPU pool. Await before calling anything else. |
| `getSystem(name)` | Returns a `SystemHandle` for the named system, or `undefined` if not found. |
| `dispose()` | Stops all systems, revokes object URLs, and frees GPU resources. |

### `SystemHandle`

Controls a particle system and its pool of pre-allocated instances.

| Method / Property | Description |
|-------------------|-------------|
| `spawnInstance(opts?)` | Acquire a pool instance and play it. Returns an `ActiveInstance`. |
| `getEmitter(name)` | Returns an `EmitterHandle` for the named emitter track. |
| `getAnchor(id)` | Returns an `AnchorHandle` for a named anchor node. |
| `getEffector(id)` | Returns an `EffectorHandle` for a named effector. |
| `link(propPath)` | Returns a `LinkHandle` for procedural control of a system-level property. |
| `on(type, handler)` | Subscribe to particle lifecycle events. Returns an unsubscribe function. |

### `ActiveInstance`

A single spawned copy of a system, acquired via `spawnInstance()`.

| Method / Property | Description |
|-------------------|-------------|
| `setPosition(x, y, z)` | Move the instance in world space. |
| `getEmitter(name)` | Returns an `EmitterHandle` scoped to this instance. |
| `link(propPath)` | Returns a `LinkHandle` for procedural control on this instance. |
| `stop()` | Stop and return this instance to the pool. |
| `isStopped` | `true` once the instance has been stopped. |

### `LinkHandle<T>`

Returned by `.link(propPath)` on any handle. Drive a property value each frame:

```ts
const xLink = fire.getEmitter('Flame').link('position.x');
xLink.value = Math.sin(time) * 2;
```

Set `xLink.value = undefined` to restore the bundled animation curve.

### `EmitterHandle` / `AnchorHandle` / `EffectorHandle`

Each exposes a `link(propPath)` method and a `showDebug` toggle. See the source for the full list of linkable property paths per handle type.

## Bundle formats

| Extension | Description |
|-----------|-------------|
| `.pmx` | Full effect bundle — systems, emitters, effectors, textures |
| `.psx` | Scene bundle — multiple `.pmx` effects composed together |

Bundles are created with the [ParticleMonkey editor](https://github.com/Pryme8/bjs-webgpu-particles).

## License

MIT © Pryme8