Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

World & Resources

The World is the central data container in Nightshade. It holds all entities, components, and global resources.

World Structure

The World is generated by the freecs::ecs! macro and contains:

#![allow(unused)]
fn main() {
pub struct World {
    pub entities: EntityStorage,
    pub resources: Resources,
}
}

Resources

Resources are global singletons accessible throughout the engine:

#![allow(unused)]
fn main() {
pub struct Resources {
    pub world_id: u64,
    pub is_runtime: bool,
    pub window: Window,
    pub secondary_windows: SecondaryWindows,
    pub user_interface: UserInterface,
    pub graphics: Graphics,
    pub input: Input,
    #[cfg(feature = "audio")]
    pub audio: AudioEngine,
    #[cfg(feature = "physics")]
    pub physics: PhysicsWorld,
    pub navmesh: NavMeshWorld,
    pub text_cache: TextCache,
    pub mesh_cache: MeshCache,
    pub animation_cache: AnimationCache,
    pub prefab_cache: PrefabCache,
    pub material_registry: MaterialRegistry,
    pub texture_cache: TextureCache,
    pub pending_font_loads: Vec<PendingFontLoad>,
    pub active_camera: Option<Entity>,
    pub event_bus: EventBus,
    pub command_queue: Vec<WorldCommand>,
    pub transform_dirty_entities: Vec<Entity>,
    pub children_cache: HashMap<Entity, Vec<Entity>>,
    pub children_cache_valid: bool,
    pub cleanup_frame_counter: u64,
    pub dropped_files: Vec<DroppedFile>,
    pub skinning_offsets: HashMap<Entity, usize>,
    pub total_skinning_joints: u32,
    #[cfg(feature = "scripting")]
    pub script_runtime: ScriptRuntime,
    #[cfg(feature = "openxr")]
    pub xr: XrResources,
    #[cfg(all(feature = "steam", not(target_arch = "wasm32")))]
    pub steam: SteamResources,
    #[cfg(feature = "physics")]
    pub picking_world: PickingWorld,
    pub gpu_picking: GpuPicking,
    #[cfg(feature = "sdf_sculpt")]
    pub sdf_world: SdfWorld,
    #[cfg(feature = "sdf_sculpt")]
    pub sdf_materials: SdfMaterialRegistry,
    pub mesh_render_state: MeshRenderState,
    #[cfg(feature = "scene_graph")]
    pub asset_registry: AssetRegistry,
    pub entity_names: HashMap<String, Entity>,
    pub entity_tags: HashMap<Entity, Vec<String>>,
    pub entity_metadata: HashMap<Entity, HashMap<String, MetadataValue>>,
    pub pending_particle_textures: Vec<ParticleTextureUpload>,
    pub ibl_views: IblViews,
    pub retained_ui: RetainedUiState,
    pub frame_schedule: FrameSchedule,
    pub sprite_slot_allocator: SpriteSlotAllocator,
    #[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
    pub mcp_command_queue: CommandQueue,
}
}

There is no separate Time resource. Timing information is accessed through world.resources.window.timing.

Accessing Resources

Resources are accessed through world.resources:

#![allow(unused)]
fn main() {
fn run_systems(&mut self, world: &mut World) {
    let dt = world.resources.window.timing.delta_time;

    if world.resources.input.keyboard.is_key_pressed(KeyCode::Space) {
        self.jump();
    }

    world.resources.graphics.bloom_enabled = true;
    world.resources.graphics.bloom_intensity = 0.5;
}
}

Common Resources

Time & Timing

Timing is accessed through world.resources.window.timing:

#![allow(unused)]
fn main() {
let dt = world.resources.window.timing.delta_time;
let fps = world.resources.window.timing.frames_per_second;
let elapsed = world.resources.window.timing.uptime_milliseconds as f32 / 1000.0;
}

The WindowTiming struct contains:

#![allow(unused)]
fn main() {
pub struct WindowTiming {
    pub frames_per_second: f32,
    pub delta_time: f32,
    pub raw_delta_time: f32,
    pub time_speed: f32,
    pub last_frame_start_instant: Option<web_time::Instant>,
    pub current_frame_start_instant: Option<web_time::Instant>,
    pub initial_frame_start_instant: Option<web_time::Instant>,
    pub frame_counter: u32,
    pub uptime_milliseconds: u64,
}
}

Input

#![allow(unused)]
fn main() {
if world.resources.input.keyboard.is_key_pressed(KeyCode::KeyW) {
    move_forward();
}

let mouse_pos = world.resources.input.mouse.position;

if world.resources.input.mouse.state.contains(MouseState::LEFT_JUST_PRESSED) {
    shoot();
}
}

Graphics Settings

#![allow(unused)]
fn main() {
world.resources.graphics.show_grid = true;
world.resources.graphics.atmosphere = Atmosphere::Sky;
world.resources.graphics.bloom_enabled = true;
world.resources.graphics.ssao_enabled = true;

world.resources.graphics.color_grading.tonemap_algorithm = TonemapAlgorithm::Aces;
}

Active Camera

#![allow(unused)]
fn main() {
world.resources.active_camera = Some(camera_entity);

if let Some(camera) = world.resources.active_camera {
    let transform = world.core.get_global_transform(camera);
}
}

World Commands

Operations that require GPU access or must be deferred are queued as WorldCommand values and processed during the render phase:

#![allow(unused)]
fn main() {
world.queue_command(WorldCommand::LoadTexture {
    name: "my_texture".to_string(),
    rgba_data: texture_bytes,
    width: 256,
    height: 256,
});

world.queue_command(WorldCommand::DespawnRecursive { entity });
world.queue_command(WorldCommand::LoadHdrSkybox { hdr_data });
world.queue_command(WorldCommand::CaptureScreenshot { path: None });
}

For immediate recursive despawning without deferral:

#![allow(unused)]
fn main() {
despawn_recursive_immediate(world, entity);
}