import type { ParticleAttachOptions, ParticleBlendHint, ParticleRenderHint } from "./particleDirector.js"; import type { EmitterConfig, Vec3 } from "./particles.js"; /** The family an effect belongs to; groups the library browser and the contact sheet. */ export type EffectGroup = "fire" | "smoke" | "sparks" | "dust" | "splash" | "muzzle" | "explosion" | "magic" | "weather"; /** * The procedural sprite family a particle draws with on the GPU path. Each family maps to a * {@link ParticleRenderHint} shape: `soft` puffs, velocity-stretched `spark` streaks, `flake` * crystals, `flame` tongues, `smoke` puffs, connected `ribbon` trails and flat `ring` ripples. * There is no image file to load or credit — the field is the authored name for the sprite. */ export type EffectTexture = "soft" | "spark" | "flake" | "flame" | "smoke" | "ribbon" | "ring"; /** * One named effect a game or the editor plays by name. Every field is data: the `config` is the * same `EmitterConfig` a hand-authored emitter uses, so a library effect serializes, retunes and * renders on the existing pooled GPU path without a second implementation. */ export interface ParticleEffect { /** Stable name, e.g. `fire/flame`. Names are the data contract; configs are not. */ name: string; /** Human label for pickers and contact sheets. */ title: string; group: EffectGroup; /** * Drop order under the graphics-tier particle budget: higher survives, lower is dropped first. * Gameplay-loud effects (explosions, muzzle flashes) outrank ambient dressing (dust, weather). */ priority: number; /** `continuous` emits from `rate`; `burst` emits `burst` particles per play. */ mode: "continuous" | "burst"; /** Particles emitted per one-shot `play`, and the pool size a standing emitter may reach. */ burst: number; texture: EffectTexture; /** Velocity streak length in seconds for `spark`/`ribbon` textures. Default 0.08. */ stretch?: number; blending: ParticleBlendHint; config: EmitterConfig; /** Attachment defaults (follow, offset, space, collision child, environment influence). */ options?: Omit; } /** Ambient dressing drops first, then gameplay-loud effects last. */ export declare const EFFECT_PRIORITY: { readonly weather: 20; readonly dust: 40; readonly smoke: 60; readonly magic: 70; readonly sparks: 70; readonly fire: 80; readonly splash: 80; readonly muzzle: 90; readonly explosion: 90; }; /** * The shared library of named particle effects: fire, smoke, sparks, dust, splashes, muzzle flash, * explosions, magic and weather. Each entry is authored parameters only — rate, lifetime, size, * colour and the sprite texture — so a game calls `ctx.particles.play("explosion/core", at)` and * the editor authors the same name instead of hand-tuning an `EmitterConfig`. Names are the * contract; a config retune here changes every consumer deliberately. */ export declare const EFFECT_LIBRARY: readonly ParticleEffect[]; /** The fallback effect used when a play call names an unknown effect — a typo still shows a spark. */ export declare const DEFAULT_EFFECT = "sparks/weld"; /** Every library effect name, for editor pickers and runtime discovery. */ export declare function effectNames(): readonly string[]; /** The named effect, or `undefined` when the name is not in the library. * @capability find-effect look up one named particle effect in the shared library, or undefined when unknown */ export declare function findEffect(name: string): ParticleEffect | undefined; /** Per-call overrides merged over a library effect; each field wins over the authored default. */ export interface EffectOverride { config?: Partial; options?: Partial; /** World position, or the standing emitter's origin when it does not follow an entity. */ position?: Vec3; /** One-shot particle count; overrides the effect's authored `burst`. */ burst?: number; } /** A library effect resolved into the exact data the director and renderer consume. */ export interface ResolvedEffect { name: string; group: EffectGroup; mode: ParticleEffect["mode"]; priority: number; /** Particles a one-shot `play` emits. */ burst: number; config: EmitterConfig; render: ParticleRenderHint; blending: ParticleBlendHint; /** Attach options including the resolved `priority`, ready for the director. */ options: ParticleAttachOptions; } /** * Resolve a named effect into concrete emitter data, with any `override` winning field by field. * An unknown name resolves to {@link DEFAULT_EFFECT} rather than throwing, so a typo shows * *something*; call {@link findEffect} when the caller must reject an unknown name. * * @capability effect-resolve turn a named library effect into emitter config, GPU sprite texture, blending and budget priority with per-call overrides */ export declare function resolveEffect(name: string, override?: EffectOverride): ResolvedEffect;