Skip to main content

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 is the whole pitch:
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.43"
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//! - Placement: [`prelude::set_position`], [`prelude::rotate`], [`prelude::set_scale`],
87//!   [`prelude::set_parent`]
88//! - Cameras: [`prelude::orbit_camera`], [`prelude::fly_camera`],
89//!   [`prelude::first_person`], [`prelude::fixed_camera`]
90//! - Input: [`prelude::key_down`], [`prelude::wasd`], [`prelude::mouse_clicked`],
91//!   [`prelude::clicked_entity`]
92//! - Immediate drawing: [`prelude::draw_cube`], [`prelude::draw_sphere`],
93//!   [`prelude::draw_line`]
94//! - Text: [`prelude::spawn_text`], [`prelude::set_text`], [`prelude::spawn_label`]
95//!
96//! ## Dropping down to the engine
97//!
98//! Every function here takes the real engine [`prelude::World`] and bottoms
99//! out in normal nightshade calls. Nothing is hidden behind a wrapper type,
100//! so when a program outgrows the facade you replace one call site at a time.
101//! The full engine is re-exported at [`nightshade`], one path away:
102//!
103//! ```ignore
104//! use nightshade_api::nightshade::prelude::*;
105//! ```
106//!
107//! ## Examples
108//!
109//! The `examples/` directory is the tour. Run one with
110//! `just run-example solar_system` from the repo root, or
111//! `cargo run -r -p nightshade-api --example solar_system`. Every example also
112//! runs in the browser with `just run-example-wasm solar_system`, which serves
113//! it through trunk.
114
115pub use nightshade;
116
117mod animate;
118#[cfg(not(target_arch = "wasm32"))]
119mod app;
120mod appearance;
121#[cfg(feature = "audio")]
122mod audio;
123mod camera;
124mod decals;
125mod draw;
126mod effects;
127mod environment;
128mod groups;
129mod input;
130mod lighting;
131#[cfg(feature = "navmesh")]
132mod navigation;
133mod palette;
134#[cfg(feature = "physics")]
135mod physics;
136#[cfg(feature = "picking")]
137mod picking;
138mod placement;
139mod runner;
140mod scene;
141mod text;
142
143/// Everything in one import.
144///
145/// ```ignore
146/// use nightshade_api::prelude::*;
147/// ```
148///
149/// Pulls in the full api surface plus the engine types it hands you:
150/// [`World`], [`Entity`], the math types, [`KeyCode`], and [`MouseButton`].
151pub mod prelude {
152    pub use crate::animate::*;
153    #[cfg(not(target_arch = "wasm32"))]
154    pub use crate::app::{App, Window, frame, open, open_with, render_image};
155    pub use crate::appearance::*;
156    #[cfg(feature = "audio")]
157    pub use crate::audio::*;
158    pub use crate::camera::*;
159    pub use crate::decals::*;
160    pub use crate::draw::*;
161    pub use crate::effects::*;
162    pub use crate::environment::*;
163    pub use crate::groups::*;
164    pub use crate::input::*;
165    pub use crate::lighting::*;
166    #[cfg(feature = "navmesh")]
167    pub use crate::navigation::*;
168    pub use crate::palette::*;
169    #[cfg(feature = "physics")]
170    pub use crate::physics::*;
171    #[cfg(feature = "picking")]
172    pub use crate::picking::*;
173    pub use crate::placement::*;
174    pub use crate::run;
175    pub use crate::runner::{run, run_scene, systems};
176    pub use crate::scene::*;
177    pub use crate::text::*;
178
179    pub use nightshade::ecs::graphics::resources::DepthOfField;
180    #[cfg(feature = "physics")]
181    pub use nightshade::ecs::physics::joints::{
182        FixedJoint, JointAxisDirection, JointHandle, RevoluteJoint, RopeJoint, SpringJoint,
183    };
184    #[cfg(feature = "physics")]
185    pub use nightshade::prelude::{CollisionEvent, RaycastHit};
186    pub use nightshade::prelude::{
187        EasingFunction, Entity, Fog, InstanceTransform, KeyCode, Line, MouseButton, Vec2, Vec3,
188        Vec4, World, nalgebra_glm, vec2, vec3, vec4,
189    };
190}