nightshade_api/lib.rs
1//! # nightshade-api
2//!
3//! A procedural high level API over the nightshade engine. Write a full 3d
4//! scene or a small game as straight-line code with free functions and plain
5//! data. No trait to implement, no callbacks to wire up, no ECS knowledge
6//! required to get started.
7//!
8//! A spinning cube:
9//!
10//! ```ignore
11//! use nightshade_api::prelude::*;
12//!
13//! fn main() {
14//! let mut app = open();
15//! let cube = spawn_cube(&mut app.world, vec3(0.0, 0.5, 0.0));
16//! while frame(&mut app) {
17//! let step = delta_time(&app.world);
18//! rotate(&mut app.world, cube, Vec3::y(), step);
19//! }
20//! }
21//! ```
22//!
23//! Add to Cargo.toml:
24//!
25//! ```toml
26//! nightshade-api = "0.45"
27//! ```
28//!
29//! ## What you get for free
30//!
31//! [`prelude::open`] gives you a window with a sky, a sun with shadows, a
32//! reference grid, an orbit camera focused on the origin, prototype textures
33//! like `"checkerboard"`, and escape to exit. Every program starts from a lit,
34//! navigable scene. Override any of it with one call: [`prelude::set_background`],
35//! [`prelude::show_grid`], [`prelude::fly_camera`], [`prelude::set_sun`].
36//!
37//! ## The two entry points
38//!
39//! Own the loop (native only). Setup is ordinary code before the loop, state
40//! is ordinary locals across loop iterations:
41//!
42//! ```ignore
43//! let mut app = open();
44//! let mut score = 0;
45//! while frame(&mut app) {
46//! score += 1;
47//! }
48//! ```
49//!
50//! Or hand the engine the loop with [`prelude::run`], which also works on
51//! wasm. Setup returns your state, the update closure receives it back every
52//! frame:
53//!
54//! ```ignore
55//! run(
56//! |world| spawn_cube(world, vec3(0.0, 0.5, 0.0)),
57//! |world, cube| {
58//! let step = delta_time(world);
59//! rotate(world, *cube, Vec3::y(), step);
60//! },
61//! )
62//! .unwrap();
63//! ```
64//!
65//! `run` returns a `Result`, so a real `main` returns it. For several per-frame
66//! jobs, the [`run!`](crate::run) macro takes any number of update systems:
67//!
68//! ```ignore
69//! fn main() -> Result<(), Box<dyn std::error::Error>> {
70//! run!(setup, handle_input, move_player, check_collisions)
71//! }
72//! ```
73//!
74//! ## Vocabulary
75//!
76//! Two verbs carry the lifetime rules. `spawn_` is retained: the thing exists
77//! until you [`prelude::despawn`] it. `draw_` is immediate: visible for
78//! exactly one frame, redraw it every frame you want it on screen.
79//!
80//! - Scene content: [`prelude::spawn_cube`], [`prelude::spawn_sphere`],
81//! [`prelude::spawn_floor`], [`prelude::spawn_model`], [`prelude::spawn_object`]
82//! - Crowds: [`prelude::spawn_objects`], [`prelude::spawn_instanced`]
83//! - Tags: [`prelude::tag`], [`prelude::tagged`], [`prelude::for_each_tagged`]
84//! - Looks: [`prelude::set_color`], [`prelude::set_metallic_roughness`],
85//! [`prelude::set_emissive`], [`prelude::set_texture`],
86//! [`prelude::set_normal_texture`]
87//! - Placement: [`prelude::set_position`], [`prelude::rotate`], [`prelude::set_scale`],
88//! [`prelude::set_parent`]
89//! - Cameras: [`prelude::orbit_camera`], [`prelude::fly_camera`],
90//! [`prelude::first_person`], [`prelude::fixed_camera`],
91//! [`prelude::set_field_of_view`], [`prelude::set_orthographic`]
92//! - Input: [`prelude::key_down`], [`prelude::wasd`], [`prelude::mouse_clicked`],
93//! [`prelude::clicked_entity`]
94//! - Immediate drawing: [`prelude::draw_cube`], [`prelude::draw_sphere`],
95//! [`prelude::draw_line`]
96//! - Text: [`prelude::spawn_text`], [`prelude::set_text`], [`prelude::spawn_label`]
97//! - UI: [`prelude::spawn_panel`], [`prelude::panel_button`],
98//! [`prelude::panel_label`], [`prelude::button_clicked`]; plus the full widget
99//! set: [`prelude::panel_data_grid`], [`prelude::panel_tree_view`],
100//! [`prelude::panel_property_grid`], [`prelude::panel_color_picker`],
101//! [`prelude::panel_date_picker`], [`prelude::panel_command_palette`],
102//! [`prelude::panel_modal`], [`prelude::panel_virtual_list`]
103//! - Animation: [`prelude::play_animation`], [`prelude::play_animation_named`],
104//! [`prelude::blend_to_animation`], [`prelude::set_animation_speed`]
105//! - Post-processing: [`prelude::set_ssao`], [`prelude::set_ssr`],
106//! [`prelude::set_tonemap`], [`prelude::set_color_grading`]
107//! - Live physics tuning: [`prelude::set_friction`], [`prelude::set_restitution`],
108//! [`prelude::set_mass`], [`prelude::set_gravity_scale`]
109//! - Layout containers: [`prelude::panel_row`], [`prelude::panel_grid`],
110//! [`prelude::panel_scroll`]; world-space UI: [`prelude::spawn_world_panel`]
111//! - Animation extras: [`prelude::add_animation_event`],
112//! [`prelude::add_animation_layer`], [`prelude::reach_to`], [`prelude::aim_at`]
113//! - Prefabs and undo: [`prelude::make_prefab`], [`prelude::spawn_prefab`],
114//! [`prelude::UndoStack`]
115//!
116//! ## Reading the scene back
117//!
118//! The setters have readers, which is what a tool that edits a scene rather than
119//! just building one needs. [`prelude::describe_entity`] gathers an entity's
120//! whole editable state, [`prelude::get_color`] and friends read one field,
121//! [`prelude::scene_tree`] and [`prelude::children`] walk the hierarchy,
122//! [`prelude::list_materials`] reads the shared material registry, and
123//! [`prelude::bounds_of`] with [`prelude::frame_entities`] measure and frame a
124//! selection. [`prelude::save_scene`] and [`prelude::load_scene`] round-trip the
125//! whole world to bytes. Components are added, removed, and snapshotted for undo
126//! by [`prelude::ComponentKind`], the surface the standalone editor is built on.
127//!
128//! ## Commands
129//!
130//! Every call also has a data form. [`prelude::Command`] is a serde enum with
131//! one variant per function, [`prelude::submit_command`] runs one, and
132//! [`prelude::submit_commands`] runs a batch where a later command can name an
133//! entity an earlier one produced with [`prelude::Ref::Result`], so one batch
134//! builds and wires up a scene. The enum is the wire format a binding targets:
135//! build `Command` values, read [`prelude::CommandReply`] back, with the json
136//! schema from [`prelude::command_schema`]. The free functions stay the real
137//! implementations and the dispatch forwards to them.
138//! See the `commands` example and `docs/COMMAND_API.md`.
139//!
140//! ## Dropping down to the engine
141//!
142//! Every function here takes the real engine [`prelude::World`] and bottoms
143//! out in normal nightshade calls. Nothing is hidden behind a wrapper type,
144//! so when a program outgrows the facade you replace one call site at a time.
145//! The full engine is re-exported at [`nightshade`], one path away:
146//!
147//! ```ignore
148//! use nightshade_api::nightshade::prelude::*;
149//! ```
150//!
151//! ## Examples
152//!
153//! The `examples/` directory is the tour. Run one with
154//! `just run-example solar_system` from the repo root, or
155//! `cargo run -r -p nightshade-api --example solar_system`. Every example also
156//! runs in the browser with `just run-example-wasm solar_system`, which serves
157//! it through trunk.
158
159pub use nightshade;
160
161mod animate;
162#[cfg(not(target_arch = "wasm32"))]
163mod app;
164mod appearance;
165#[cfg(feature = "audio")]
166mod audio;
167mod bounds;
168mod camera;
169#[cfg(feature = "physics")]
170mod character;
171mod cloth;
172mod command;
173mod cutscene;
174mod decals;
175mod draw;
176#[cfg(feature = "protocol")]
177pub mod editor;
178mod effects;
179mod environment;
180mod events;
181mod groups;
182mod hierarchy;
183mod input;
184mod inspect;
185mod lighting;
186mod materials;
187mod mesh;
188mod messaging;
189mod morph;
190#[cfg(feature = "navmesh")]
191mod navigation;
192#[cfg(all(feature = "net", not(target_arch = "wasm32")))]
193mod net;
194mod palette;
195#[cfg(feature = "physics")]
196mod physics;
197#[cfg(feature = "picking")]
198mod picking;
199mod placement;
200mod prefab;
201mod reflect;
202mod render;
203mod runner;
204mod scene;
205#[cfg(feature = "scripting")]
206mod scripting;
207mod serialize;
208#[cfg(any(feature = "terrain", feature = "grass"))]
209mod terrain;
210mod text;
211mod ui;
212mod undo;
213mod window;
214#[cfg(feature = "picking")]
215mod world_ui;
216
217/// Everything in one import.
218///
219/// ```ignore
220/// use nightshade_api::prelude::*;
221/// ```
222///
223/// Pulls in the full api surface plus the engine types it hands you:
224/// [`World`], [`Entity`], the math types, [`KeyCode`], and [`MouseButton`].
225pub mod prelude {
226 pub use crate::animate::*;
227 #[cfg(not(target_arch = "wasm32"))]
228 pub use crate::app::{App, Window, frame, open, open_with, render_image};
229 pub use crate::appearance::*;
230 #[cfg(feature = "audio")]
231 pub use crate::audio::*;
232 pub use crate::bounds::*;
233 pub use crate::camera::*;
234 #[cfg(feature = "physics")]
235 pub use crate::character::*;
236 pub use crate::cloth::*;
237 pub use crate::command::*;
238 pub use crate::cutscene::*;
239 pub use crate::decals::*;
240 pub use crate::draw::*;
241 pub use crate::effects::*;
242 pub use crate::environment::*;
243 pub use crate::events::*;
244 pub use crate::groups::*;
245 pub use crate::hierarchy::*;
246 pub use crate::input::*;
247 pub use crate::inspect::*;
248 pub use crate::lighting::*;
249 pub use crate::materials::*;
250 pub use crate::mesh::*;
251 pub use crate::messaging::*;
252 pub use crate::morph::*;
253 #[cfg(feature = "navmesh")]
254 pub use crate::navigation::*;
255 #[cfg(all(feature = "net", not(target_arch = "wasm32")))]
256 pub use crate::net::*;
257 pub use crate::palette::*;
258 #[cfg(feature = "physics")]
259 pub use crate::physics::*;
260 #[cfg(feature = "picking")]
261 pub use crate::picking::*;
262 pub use crate::placement::*;
263 pub use crate::prefab::*;
264 pub use crate::reflect::*;
265 pub use crate::render::*;
266 pub use crate::run;
267 pub use crate::runner::{run, run_scene, systems};
268 pub use crate::scene::*;
269 #[cfg(feature = "scripting")]
270 pub use crate::scripting::*;
271 pub use crate::serialize::*;
272 #[cfg(any(feature = "terrain", feature = "grass"))]
273 pub use crate::terrain::*;
274 pub use crate::text::*;
275 pub use crate::ui::*;
276 pub use crate::undo::*;
277 pub use crate::window::*;
278 #[cfg(feature = "picking")]
279 pub use crate::world_ui::*;
280 pub use nightshade::ecs::material::components::Material;
281 pub use nightshade::ecs::particles::components::ParticleEmitter;
282 #[cfg(feature = "navmesh")]
283 pub use nightshade::prelude::RecastNavMeshConfig;
284
285 pub use nightshade::ecs::graphics::resources::DepthOfField;
286 #[cfg(feature = "physics")]
287 pub use nightshade::ecs::physics::joints::{
288 FixedJoint, JointAxisDirection, JointHandle, RevoluteJoint, RopeJoint, SpringJoint,
289 };
290 #[cfg(feature = "physics")]
291 pub use nightshade::prelude::{CollisionEvent, RaycastHit};
292 pub use nightshade::prelude::{
293 EasingFunction, Entity, Fog, InstanceTransform, KeyCode, Line, MouseButton, ShadingMode,
294 TextAlignment, Vec2, Vec3, Vec4, VerticalAlignment, ViewportShading, World, nalgebra_glm,
295 vec2, vec3, vec4,
296 };
297}