import { Scene, TransformNode } from '@babylonjs/core'; import { GameEngine } from "../classes/gameEngine.d.ts"; import { ColliderDebugConfig } from "../managers/colliderDebug.d.ts"; import { LoggingUtility } from "../utils/logger.d.ts"; /** * Minimal interface for Level that property handlers receive. * This avoids circular dependencies while still providing access to level functionality. */ export interface LevelInstance { readonly name: string; /** The current scene for this level (null if not loaded) */ readonly scene: Scene | null; /** * Dispose of this level's resources and scene. */ $dispose(): Promise; } /** * Handler function for processing custom properties on scene nodes. */ export type PropertyHandler = (node: TransformNode, value: unknown, level: LevelInstance, gameEngine: GameEngine) => void | Promise; /** * Runtime context containing all dependencies needed by a Level. * Passed to Level constructor by LevelManager during instantiation. */ export interface LevelContext { /** The game engine instance providing access to all subsystems */ gameEngine: GameEngine; /** Map of property handlers for processing scene node metadata */ propertyHandlers: Map; /** Optional logging utility for creating level-specific loggers */ logger?: LoggingUtility; } /** * Definition for spawning an entity at a spawn point */ export interface SpawnDefinition { /** The entity type name to spawn */ entity: string; /** Optional human-readable name for the spawned entity instance. */ name?: string; /** Tags to apply to the spawned entity (merged with definition tags). */ tags?: string[]; /** Additional configuration passed to the entity's initial state */ config?: Record; /** Debug collider visualization config. Overrides the entity definition's debugCollider. */ debugCollider?: ColliderDebugConfig; } /** * Definition for entity types found in the scene. * Used to configure entities that are marked with the 'entity' property in scene files. */ export interface EntityDefinition { /** Optional name override for the entity (overrides the scene node name). */ name?: string; /** Tags to apply to the entity (merged with definition tags). */ tags?: string[]; /** Additional configuration passed to the entity's initial state */ config?: Record; /** Debug collider visualization config. Overrides the entity definition's debugCollider. */ debugCollider?: ColliderDebugConfig; } /** * Configuration for loading a scene file. * Can be a simple string path (backward compatible) or an object with options. */ export interface SceneConfig { /** Path to the scene file (.glb, .gltf, .babylon, etc.) */ path: string; /** * Whether the scene data is in a right-handed coordinate system. * When true, sets `scene.useRightHandedSystem = true` before loading, * which tells BabylonJS to interpret all coordinates as right-handed. * Typically needed for .babylon files exported from Blender. */ rightHanded?: boolean; } /** * Configuration for a game level loaded from YAML */ export interface LevelConfig { /** The name of the level */ name: string; /** Scene file path, or configuration object with path and options */ scene?: string | SceneConfig; /** Name of a registered custom Level class to use instead of GameLevel */ class?: string; /** Configuration passed to custom Level class */ config?: Record; /** * Spawn point definitions. * Keys match the 'spawn' property values in the scene file. */ spawns?: Record; /** * Entity type definitions. * Keys match the 'entity' property values in the scene file. */ entities?: Record; /** * Physics configuration for this level. * If true, enables physics with default gravity (-9.81). * If an object, can specify custom gravity. */ physics?: boolean | { gravity?: Vec3Config; }; /** Asset paths to preload before building the scene */ preload?: string[]; /** Environment configuration (skybox and IBL lighting) */ environment?: EnvironmentConfig; /** Camera configuration. Keys match Blender camera names (override) or define new cameras (create). */ cameras?: Record; /** Light configuration. Keys match Blender light names (override) or define new lights (create). */ lights?: Record; /** Level-scoped sound configuration. Sounds are paused/resumed with level lifecycle. */ sounds?: Record; /** Post-processing effects configuration */ postProcessing?: PostProcessingConfig; /** Clustered lighting configuration for many-light scenes */ clustering?: ClusteringConfig; /** Named outline layers for entity highlighting */ outlines?: Record; } /** * Reusable 3D vector config for positions, directions, and rotations. */ export interface Vec3Config { x: number; y: number; z: number; } /** * Reusable quaternion config for rotations. */ export interface QuatConfig { x: number; y: number; z: number; w: number; } /** * Reusable RGB color config. */ export interface ColorConfig { r: number; g: number; b: number; } /** * Configuration for a single camera. If `type` is present, a new camera is created. * If `type` is omitted, properties are applied as overrides to a Blender-imported camera. */ export interface CameraDefinition { /** Camera type (required for create mode, omit for override mode) */ type?: 'free' | 'arcRotate' | 'universal' | 'geospatial'; /** Mark as the active camera for this level */ active?: boolean; /** Attach canvas input controls */ attachControl?: boolean; /** Camera position (create mode) */ position?: Vec3Config; /** Camera look-at target (create mode; arcRotate) */ target?: Vec3Config; /** Camera rotation in radians (create mode; free/universal) */ rotation?: Vec3Config; fov?: number; minZ?: number; maxZ?: number; speed?: number; alpha?: number; beta?: number; radius?: number; lowerRadiusLimit?: number; upperRadiusLimit?: number; lowerBetaLimit?: number; upperBetaLimit?: number; wheelPrecision?: number; planetRadius?: number; yaw?: number; pitch?: number; center?: Vec3Config; checkCollisions?: boolean; radiusMin?: number; radiusMax?: number; pitchMin?: number; pitchMax?: number; yawMin?: number; yawMax?: number; } /** * Configuration for a single light. If `type` is present, a new light is created. * If `type` is omitted, properties are applied as overrides to a Blender-imported light. */ export interface LightDefinition { /** Light type (required for create mode, omit for override mode) */ type?: 'hemispheric' | 'directional' | 'point' | 'spot' | 'rectarea'; intensity?: number; diffuse?: ColorConfig; specular?: ColorConfig; position?: Vec3Config; direction?: Vec3Config; groundColor?: ColorConfig; angle?: number; exponent?: number; width?: number; height?: number; } /** * Configuration for the scene environment: skybox visuals and IBL (image-based lighting) for PBR reflections. * * - `ibl` alone: sets PBR reflection source, no visible skybox * - `skybox` alone with HDR/env: used for both IBL and visible skybox * - `skybox` alone with JPG/PNG: visible skybox sphere, no IBL * - Both `ibl` and `skybox`: separate IBL source and visible skybox (recommended for quality) */ export interface EnvironmentConfig { /** HDR or env file for PBR reflections (IBL) */ ibl?: string; /** IBL cubemap resolution in pixels (default 256) */ iblResolution?: number; /** Skybox texture path. HDR/env creates a cubemap skybox; JPG/PNG creates a textured sphere. */ skybox?: string; /** Skybox sphere diameter (default 1000). Only applies to JPG/PNG sphere skyboxes. */ skyboxSize?: number; /** Y-axis rotation in radians for the environment texture */ rotation?: number; } /** * Configuration for a level-scoped sound. Sounds are created when the level loads, * paused on deactivate, resumed on activate, and disposed on unload. */ export interface LevelSoundConfig { /** Path to the audio file */ url: string; /** Audio channel name (e.g., 'music', 'sfx', 'ambient') */ channel?: string; /** Whether to loop the sound (default false) */ loop?: boolean; /** Whether to start playing when the level loads (default false) */ autoplay?: boolean; /** Volume level 0-1 (default 1) */ volume?: number; } /** * Configuration for post-processing effects applied to a level's scene. */ export interface PostProcessingConfig { /** * Rendering backend. 'pipeline' uses DefaultRenderingPipeline, 'frameGraph' uses Frame Graph. * Default: 'pipeline'. */ renderer?: 'pipeline' | 'frameGraph'; bloom?: { weight?: number; threshold?: number; scale?: number; kernel?: number; }; ssao?: { radius?: number; samples?: number; totalStrength?: number; }; tonemap?: { operator?: 'hable' | 'reinhard' | 'hejidawson' | 'photographic' | 'aces'; }; chromaticAberration?: { amount?: number; }; grain?: { intensity?: number; animated?: boolean; }; vignette?: { weight?: number; stretch?: number; color?: { r: number; g: number; b: number; }; }; sharpen?: { edge?: number; color?: number; }; /** Volumetric lighting (Frame Graph only). Warns if used with pipeline renderer */ volumetric?: { extinction?: number; scattering?: number; }; } /** * Configuration for clustered lighting. When enabled, all eligible point and spot lights * are rendered via a screen-space clustering system for improved multi-light performance. * Hemispheric, directional, and rect area lights are unaffected. */ export interface ClusteringConfig { enabled: boolean; horizontalTiles?: number; verticalTiles?: number; depthSlices?: number; maxRange?: number; } /** * Configuration for a named selection outline layer. * Defines the visual style for screen-space entity outlines. */ export interface OutlineLayerConfig { color?: ColorConfig; thickness?: number; occlusionStrength?: number; } /** * Constructor signature for Level classes. * All Level subclasses must accept (config, context) parameters. */ export type LevelConstructor = new (config: LevelConfig, context: LevelContext) => LevelInstance;