nightshade 0.13.2

A cross-platform data-oriented game engine.
Documentation
//! ECS world definition and component/resource re-exports.
//!
//! The [`World`] struct is the central data store for all game state, generated by
//! the `freecs::ecs!` macro. It contains:
//!
//! - **Entities**: Created with `world.spawn_entities(flags, count)`, identified by [`Entity`] (u64)
//! - **Components**: Bitflag-selected data (e.g., `LOCAL_TRANSFORM | RENDER_MESH`)
//! - **Resources**: Global singletons accessed via `world.resources`
//!
//! Key resource paths:
//!
//! - `world.resources.window.timing` — frame timing ([`WindowTiming`](resources::WindowTiming))
//! - `world.resources.input` — keyboard/mouse/touch state ([`Input`](resources::Input))
//! - `world.resources.graphics` — rendering settings ([`Graphics`](resources::Graphics))
//! - `world.resources.active_camera` — current camera entity
//! - `world.resources.entity_names` — name-to-entity mapping

pub mod components {
    pub use crate::ecs::animation::components::{
        AnimationChannel, AnimationClip, AnimationInterpolation, AnimationPlayer,
        AnimationProperty, AnimationSampler, AnimationSamplerOutput, AnimationValue,
    };
    pub use crate::ecs::audio::components::{AudioListener, AudioSource};
    pub use crate::ecs::bounding_volume::components::{BoundingVolume, OrientedBoundingBox};
    pub use crate::ecs::camera::components::{
        Camera, OrthographicCamera, PanOrbitCamera, PerspectiveCamera, Projection, Smoothing,
    };

    pub use crate::ecs::decal::components::Decal;
    pub use crate::ecs::grass::components::{
        GrassConfig, GrassInteractor, GrassRegion, GrassSpecies,
    };
    pub use crate::ecs::input::components::Hovered;
    #[cfg(feature = "lattice")]
    pub use crate::ecs::lattice::components::{Lattice, LatticeInfluenced};
    pub use crate::ecs::light::components::{Light, LightType};
    pub use crate::ecs::lines::components::{Line, Lines, MAX_LINES};
    pub use crate::ecs::material::components::{AlphaMode, Material, MaterialRef};
    pub use crate::ecs::mesh::components::{InstanceTransform, InstancedMesh, RenderMesh};
    pub use crate::ecs::morph::components::MorphWeights;
    pub use crate::ecs::name::components::Name;
    pub use crate::ecs::particles::components::{
        ColorGradient, EmitterShape, EmitterType, ParticleEmitter, ParticleSystemStats,
        ParticleTextureUpload,
    };
    pub use crate::ecs::physics::components::{
        CharacterControllerComponent, ColliderComponent, ColliderShape, CollisionListener,
        PhysicsInterpolation, RigidBodyComponent,
    };
    pub use crate::ecs::render_layer::components::RenderLayer;
    pub use crate::ecs::script::components::{Script, ScriptSource};
    pub use crate::ecs::shadow::components::CastsShadow;
    pub use crate::ecs::skin::components::{Joint, Skin};
    pub use crate::ecs::sprite::components::{
        NineSlice, Sprite, SpriteBlendMode, SpriteStencilMode,
    };
    pub use crate::ecs::sprite_animator::components::{LoopMode, SpriteAnimator, SpriteFrame};
    pub use crate::ecs::sprite_particles::components::{
        ColorRange2D, EmitterShape2D, SpriteParticleEmitter,
    };
    pub use crate::ecs::text::components::{
        Text, TextAlignment, TextCharacterBackgroundColors, TextCharacterColors, TextProperties,
        VerticalAlignment,
    };
    pub use crate::ecs::tilemap::components::{TileData, Tilemap};
    pub use crate::ecs::transform::components::{
        GlobalTransform, LocalTransform, LocalTransformDirty, Parent, Rotation,
    };
    pub use crate::ecs::tween::components::{
        Tween, TweenLoopMode, TweenState, TweenTrack, TweenValue,
    };
    pub use crate::ecs::tween::easing::EasingFunction;
    pub use crate::ecs::ui::components::{
        StateTransition, UiButtonData, UiDepthMode, UiLayoutNode, UiLayoutRoot, UiNodeColor,
        UiNodeContent, UiNodeInteraction, UiStateWeights, UiThemeBinding, UiWidgetState,
    };
    pub use crate::ecs::visibility::components::Visibility;
    pub use crate::ecs::water::components::Water;
}

