nightshade-api 0.48.0

Procedural high level API for the nightshade game engine
Documentation
//! Runtime prefabs: capture a configured entity and its children once, then
//! stamp copies of it anywhere. A prefab is a self-contained snapshot of a
//! subtree with its meshes and textures embedded, so it survives a
//! [`save_prefab`] round trip and instances independently of the original.

use nightshade::ecs::scene::commands::{save_scene_binary_to_bytes, spawn_scene, subtree_to_scene};
use nightshade::ecs::scene::{
    Scene, SceneError, apply_scene_settings, capture_scene_settings, embed_referenced_meshes,
    embed_referenced_textures, load_scene_binary_from_bytes,
};
use nightshade::prelude::{Entity, Vec3, World, tracing};

/// A reusable template captured from a live entity subtree. Build one with
/// [`make_prefab`] and place copies with [`spawn_prefab`].
#[derive(Clone)]
pub struct Prefab {
    scene: Scene,
}

/// Captures `root` and everything parented under it into a prefab, embedding the
/// meshes and textures it references so the template is self-contained.
pub fn make_prefab(world: &World, root: Entity) -> Prefab {
    let mut scene = subtree_to_scene(world, root, "prefab");
    embed_referenced_meshes(world, &mut scene);
    embed_referenced_textures(world, &mut scene);
    Prefab { scene }
}

/// Stamps a fresh copy of `prefab` into the world with its root moved to
/// `position`, returning the root entities of the new instance. Scene-level
/// render settings are preserved across the spawn, which the underlying scene
/// load would otherwise overwrite.
pub fn spawn_prefab(world: &mut World, prefab: &Prefab, position: Vec3) -> Vec<Entity> {
    let settings = capture_scene_settings(world);
    let atmosphere = world.resources.render_settings.atmosphere;
    let roots = match spawn_scene(world, &prefab.scene, None) {
        Ok(result) => result.root_entities,
        Err(error) => {
            tracing::error!("Failed to spawn prefab: {error}");
            Vec::new()
        }
    };
    apply_scene_settings(world, &settings);
    world.resources.render_settings.atmosphere = atmosphere;
    for &root in &roots {
        crate::placement::set_position(world, root, position);
    }
    roots
}

/// Serializes a prefab to self-contained bytes for storing on disk.
pub fn save_prefab(prefab: &Prefab) -> Result<Vec<u8>, SceneError> {
    let mut scene = prefab.scene.clone();
    save_scene_binary_to_bytes(&mut scene)
}

/// Loads a prefab from bytes written by [`save_prefab`].
pub fn load_prefab(bytes: &[u8]) -> Result<Prefab, SceneError> {
    let scene = load_scene_binary_from_bytes(bytes)?;
    Ok(Prefab { scene })
}