import type { Aabb, Vec2 } from "../world/geometry.js"; import type { EditorDirective, EditorDirectiveKind, EditorDocument, EditorPopulationDirective, EditorScatterDirective } from "./types.js"; /** * The deterministic materializer for scene {@link EditorDirective}s — the bake side of the * bake/patch seam in #985. A directive is one authored line ("scatter rocks across the north * ridge"); this expands it into many placements with **stable per-instance ids** (`# * `) so a sparse overlay can hand-tweak or delete individual instances by id without every * re-materialize orphaning those edits. Fully deterministic: same directive + seed + region ⇒ the * same field, every time (safe for verify/CI). Built on the existing `scatter` primitive. */ /** One materialized placement from a directive — grounded XZ, deterministic scale/yaw, stable id. */ export interface MaterializedInstance { /** Stable id `#` — the key an overlay patches or deletes. */ id: string; /** The directive that minted this instance. */ directiveId: string; kind: EditorDirectiveKind; /** What to place: a `scatter` directive's catalog asset, or a `population` directive's species id. */ asset: string; x: number; z: number; /** Vertical offset in meters (0 unless an overlay sets it); grounding on terrain stays the caller's job. */ y: number; rotationY: number; scale: number; } /** A resolved directive footprint: the XZ bounds to scatter within, plus an optional clip polygon. */ export interface DirectiveFootprint { area: Aabb; polygon?: Vec2[]; } /** * Resolves the footprint a directive fills: an explicit `area`, else the footprint of the named * `region` — a scatter/closed path (as a clip polygon) or a volume (its XZ AABB). Null when neither * is present or the region id does not resolve. * @capability world-directives resolve a directive's region footprint from the scene document */ export declare function resolveDirectiveFootprint(doc: EditorDocument, directive: EditorDirective): DirectiveFootprint | null; /** * Materializes a scatter directive into deterministic catalog-prop placements across its footprint, * clipped to the region polygon when one is present. Per-instance scale and yaw derive from the * directive id + seed + point index, so ids are stable across re-materializes. * @capability world-directives materialize a scatter directive into placements */ export declare function materializeScatterDirective(directive: EditorScatterDirective, footprint: DirectiveFootprint): MaterializedInstance[]; /** * Materializes a population directive into deterministic mob spawn placements: at most `cap` of each * weighted species, distributed across the footprint. Each placement carries a stable id and its * species id in `asset`, ready to feed `ctx.scene.entity.spawn` / `ai/populationDirector`. * @capability world-directives materialize a population directive into spawns */ export declare function materializePopulationDirective(directive: EditorPopulationDirective, footprint: DirectiveFootprint): MaterializedInstance[]; /** * Materializes one directive against a document, resolving its footprint first. Returns an empty * list when the region does not resolve. * @capability world-directives materialize one scene directive into instances */ export declare function materializeDirective(doc: EditorDocument, directive: EditorDirective): MaterializedInstance[]; /** A per-instance hand-tweak over a materialized directive, keyed by the minted instance id. */ export interface DirectiveInstancePatch { /** Override the placement's XZ position. */ position?: { x: number; z: number; }; /** Override the vertical offset. */ y?: number; scale?: number; rotationY?: number; /** Remove this instance from the materialized set. */ deleted?: boolean; } /** * A sparse overlay over one directive's materialized instances — the "nudge *that one* rock" answer. * Hand-edits are keyed by the stable instance id the materializer mints, so they survive re-bakes. */ export interface EditorDirectiveOverlay { /** The directive id whose instances this overlay patches. */ over: string; patches: Record; } /** * Applies a directive overlay to its materialized instances: patched fields override, `deleted` * drops the instance. Instances with no patch pass through untouched. * @capability world-directives apply a sparse overlay over materialized directive instances */ export declare function applyDirectiveOverlay(instances: readonly MaterializedInstance[], overlay: EditorDirectiveOverlay): MaterializedInstance[]; /** * Materializes every directive on a document into one flat instance list, applying each directive's * overlay (matched by `over` === directive id) as it goes. The bulk-content counterpart to * `resolveAuthoredObjects` / `resolveScatter`: games and headless tests read the same list. * @capability world-directives materialize all scene directives with their overlays */ export declare function materializeDirectives(doc: EditorDocument, overlays?: readonly EditorDirectiveOverlay[]): MaterializedInstance[];