Skip to main content

khora_sdk/
lib.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! The public-facing Software Development Kit (SDK) for the Khora Engine.
16//!
17//! This is the **only** crate that should be used by game developers.
18//! All internal crates (khora-agents, khora-control, etc.) are implementation details.
19//!
20//! # Examples
21//!
22//! A minimal game is an [`EngineApp`] handed to [`run_winit`]. The SDK owns the
23//! engine loop; your type owns the game logic. Everything you need for game code
24//! is in [`prelude`].
25//!
26//! ```rust,no_run
27//! use khora_sdk::prelude::*;
28//! use khora_sdk::prelude::math::Vec3;
29//! use khora_sdk::{
30//!     run_winit, AgentProvider, DccService, EngineApp, GameWorld, PhaseProvider,
31//!     Runtime, Vessel, WindowConfig,
32//! };
33//! use khora_sdk::winit_adapters::WinitWindowProvider;
34//!
35//! struct MyGame;
36//!
37//! impl EngineApp for MyGame {
38//!     fn window_config() -> WindowConfig {
39//!         WindowConfig { title: "My Game".into(), ..WindowConfig::default() }
40//!     }
41//!     fn new() -> Self {
42//!         MyGame
43//!     }
44//!     fn setup(&mut self, world: &mut GameWorld, _runtime: &Runtime) {
45//!         // Spawn a camera looking down the -Z axis.
46//!         let camera = ecs::Camera::new_perspective(
47//!             std::f32::consts::FRAC_PI_4,
48//!             16.0 / 9.0,
49//!             0.1,
50//!             1000.0,
51//!         );
52//!         Vessel::at(world, Vec3::new(0.0, 2.0, 10.0))
53//!             .with_component(camera)
54//!             .build();
55//!     }
56//!     fn update(&mut self, _world: &mut GameWorld, _inputs: &[InputEvent]) {}
57//! }
58//!
59//! // `AgentProvider` / `PhaseProvider` are required super-traits; the default
60//! // (no custom agents, no custom phases) is enough for most games.
61//! impl AgentProvider for MyGame {
62//!     fn register_agents(&self, _dcc: &DccService, _runtime: &mut Runtime) {}
63//! }
64//! impl PhaseProvider for MyGame {}
65//!
66//! fn main() -> anyhow::Result<()> {
67//!     run_winit::<WinitWindowProvider, MyGame>(|_window, _runtime, _event_loop| {
68//!         // Wire backends (renderer, physics, audio, …) into `_runtime` here.
69//!     })
70//! }
71//! ```
72
73#![warn(missing_docs)]
74
75mod engine;
76mod game_world;
77mod run_default;
78mod traits;
79mod vessel;
80pub mod winit_adapters;
81
82pub use engine::EngineCore;
83pub use game_world::GameWorld;
84pub use run_default::run_default;
85pub use traits::{AgentProvider, EngineApp, PhaseProvider, WindowProvider};
86pub use vessel::{spawn_cube_at, spawn_plane, spawn_sphere, Vessel};
87pub use winit_adapters::{run_winit, WinitAppRunner};
88
89// Re-export window provider for convenience
90pub use winit_adapters::WinitWindowProvider;
91
92// ─────────────────────────────────────────────────────────────────────
93// Editor UI re-exports — so editor panels can import from SDK only
94// ─────────────────────────────────────────────────────────────────────
95pub mod editor_ui {
96    //! Editor UI types re-exported from khora_core.
97    //!
98    //! Includes everything from `khora_core::ui::editor::*` plus the
99    //! shared `UiTheme` and font types that live one level up in
100    //! `khora_core::ui` (because the hub uses them too).
101    pub use khora_core::ui::editor::*;
102    pub use khora_core::ui::fonts::{FontHandle, FontPack, NamedFont};
103    pub use khora_core::ui::theme::UiTheme;
104}
105
106pub mod tool_ui {
107    //! UI surface for standalone Khora tools (the hub, future asset
108    //! cookers, …).
109    //!
110    //! These tools depend on `khora-sdk` and reach the egui backend
111    //! exclusively through this module — never directly via `egui`
112    //! or `eframe`. The day the engine swaps backend, this re-export
113    //! list moves to whichever crate provides the new
114    //! [`run_native`] + [`AppContext`] implementation.
115    //!
116    //! This module is the **runtime** seam only. Khora's *look* — the brand
117    //! palette and the shared widget vocabulary — is cosmetics and lives in
118    //! the separate `khora-tool-ui` crate, which the SDK deliberately does
119    //! **not** depend on, so a game built on Khora never compiles the engine
120    //! vendor's brand. Tools depend on both.
121
122    pub use khora_core::math::{LinearRgba, Rect2D, Vec2};
123    pub use khora_core::ui::editor::{
124        FontFamilyHint, Icon, InlineEditEvent, Interaction, TextAlign,
125    };
126    pub use khora_core::ui::{
127        Align, Align2, App, AppContext, AppLifecycle, CornerRadius, FontHandle, FontPack, Margin,
128        NamedFont, Stroke, UiBuilder, UiTheme,
129    };
130    pub use khora_infra::ui::egui::app::{run_native, WindowConfigInput, WindowIconInput};
131}
132
133// ─────────────────────────────────────────────────────────────────────
134// Re-exports from internal crates — the SDK is the single entry point
135// ─────────────────────────────────────────────────────────────────────
136
137// Control / DCC
138pub use khora_control::{Context as EngineContext, DccConfig, DccService, EngineMode};
139// Re-export the same Context as `DccContext` so editor code can use the
140// more descriptive name without a separate `use` line. (Same type — both
141// re-exports point at `khora_control::Context`.)
142//
143// `AgentRegistry` is exposed as a read-only telemetry surface for the
144// editor's Control Plane panel. The mutating side (`ExecutionScheduler`,
145// `BudgetChannel`, `EnginePlugin`) stays internal — the SDK is a façade
146// for game code, not for engine internals.
147pub use khora_control::registry::AgentRegistry;
148pub use khora_control::Context as DccContext;
149
150// Core types
151pub use khora_core::agent::{AgentImportance, ExecutionPhase, ExecutionTiming};
152pub use khora_core::control::gorna::{AgentHints, AgentId, AgentStatus, EngineHint, StrategyId};
153pub use khora_core::telemetry::{MonitoredResourceType, TelemetryEvent};
154pub use khora_core::ui::editor::generate_selection_gizmos;
155pub use khora_core::ui::editor::gizmo::GizmoKind;
156pub use khora_core::ui::editor::gizmo::GizmoLineInstance;
157pub use khora_core::ui::editor::viewport_texture::ViewportTextureHandle;
158pub use khora_core::ui::editor::{
159    AssetEntry, CommandHistory, ComponentJson, EditorCamera, EditorCommand, EditorLogCapture,
160    EditorMode, EditorPanel, EditorShell, EditorState, EntityIcon, FontFamilyHint, GizmoMode, Icon,
161    InspectedEntity, Interaction, LogEntry, LogLevel, PanelLocation, PlayMode, PropertyEdit,
162    SceneNode, StatusBarData, TextAlign, UiBuilder,
163};
164pub use khora_core::ui::fonts::{FontHandle, FontPack, NamedFont};
165pub use khora_core::ui::theme::UiTheme;
166pub use khora_core::{Backends, Resources, Runtime, Services};
167
168// Telemetry service
169pub use khora_telemetry::MonitorRegistry;
170pub use khora_telemetry::TelemetryService;
171// AgentRegistry is already re-exported above (line 51) via
172// `pub use khora_control::registry::AgentRegistry`.
173
174// Infra / monitors
175pub use khora_infra::telemetry::memory_monitor::MemoryMonitor;
176pub use khora_infra::GpuMonitor;
177
178// I/O
179pub use khora_core::asset::AssetSource;
180pub use khora_core::scene::{SceneFile, SerializationGoal};
181pub use khora_data::assets::SoundData;
182pub use khora_io;
183pub use khora_io::asset::decoders::audio::SymphoniaDecoder;
184pub use khora_io::asset::{
185    AssetChangeEvent, AssetChangeKind, AssetIdRegistry, AssetIo, AssetService, AssetWatcher,
186    AssetWriter, FileLoader, FileSystemResolver, IndexBuilder, MeshDispatcher, PackBuilder,
187    PackHeader, PackLoader, PackOutput, PackProgress, PACK_FORMAT_VERSION, PACK_HEADER_SIZE,
188    PACK_MAGIC,
189};
190pub use khora_io::serialization::SerializationService;
191pub use khora_telemetry::MetricsRegistry;
192
193// Mesh type (used by editor ops)
194pub use khora_core::renderer::api::scene::mesh::Mesh;
195
196// Scene environment — selects the equirectangular map the IBL bake projects
197// onto the environment cube (absent ⇒ the procedural sky is baked instead).
198pub use khora_data::EnvironmentMap;
199
200/// Renderer sub-modules (used by editor gizmo)
201pub mod renderer {
202    pub use khora_core::renderer::api::resource;
203    pub use khora_core::renderer::api::scene;
204    pub use khora_core::renderer::light;
205}
206
207// WgpuRenderSystem (used by editor main)
208pub use khora_infra::WgpuRenderSystem;
209
210// Backend implementations and their traits — apps insert these into
211// `Runtime::backends` / `Runtime::resources` during the `run_winit`
212// bootstrap closure to wire the engine to its physics, layout, text and
213// audio backends.
214pub use khora_core::audio::{AudioDevice, AudioMixBus, AudioStream, DefaultMixBus, StreamInfo};
215pub use khora_core::physics::PhysicsProvider;
216pub use khora_core::renderer::api::text::TextRenderer;
217pub use khora_core::renderer::traits::PipelineSystem;
218pub use khora_core::ui::LayoutSystem;
219pub use khora_infra::audio::backends::cpal::CpalAudioDevice;
220pub use khora_infra::graphics::WgpuPipelineSystem;
221pub use khora_infra::physics::rapier::RapierPhysicsWorld;
222pub use khora_infra::renderer::StandardTextRenderer;
223pub use khora_infra::ui::TaffyLayoutSystem;
224pub use khora_lanes::render_lane::shaders::TEXT_WGSL;
225
226// Data / ECS (needed for world restore)
227pub use khora_data;
228pub use khora_data::ecs::World as EcsWorld;
229
230// Re-export types used by editor panels and gizmo code
231pub use khora_core;
232pub use khora_core::math::Mat4;
233pub use khora_core::renderer::traits::RenderSystem;
234pub use khora_data::ecs::HandleComponent;
235
236// PropertyEdit is in khora_core::ui::editor, already re-exported via editor_ui
237pub use khora_data::scene::ComponentRegistration;
238pub use khora_data::scene::{instantiate_subtree, serialize_subtree};
239
240// Agents (for when apps need to create their own)
241pub use khora_agents;
242
243// Lanes — re-exported so the editor can reach built-in shaders without
244// taking a direct dependency on khora-lanes.
245pub use khora_lanes;
246
247// Winit — re-exported so the editor can downcast the opaque `&dyn Any`
248// `event_loop` argument passed to the `run_winit` bootstrap closure.
249pub use winit;
250
251// Re-export inventory for editor
252pub extern crate inventory;
253
254pub mod prelude {
255    //! Common imports for game development.
256    //!
257    //! Glob-import this module to bring the everyday game-dev types into scope:
258    //! input ([`InputEvent`], [`KeyCode`], [`MouseButton`]), timing
259    //! ([`Time`], [`SharedTime`]), assets ([`AssetHandle`], [`AssetUUID`]), and
260    //! the [`ecs`], [`materials`], and [`math`] sub-modules. The window config
261    //! types [`WindowConfig`] and [`WindowIcon`] come along too.
262    //!
263    //! # Examples
264    //!
265    //! ```rust
266    //! use khora_sdk::prelude::*;
267    //! use khora_sdk::prelude::math::Vec3;
268    //!
269    //! // ECS components, math, and materials are all reachable through the prelude.
270    //! let _transform = ecs::Transform::from_translation(Vec3::new(0.0, 1.0, 0.0));
271    //! let _material = materials::StandardMaterial::default();
272    //! let _red = math::LinearRgba::RED;
273    //! ```
274
275    // SDK types
276    pub use crate::{WindowConfig, WindowIcon, PRIMARY_VIEWPORT};
277
278    // Assets
279    pub use khora_core::asset::{AssetHandle, AssetUUID};
280
281    // Memory tracking (for `#[global_allocator]`)
282    pub use khora_core::memory::SaaTrackingAllocator;
283
284    // Input
285    pub use khora_core::platform::{InputEvent, KeyCode, MouseButton};
286
287    // Per-frame timing — real frame delta, fixed sim step, interpolation alpha.
288    // `SharedTime` is the interior-mutable handle to cache in `setup` and read
289    // each frame in `update`.
290    pub use khora_core::time::{SharedTime, Time};
291
292    // ECS types
293    pub mod ecs {
294        //! Core ECS types for game logic.
295        pub use khora_core::ecs::entity::EntityId;
296        pub use khora_core::physics::{BodyType, ColliderShape};
297        pub use khora_core::renderer::light::{DirectionalLight, LightType, PointLight, SpotLight};
298        pub use khora_data::ecs::{
299            AudioSource, Camera, Children, Collider, Component, ComponentBundle, GlobalTransform,
300            Light, MaterialRef, MeshRef, Name, Parent, ProceduralMeshKind, ProjectionType,
301            RigidBody, Tag, Transform, Without,
302        };
303    }
304
305    // Materials
306    pub mod materials {
307        //! Built-in material types.
308        //!
309        //! [`AlphaMode`] is re-exported alongside them because it is the type of
310        //! `StandardMaterial::alpha_mode`: without it a game could not select
311        //! masked or blended transparency through the SDK.
312        pub use khora_core::asset::{
313            AlphaMode, EmissiveMaterial, StandardMaterial, UnlitMaterial, WireframeMaterial,
314        };
315    }
316
317    // Math
318    pub mod math {
319        //! Math types and utilities.
320        pub use khora_core::math::LinearRgba;
321        pub use khora_core::math::*;
322    }
323}
324
325// Re-export InputEvent at crate level for trait usage
326pub use khora_core::platform::{InputEvent, KeyCode, MouseButton};
327
328/// Well-known viewport handle for the primary 3D viewport.
329pub const PRIMARY_VIEWPORT: ViewportTextureHandle = ViewportTextureHandle(0);
330
331/// Raw window icon data for native window creation.
332#[derive(Clone, Debug)]
333pub struct WindowIcon {
334    /// RGBA8 pixel buffer stored row-major.
335    pub rgba: Vec<u8>,
336    /// Icon width in pixels.
337    pub width: u32,
338    /// Icon height in pixels.
339    pub height: u32,
340}
341
342/// Window configuration for applications.
343#[derive(Clone, Debug)]
344pub struct WindowConfig {
345    /// Window title shown by the platform window manager.
346    pub title: String,
347    /// Initial window width in pixels.
348    pub width: u32,
349    /// Initial window height in pixels.
350    pub height: u32,
351    /// Optional custom window icon.
352    pub icon: Option<WindowIcon>,
353}
354
355impl Default for WindowConfig {
356    fn default() -> Self {
357        Self {
358            title: "Khora Engine".to_owned(),
359            width: 1024,
360            height: 768,
361            icon: None,
362        }
363    }
364}