pub mod resources {
    #[cfg(feature = "audio")]
    pub use crate::ecs::audio::resources::AudioEngine;
    pub use crate::ecs::event_bus::resources::{EventBus, Message};
    pub use crate::ecs::graphics::resources::{
        Atmosphere, ColorGrading, ColorGradingPreset, Fog, Graphics, IblViews, MeshLodChain,
        MeshLodLevel, TonemapAlgorithm, VertexSnap,
    };
    pub use crate::ecs::input::resources::{Input, MouseState};
    pub use crate::ecs::material::resources::MaterialRegistry;
    #[cfg(feature = "physics")]
    pub use crate::ecs::physics::resources::PhysicsWorld;
    #[cfg(feature = "assets")]
    pub use crate::ecs::prefab::resources::CachedPrefab;
    pub use crate::ecs::prefab::resources::{AnimationCache, MeshCache, PrefabCache};
    #[cfg(feature = "scripting")]
    pub use crate::ecs::script::resources::ScriptRuntime;
    #[cfg(feature = "sdf_sculpt")]
    pub use crate::ecs::sdf::resources::{SdfMaterial, SdfMaterialRegistry, SdfWorld};
    pub use crate::ecs::text::resources::TextCache;
    pub use crate::ecs::ui::UserInterface;
    pub use crate::ecs::window::resources::{
        SecondaryWindowInput, SecondaryWindowState, SecondaryWindows, ViewportRect, Window,
        WindowSpawnRequest, WindowTiming,
    };
    pub use crate::render::wgpu::texture_cache::TextureCache;
}

pub mod events {
    pub use crate::ecs::event_bus::resources::{InputEvent, KeyState, Message};
}

pub mod commands;
pub use commands::{
    CommandQueue, WorldCommand, capture_procedural_atmosphere_ibl, cleanup_unused_resources_system,
    despawn_entities_with_cache_cleanup, load_hdr_skybox, load_procedural_textures,
    process_commands_system, set_material_with_textures, spawn_3d_billboard_text_with_properties,
    spawn_3d_text_with_properties, spawn_cone_at, spawn_cube_at, spawn_cylinder_at,
    spawn_instanced_mesh, spawn_instanced_mesh_with_material, spawn_mesh_at, spawn_plane_at,
    spawn_sphere_at, spawn_sun, spawn_torus_at, spawn_water_plane_at,
};
#[cfg(not(target_arch = "wasm32"))]
pub use commands::{capture_screenshot, capture_screenshot_to_path};

pub mod animation_systems {
    pub use crate::ecs::animation::systems::{apply_animations, update_animation_players};
}

mod render_trait;
pub use render_trait::{Render, UiOutput, UiPrimitives};

pub use freecs::Entity;
pub use nalgebra_glm::{Mat4, Quat, Vec2, Vec3, Vec4};

