ecspresso
Version:
A minimal Entity-Component-System library for typescript and javascript.
98 lines (97 loc) • 4.19 kB
TypeScript
/**
* Flocking Plugin for ECSpresso
*
* Classic boid simulation — separation, alignment, cohesion. Produces
* emergent group movement from simple per-entity steering forces.
*
* Composes with the physics2D plugin: flocking computes steering forces
* and feeds them through `applyForce()`. Physics integration handles
* velocity and position updates.
*
* Requires the spatial-index plugin for efficient neighbor queries.
* Entities must have a `circleCollider` (or `aabbCollider`) to appear
* in spatial index queries.
*/
import { type BasePluginOptions } from 'ecspresso';
import type { ComponentsConfig, ResourcesConfig } from 'ecspresso';
import type { TransformWorldConfig } from '../spatial/transform';
import type { Physics2DOwnComponentTypes } from '../physics/physics2D';
import type { SpatialIndexResourceTypes } from '../spatial/spatial-index';
/**
* Configures flocking behavior for a boid entity.
*
* Entities with this component must also have:
* - `localTransform` + `worldTransform` (transform plugin)
* - `velocity` + `force` + `rigidBody` (physics2D plugin)
* - `circleCollider` with radius >= perceptionRadius (for spatial index queries)
*/
export interface FlockingAgent {
/** Radius within which neighbors are detected */
perceptionRadius: number;
/** Separation weight — steer away from nearby neighbors (default: 1.5) */
separationWeight: number;
/** Alignment weight — match average heading of neighbors (default: 1.0) */
alignmentWeight: number;
/** Cohesion weight — steer toward average position of neighbors (default: 1.0) */
cohesionWeight: number;
/** Maximum steering force magnitude per frame */
maxForce: number;
/** Maximum velocity magnitude (hard speed cap) */
maxSpeed: number;
/** Flock group ID for independent flocks (default: 0) */
flockGroup: number;
}
/**
* Component types provided by the flocking plugin.
*/
export interface FlockingComponentTypes {
flockingAgent: FlockingAgent;
}
/**
* WorldConfig representing the flocking plugin's provided types.
*/
export type FlockingWorldConfig = ComponentsConfig<FlockingComponentTypes>;
export interface FlockingPluginOptions<G extends string = 'ai'> extends BasePluginOptions<G> {
/** Priority for the heading/speed-clamp system (default: 200) */
headingPriority?: number;
}
/**
* Create a flockingAgent component with sensible defaults.
*
* Entities must also have a `circleCollider` with radius >= perceptionRadius
* for the spatial index to find them as neighbors.
*
* @param options Partial overrides for flocking agent fields
* @returns Component object suitable for spreading into spawn()
*
* @example
* ```typescript
* ecs.spawn({
* ...createFlockingAgent({ perceptionRadius: 80, maxSpeed: 150 }),
* ...createRigidBody('dynamic', { mass: 1, drag: 1, gravityScale: 0 }),
* ...createCircleCollider(80),
* ...createGraphicsComponents(boidGraphics, { x: 100, y: 200 }),
* });
* ```
*/
export declare function createFlockingAgent(options?: Partial<FlockingAgent>): Pick<FlockingComponentTypes, 'flockingAgent'>;
/**
* Create a flocking plugin for ECSpresso.
*
* Installs two systems:
* - `flocking-forces` — computes separation/alignment/cohesion and applies via applyForce()
* - `flocking-heading` — clamps speed to maxSpeed and orients rotation to match velocity
*
* Requires the transform, physics2D, and spatial-index plugins to be installed.
*
* @example
* ```typescript
* const ecs = ECSpresso.create()
* .withPlugin(createRenderer2DPlugin({ background: '#0a0a2e' }))
* .withPlugin(createPhysics2DPlugin())
* .withPlugin(createSpatialIndexPlugin())
* .withPlugin(createFlockingPlugin())
* .build();
* ```
*/
export declare function createFlockingPlugin<G extends string = 'ai'>(options?: FlockingPluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithComponents<import("ecspresso").EmptyConfig, FlockingComponentTypes>, TransformWorldConfig & ComponentsConfig<Pick<Physics2DOwnComponentTypes, "force" | "velocity">> & ResourcesConfig<SpatialIndexResourceTypes>, "flocking-forces" | "flocking-heading", G, never, never>;