import { type DecayMeterConfig } from "../survival/decayMeter.js"; /** * A decaying need is a survival decay meter (`max`/`min`/`start`/`rate`, optional moodle * thresholds) whose satisfaction an agent brain reads to score actions. The meter owns the * numbers; per-need appeal lives in the game's utility options. */ export type NeedDefinition = DecayMeterConfig; /** One need's current satisfaction, worst-first ready: `fraction` is 0 (empty) … 1 (full). */ export interface NeedReading { id: string; value: number; fraction: number; } /** Serializable need state: values plus any in-play retuning, so a save keeps the dials. */ export interface NeedSnapshot { /** Satisfaction per need id; undeclared ids are ignored on restore. */ values: Record; /** Base rates after `setRate`; absent entries keep the definition's rate. */ rates: Record; /** Active per-need rate multipliers from `setRateModifier`. */ modifiers: Record; } /** * Named needs that drain or recover on game time — hunger, energy, hygiene, bladder, fun. * Reads are index-addressed (`indexOf` once, `fractionAt` per tick) so a thousand-agent loop * never re-resolves ids; the whole set round-trips through {@link NeedSnapshot}. */ export interface NeedSet { /** Drain every need by `rate * modifier * dt` in place. Call once per game tick. */ tick(dt: number): void; /** Declared ids in definition order. */ ids(): readonly string[]; /** Stable index for a declared need, or `-1`. Resolve once, then use the `*At` readers. */ indexOf(id: string): number; /** Raw value at `indexOf(id)` — no allocation, no lookup. */ valueAt(index: number): number; /** 0..1 fill at `indexOf(id)` — what response curves sample. */ fractionAt(index: number): number; value(id: string): number; fraction(id: string): number; /** Consumable/action refill; negative drains. Throws on an unknown id. */ refill(id: string, amount: number): void; /** Overwrite one need's base rate (a harsher game mode). Throws on an unknown id. */ setRate(id: string, rate: number): void; /** Multiply one need's drain until cleared with `1`; `null` sets every need at once. */ setRateModifier(id: string | null, multiplier: number): void; /** Least-satisfied need by fraction, declared order breaking ties; `null` when none declared. */ mostUrgent(): NeedReading | null; snapshot(): NeedSnapshot; restore(next: NeedSnapshot): void; } /** * Create the needs an agent or a park guest carries. Decay reuses the survival meter formulas * (`survival/decayMeter`), so moodle thresholds, clamping and rate modifiers behave exactly like * every other meter; this set adds index-addressed reads and single-need retuning for hot AI loops. * Score these needs into an action with `createUtilityBrain` (`@jgengine/core/world`). * * @capability needs decaying needs an agent reads by index to decide what it wants next */ export declare function createNeedSet(definitions: readonly NeedDefinition[]): NeedSet;