UNPKG

ecspresso

Version:

A minimal Entity-Component-System library for typescript and javascript.

98 lines (97 loc) 4.19 kB
/** * 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>;