freecs::ecs! {
    World {
        Core {
            animation_player: crate::ecs::animation::components::AnimationPlayer => ANIMATION_PLAYER,
            name: crate::ecs::name::components::Name => NAME,
            local_transform: crate::ecs::transform::components::LocalTransform => LOCAL_TRANSFORM,
            global_transform: crate::ecs::transform::components::GlobalTransform => GLOBAL_TRANSFORM,
            local_transform_dirty: crate::ecs::transform::components::LocalTransformDirty => LOCAL_TRANSFORM_DIRTY,
            parent: crate::ecs::transform::components::Parent => PARENT,
            ignore_parent_scale: crate::ecs::transform::components::IgnoreParentScale => IGNORE_PARENT_SCALE,
            audio_source: crate::ecs::audio::components::AudioSource => AUDIO_SOURCE,
            audio_listener: crate::ecs::audio::components::AudioListener => AUDIO_LISTENER,
            camera: crate::ecs::camera::components::Camera => CAMERA,
            pan_orbit_camera: crate::ecs::camera::components::PanOrbitCamera => PAN_ORBIT_CAMERA,
            third_person_camera: crate::ecs::camera::components::ThirdPersonCamera => THIRD_PERSON_CAMERA,
            light: crate::ecs::light::components::Light => LIGHT,
            lines: crate::ecs::lines::components::Lines => LINES,
            visibility: crate::ecs::visibility::components::Visibility => VISIBILITY,
            decal: crate::ecs::decal::components::Decal => DECAL,
            render_mesh: crate::ecs::mesh::components::RenderMesh => RENDER_MESH,
            material_ref: crate::ecs::material::components::MaterialRef => MATERIAL_REF,
            render_layer: crate::ecs::render_layer::components::RenderLayer => RENDER_LAYER,
            text: crate::ecs::text::components::Text => TEXT,
            text_character_colors: crate::ecs::text::components::TextCharacterColors => TEXT_CHARACTER_COLORS,
            text_character_background_colors: crate::ecs::text::components::TextCharacterBackgroundColors => TEXT_CHARACTER_BACKGROUND_COLORS,
            bounding_volume: crate::ecs::bounding_volume::components::BoundingVolume => BOUNDING_VOLUME,
            hovered: crate::ecs::input::components::Hovered => HOVERED,
            rotation: crate::ecs::transform::components::Rotation => ROTATION,
            casts_shadow: crate::ecs::shadow::components::CastsShadow => CASTS_SHADOW,
            rigid_body: crate::ecs::physics::components::RigidBodyComponent => RIGID_BODY,
            collider: crate::ecs::physics::components::ColliderComponent => COLLIDER,
            character_controller: crate::ecs::physics::components::CharacterControllerComponent => CHARACTER_CONTROLLER,
            physics_interpolation: crate::ecs::physics::components::PhysicsInterpolation => PHYSICS_INTERPOLATION,
            collision_listener: crate::ecs::physics::components::CollisionListener => COLLISION_LISTENER,
            instanced_mesh: crate::ecs::mesh::components::InstancedMesh => INSTANCED_MESH,
            particle_emitter: crate::ecs::particles::components::ParticleEmitter => PARTICLE_EMITTER,
            prefab_source: crate::ecs::prefab::components::PrefabSource => PREFAB_SOURCE,
            prefab_instance: crate::ecs::prefab::components::PrefabInstance => PREFAB_INSTANCE,
            script: crate::ecs::script::components::Script => SCRIPT,
            skin: crate::ecs::skin::components::Skin => SKIN,
            joint: crate::ecs::skin::components::Joint => JOINT,
            morph_weights: crate::ecs::morph::components::MorphWeights => MORPH_WEIGHTS,
            navmesh_agent: crate::ecs::navmesh::components::NavMeshAgent => NAVMESH_AGENT,
            lattice: crate::ecs::lattice::components::Lattice => LATTICE,
            lattice_influenced: crate::ecs::lattice::components::LatticeInfluenced => LATTICE_INFLUENCED,
            water: crate::ecs::water::components::Water => WATER,
            grass_region: crate::ecs::grass::components::GrassRegion => GRASS_REGION,
            grass_interactor: crate::ecs::grass::components::GrassInteractor => GRASS_INTERACTOR,
            tween: crate::ecs::tween::components::Tween => TWEEN,
        }
        Ui {
            ui_layout_root: crate::ecs::ui::components::UiLayoutRoot => UI_LAYOUT_ROOT,
            ui_layout_node: crate::ecs::ui::components::UiLayoutNode => UI_LAYOUT_NODE,
            ui_node_color: crate::ecs::ui::components::UiNodeColor => UI_NODE_COLOR,
            ui_theme_binding: crate::ecs::ui::components::UiThemeBinding => UI_THEME_BINDING,
            ui_node_content: crate::ecs::ui::components::UiNodeContent => UI_NODE_CONTENT,
            ui_node_interaction: crate::ecs::ui::components::UiNodeInteraction => UI_NODE_INTERACTION,
            ui_state_weights: crate::ecs::ui::components::UiStateWeights => UI_STATE_WEIGHTS,
            ui_widget_state: crate::ecs::ui::components::UiWidgetState => UI_WIDGET_STATE,
            ui_drag_source: crate::ecs::ui::components::UiDragSource => UI_DRAG_SOURCE,
            ui_drop_target: crate::ecs::ui::components::UiDropTarget => UI_DROP_TARGET,
        }
        Sprite2d {
            sprite: crate::ecs::sprite::components::Sprite => SPRITE,
            sprite_animator: crate::ecs::sprite_animator::components::SpriteAnimator => SPRITE_ANIMATOR,
            tilemap: crate::ecs::tilemap::components::Tilemap => TILEMAP,
            sprite_particle_emitter: crate::ecs::sprite_particles::components::SpriteParticleEmitter => SPRITE_PARTICLE_EMITTER,
        }
    }
    Resources {
        world_id: u64,
        is_runtime: bool,
        window: crate::ecs::window::resources::Window,
        secondary_windows: crate::ecs::window::resources::SecondaryWindows,
        user_interface: crate::ecs::ui::UserInterface,
        graphics: crate::ecs::graphics::resources::Graphics,
        input: crate::ecs::input::resources::Input,
        #[cfg(feature = "audio")]
        audio: crate::ecs::audio::resources::AudioEngine,
        #[cfg(feature = "physics")]
        physics: crate::ecs::physics::resources::PhysicsWorld,
        navmesh: crate::ecs::navmesh::resources::NavMeshWorld,
        text_cache: crate::ecs::text::resources::TextCache,
        mesh_cache: crate::ecs::prefab::resources::MeshCache,
        animation_cache: crate::ecs::prefab::resources::AnimationCache,
        prefab_cache: crate::ecs::prefab::resources::PrefabCache,
        material_registry: crate::ecs::material::resources::MaterialRegistry,
        texture_cache: crate::render::wgpu::texture_cache::TextureCache,
        pending_font_loads: Vec<crate::ecs::text::commands::PendingFontLoad>,
        active_camera: Option<freecs::Entity>,

        event_bus: crate::ecs::event_bus::resources::EventBus,
        command_queue: Vec<crate::ecs::world::commands::WorldCommand>,
        transform_dirty_entities: Vec<freecs::Entity>,
        children_cache: std::collections::HashMap<freecs::Entity, Vec<freecs::Entity>>,
        children_cache_valid: bool,
        cleanup_frame_counter: u64,
        dropped_files: Vec<crate::ecs::input::resources::DroppedFile>,
        skinning_offsets: std::collections::HashMap<freecs::Entity, usize>,
        total_skinning_joints: u32,
        #[cfg(feature = "scripting")]
        script_runtime: crate::ecs::script::resources::ScriptRuntime,
        #[cfg(feature = "openxr")]
        xr: crate::xr::XrResources,
        #[cfg(all(feature = "steam", not(target_arch = "wasm32")))]
        steam: crate::steam::SteamResources,
        #[cfg(feature = "physics")]
        picking_world: crate::ecs::picking::resources::PickingWorld,
        gpu_picking: crate::ecs::gpu_picking::GpuPicking,
        #[cfg(feature = "sdf_sculpt")]
        sdf_world: crate::ecs::sdf::resources::SdfWorld,
        #[cfg(feature = "sdf_sculpt")]
        sdf_materials: crate::ecs::sdf::resources::SdfMaterialRegistry,
        mesh_render_state: crate::render::wgpu::passes::geometry::MeshRenderState,
        #[cfg(feature = "scene_graph")]
        asset_registry: crate::ecs::scene::registry::AssetRegistry,
        #[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
        mcp_command_queue: crate::mcp::CommandQueue,
        entity_names: std::collections::HashMap<String, freecs::Entity>,
        entity_tags: std::collections::HashMap<freecs::Entity, Vec<String>>,
        entity_metadata: std::collections::HashMap<freecs::Entity, std::collections::HashMap<String, crate::ecs::scene::MetadataValue>>,
        pending_particle_textures: Vec<crate::ecs::particles::components::ParticleTextureUpload>,
        ibl_views: crate::ecs::graphics::resources::IblViews,
        retained_ui: crate::ecs::ui::resources::RetainedUiState,
        frame_schedule: crate::schedule::FrameSchedule,
        sprite_slot_allocator: crate::ecs::sprite::slot_allocator::SpriteSlotAllocator,
        #[cfg(all(feature = "file_watcher", not(target_arch = "wasm32")))]
        file_watcher: crate::ecs::file_watcher::FileWatcher,
        #[cfg(all(feature = "assets", feature = "file_watcher", not(target_arch = "wasm32")))]
        asset_watcher: crate::ecs::asset_watcher::AssetWatcher,
        #[cfg(all(target_os = "android", feature = "android"))]
        android_app: Option<android_activity::AndroidApp>,
    }
}

pub use crate::ecs::input::resources::DroppedFile;