import { Mesh, Group, DirectionalLight, AmbientLight, HemisphereLight, Scene, Object3D, Vector3, MeshStandardMaterial } from 'three'; import { b as Palette, O as Obstacle } from './types-C_yucwmh.js'; interface TerrainOptions { seed?: number; /** Square side length. Default 80. */ size?: number; /** Vertices per side. Default 96. */ resolution?: number; /** Peak height. Default 6. */ amplitude?: number; /** Noise feature size in world units. Default 28. */ noiseScale?: number; octaves?: number; /** Flatten low areas into meadows (0–1, higher = flatter valleys). Default 0.55. */ valleyFlatness?: number; /** Blend low bands toward sand below (waterLevel + shore margin). */ waterLevel?: number; palette?: Palette; } interface Terrain { mesh: Mesh; /** Exact analytic height at any (x, z) — same function that built the * mesh, so agents/navmesh queries never disagree with the visuals. */ heightAt(x: number, z: number): number; size: number; seed: number; } /** * A seeded low-poly terrain: fractal value noise displacing a plane, with * height/slope-banded vertex colors (grass → high grass → cliff → peak). * The height function is exported, not just baked into vertices — that's * what lets gameplay (spawning, scattering, navmesh baking, agent ground * clamping) agree exactly with what's rendered. */ declare function createTerrain(options?: TerrainOptions): Terrain; interface SkyOptions { topColor?: number; bottomColor?: number; radius?: number; palette?: Palette; } interface Sky { mesh: Mesh; setColors(top: number, bottom: number): void; } /** * A gradient sky dome (vertical color blend on an inverted sphere). * Colors default to the palette, so themed scenes get matching skies. */ declare function createSky(options?: SkyOptions): Sky; type LightingPreset = 'day' | 'golden-hour' | 'overcast' | 'night'; interface LightingRig { group: Group; sun: DirectionalLight; ambient: AmbientLight; hemisphere: HemisphereLight; } /** * The three lights every scene rebuilds, as a preset: warm directional * "sun" (position doubles as light direction), ambient fill, and a * hemisphere tint. Retune any of them via the returned rig. */ declare function createLightingRig(preset?: LightingPreset): LightingRig; type FogPreset = 'clear' | 'haze' | 'thick' | 'eerie'; /** Distance fog matched to the palette's fog color. 'clear' removes it. */ declare function applyFog(scene: Scene, preset: FogPreset, palette?: Palette): void; interface WaterOptions { /** World-space water surface height. Default 0.8. */ level?: number; size?: number; resolution?: number; /** Wave height. Default 0.06. */ amplitude?: number; /** Wave speed multiplier. Default 1. */ speed?: number; palette?: Palette; } interface Water { mesh: Mesh; level: number; /** Advance the wave animation. Call from your frame loop. */ update(dt: number): void; /** Is ground at this height below the surface? */ isUnderwater(groundHeight: number): boolean; } /** * A low-poly animated water plane at a fixed level. Pair it with a * terrain built using the same `waterLevel` so shores blend to sand, and * keep scatter/agents ashore with `aboveWater(terrain, water)`. */ declare function createWater(options?: WaterOptions): Water; /** * A scatter mask keeping placements on dry land: true when the terrain * at (x, z) sits above the water level plus `margin`. */ declare function aboveWater(terrain: Terrain, water: Pick, margin?: number): (x: number, z: number) => boolean; interface DayCycleOptions { sky?: Sky; rig?: LightingRig; /** Scene whose fog color should track the cycle. */ scene?: Scene; /** Lamp props/objects whose PointLights + glow bulbs ignite at night. */ lamps?: Array<{ object: Object3D; } | Object3D>; palette?: Palette; /** Seconds per full day. Default 60. */ dayLength?: number; /** Initial time: 0 = midnight, 0.25 = dawn, 0.5 = noon, 0.75 = dusk. */ timeOfDay?: number; } interface DayCycle { timeOfDay: number; /** Sun elevation in [-1, 1]; negative = below the horizon. */ readonly sunElevation: number; readonly isNight: boolean; /** Advance by dt seconds of real time and re-apply everything. */ update(dt: number): void; /** Jump to a time of day and re-apply everything. */ set(t: number): void; } /** * One `timeOfDay` parameter driving the whole environment in lockstep: * sun position/color/intensity, sky gradient, ambient level, fog color, * and lamps that ignite as the sun drops below the horizon. * * ```ts * const cycle = createDayCycle({ sky, rig, scene, lamps: [lampA, lampB], dayLength: 120 }); * game.onUpdate((t) => cycle.update(t.delta)); * ``` */ declare function createDayCycle(options?: DayCycleOptions): DayCycle; interface PathOptions { /** Ribbon width. Default 1.8. */ width?: number; /** Ground height lookup; a number means flat ground. Default 0. */ surface?: number | ((x: number, z: number) => number); /** Samples per world unit of path length. Default 1. */ samplesPerUnit?: number; /** Close the path into a loop. Default false. */ loop?: boolean; /** Extra clearance added to scatter keep-out circles. Default 0.6. */ keepOutMargin?: number; palette?: Palette; } interface WorldPath { mesh: Mesh; /** Smoothed centerline draped on the surface — feed straight into a * GAMA `Path` for patrols, or use as camera dolly points. */ route: Vector3[]; /** Keep-out circles for `scatter()` so nothing grows on the road. */ keepOut: Array<{ center: { x: number; z: number; }; radius: number; }>; /** Is (x, z) on the path surface? (e.g. to exclude grass) */ contains(x: number, z: number): boolean; loop: boolean; } /** * A dirt path: a Catmull-Rom-smoothed ribbon draped over the surface. * One authored polyline feeds three things at once — the visual ribbon, * scatter keep-out, and a patrol route for agents. That's the SCENA * handshake applied to level design. * * ```ts * const road = createPath([a, b, c], { surface: terrain.heightAt, loop: true }); * scene.add(road.mesh); * scatter({ ..., keepOut: road.keepOut }); * agent.addBehavior(new FollowPath(new Path(road.route, road.loop), 1.5)); * ``` */ declare function createPath(points: Array, options?: PathOptions): WorldPath; interface RoomOptions { seed?: number; /** Cell size override. Default KIT_UNIT. */ unit?: number; /** Wall height. Default 3. */ wallHeight?: number; /** Build a ceiling slab (with beams). Default true. */ ceiling?: boolean; /** Floor finish. Default 'plank' (floorboards); 'stone' for flagstones. */ floor?: 'plank' | 'stone'; /** Give each hearth a real flickering PointLight. Default true. */ hearthLight?: boolean; palette?: Palette; } /** A window opening in a room wall. */ interface RoomWindow { /** Center of the opening at the interior wall face (room-local). */ position: Vector3; /** Unit vector pointing from the window INTO the room. */ normal: Vector3; /** Opening width / height in world units. */ width: number; height: number; /** The daylight pane material — `createInteriorLight` brightens/dims it. */ pane: MeshStandardMaterial; } /** A fireplace built into a room wall. */ interface RoomHearth { /** Cell center of the hearth (room-local, y = 0). */ position: Vector3; /** Unit vector pointing from the hearth INTO the room. */ normal: Vector3; } /** * A clear run of interior wall — somewhere to hang things. * * Runs are **merged**: five wall cells in a line become one 6 m wall, not * five 1.2 m panels, because "hang a picture halfway along the north wall" * is the question anyone actually has. A window or a hearth splits a run, * since you cannot hang a picture over either. * * Structurally a `HangSurface`, so it goes straight into `hangOn`. */ interface RoomWall { /** * Anchor at the wall face, floor level, centred on the run: **+z points * into the room, +x runs along the wall, +y is up**. Already parented into * the room group. */ anchor: Object3D; /** Centre of the run at the interior face, room-local, y = 0. */ position: Vector3; /** Unit vector pointing from the wall INTO the room. */ normal: Vector3; /** Length of the clear run, in world units. */ length: number; /** Wall height, in world units. */ height: number; } interface Room { group: Group; /** One obstacle per wall/window/hearth cell — feed GAMA's ObstacleAvoidance. */ obstacles: Obstacle[]; /** World positions of 'S' cells (player/NPC spawn points). */ spawns: Vector3[]; /** Window openings — `createInteriorLight` turns these into light shafts. */ windows: RoomWindow[]; /** Fireplaces (already burning; their light honors `hearthLight`). */ hearths: RoomHearth[]; /** Clear interior wall runs, longest first — feed these to `hangOn`. */ walls: RoomWall[]; /** Centers of '~' rug cells (a woven rug is already laid on each). */ rugs: Vector3[]; /** Centers of 'D' doorway cells — `furnishRoom` keeps them clear. */ doors: Vector3[]; /** The grid cell size this room was built on. */ unit: number; /** Is (x, z) over a walkable floor cell? */ floorAt(x: number, z: number): boolean; /** Footprint in world units: { width, depth } centered on the origin. */ size: { width: number; depth: number; }; /** * Show/hide the whole interior (geometry AND its real lights) in one call — * the cheap culling switch for stepping outdoors. */ setActive(active: boolean): void; } /** * Assemble a furnished-ready interior from an ASCII map — the indoor * counterpart of `assembleKit`, sharing its grid, its cell vocabulary and its * `Kit`-shaped gameplay data, then adding what a room needs to feel indoors: * a beamed ceiling, plastered walls over floorboards, window openings that * know which way they face, and a burning hearth. * * - `#` wall block (blocks movement, becomes an obstacle) * - `.` floor tile * - `D` doorway: floor + lintel spanning the gap overhead * - `W` window: wall with an opening (sill + header), recorded in `windows` * - `H` hearth: wall cell replaced by a burning fireplace * - `T` floor + standing torch * - `S` floor + recorded spawn point * - `~` floor + woven rug * - ` ` nothing * * ```ts * const cottage = createRoom([ * '##H##', * 'W...W', * '#.~.#', * '#.S.#', * '##D##', * ], { palette }); * scene.add(cottage.group); * cottage.group.add(createInteriorLight(cottage).group); // daylight shafts * ``` * * The architecture renders as a handful of InstancedMeshes regardless of map * size; only windows, hearths, rugs and torches add individual meshes. */ declare function createRoom(rows: string[], options?: RoomOptions): Room; export { type DayCycle as D, type FogPreset as F, type LightingPreset as L, type PathOptions as P, type Room as R, type Sky as S, type Terrain as T, type Water as W, type DayCycleOptions as a, type LightingRig as b, type RoomHearth as c, type RoomOptions as d, type RoomWall as e, type RoomWindow as f, type SkyOptions as g, type TerrainOptions as h, type WaterOptions as i, type WorldPath as j, aboveWater as k, applyFog as l, createDayCycle as m, createLightingRig as n, createPath as o, createRoom as p, createSky as q, createTerrain as r, createWater as s };