import { type ParamLayer, type LayerSelection } from "./paramLayers.js"; /** * A selectable rule over a tagged pool. `tags` classify it for include/exclude filtering and for * `requires`/`conflicts` matching (which match either another rule's id or one of its tags). `layers` * are the parameter layers this rule contributes when active; `payload` is opaque caller data. */ export interface RuleDef { readonly id: string; readonly tags?: readonly string[]; /** Relative pick weight; non-positive or omitted is treated as `1`. */ readonly weight?: number; /** Ids/tags that must already be selected for this rule to become eligible. */ readonly requires?: readonly string[]; /** Ids/tags that, if already selected (either direction), make this rule ineligible. */ readonly conflicts?: readonly string[]; /** Parameter layers contributed when this rule is active, read back via {@link RuleRegistry.layersFor}. */ readonly layers?: readonly ParamLayer[]; readonly payload?: TPayload; } /** Deterministic selection inputs — plain serializable data a host can persist and replay. */ export interface RuleSelectionConfig { readonly count: number; readonly seed: string | number; /** If set, only rules carrying at least one of these tags are eligible. */ readonly includeTags?: readonly string[]; /** Rules carrying any of these tags are excluded outright. */ readonly excludeTags?: readonly string[]; /** Rule ids force-selected first, in order; counts toward `count`. Unknown ids are ignored. */ readonly locked?: readonly string[]; } /** The result of a selection — the chosen rules and their ids (a serializable {@link LayerSelection}-style list). */ export interface RuleSelection { readonly rules: readonly RuleDef[]; readonly ids: readonly string[]; } /** * Select up to `count` rules from `pool` deterministically from `config.seed`. Locked ids are placed * first (in order), then remaining slots are filled by weighted draw from tag-filtered, still-eligible * candidates, honoring `requires`/`conflicts` after each pick. Each slot draws from an independent * seed stream keyed by slot index, so a later slot's outcome never shifts an earlier one. Selection * stops early when no compatible candidate remains. Pure given `pool` + `config`. * * @capability rule-selection deterministically select rules from a tagged pool under compatibility/exclusion constraints */ export declare function selectRules(pool: readonly RuleDef[], config: RuleSelectionConfig): RuleSelection; /** * Reroll a prior selection: keep `keepIds` (the locked slots) and re-draw the rest under a fresh, * still-deterministic stream derived from `config.seed` and `salt`. The same seed + salt + keep set * reproduce the same reroll, so reroll history stays replayable. * * @capability rule-selection reroll unlocked slots of a selection deterministically from seed and salt */ export declare function rerollRules(pool: readonly RuleDef[], config: RuleSelectionConfig, keepIds: readonly string[], salt?: string | number): RuleSelection; /** Registered pool of {@link RuleDef}s — the install seam games register mutators/modes/events into. */ export interface RuleRegistry { register(rule: RuleDef): void; has(id: string): boolean; get(id: string): RuleDef | undefined; all(): readonly RuleDef[]; /** Run {@link selectRules} over the registered pool. */ select(config: RuleSelectionConfig): RuleSelection; /** * Collect the parameter layers contributed by the given selected rule ids, in id order. Unknown ids * are skipped so stale/migrated selections resolve without throwing. This is the bridge from a * rule selection to a {@link ParamLayer} stack — core reads `.layers`, never a rule's name. */ layersFor(ids: LayerSelection): readonly ParamLayer[]; } /** * Create a {@link RuleRegistry}. Rules install through `register` (duplicate ids throw); selection and * `layersFor` are data-driven, so the core never branches on which mutators exist. * * @capability rule-selection register rules and bridge a selection to its contributed parameter layers */ export declare function createRuleRegistry(initial?: readonly RuleDef[]): RuleRegistry;