1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//! # nightshade-api
//!
//! A procedural high level API over the nightshade engine. Write a full 3d
//! scene or a small game as straight-line code with free functions and plain
//! data. No trait to implement, no callbacks to wire up, no ECS knowledge
//! required to get started.
//!
//! A spinning cube is the whole pitch:
//!
//! ```ignore
//! use nightshade_api::prelude::*;
//!
//! fn main() {
//! let mut app = open();
//! let cube = spawn_cube(&mut app.world, vec3(0.0, 0.5, 0.0));
//! while frame(&mut app) {
//! let step = delta_time(&app.world);
//! rotate(&mut app.world, cube, Vec3::y(), step);
//! }
//! }
//! ```
//!
//! Add to Cargo.toml:
//!
//! ```toml
//! nightshade-api = "0.40"
//! ```
//!
//! ## What you get for free
//!
//! [`prelude::open`] gives you a window with a sky, a sun with shadows, a
//! reference grid, an orbit camera focused on the origin, prototype textures
//! like `"checkerboard"`, and escape to exit. Every program starts from a lit,
//! navigable scene. Override any of it with one call: [`prelude::set_background`],
//! [`prelude::show_grid`], [`prelude::fly_camera`], [`prelude::set_sun`].
//!
//! ## The two entry points
//!
//! Own the loop (native only). Setup is ordinary code before the loop, state
//! is ordinary locals across loop iterations:
//!
//! ```ignore
//! let mut app = open();
//! let mut score = 0;
//! while frame(&mut app) {
//! score += 1;
//! }
//! ```
//!
//! Or hand the engine the loop with [`prelude::run`], which also works on
//! wasm. Setup returns your state, the update closure receives it back every
//! frame:
//!
//! ```ignore
//! run(
//! |world| spawn_cube(world, vec3(0.0, 0.5, 0.0)),
//! |world, cube| {
//! let step = delta_time(world);
//! rotate(world, *cube, Vec3::y(), step);
//! },
//! )
//! .unwrap();
//! ```
//!
//! ## Vocabulary
//!
//! Two verbs carry the lifetime rules. `spawn_` is retained: the thing exists
//! until you [`prelude::despawn`] it. `draw_` is immediate: visible for
//! exactly one frame, redraw it every frame you want it on screen.
//!
//! - Scene content: [`prelude::spawn_cube`], [`prelude::spawn_sphere`],
//! [`prelude::spawn_floor`], [`prelude::spawn_model`], [`prelude::spawn_object`]
//! - Crowds: [`prelude::spawn_objects`], [`prelude::spawn_instanced`]
//! - Tags: [`prelude::tag`], [`prelude::tagged`], [`prelude::for_each_tagged`]
//! - Looks: [`prelude::set_color`], [`prelude::set_metallic_roughness`],
//! [`prelude::set_emissive`], [`prelude::set_texture`]
//! - Placement: [`prelude::set_position`], [`prelude::rotate`], [`prelude::set_scale`],
//! [`prelude::set_parent`]
//! - Cameras: [`prelude::orbit_camera`], [`prelude::fly_camera`],
//! [`prelude::first_person`], [`prelude::fixed_camera`]
//! - Input: [`prelude::key_down`], [`prelude::wasd`], [`prelude::mouse_clicked`],
//! [`prelude::clicked_entity`]
//! - Immediate drawing: [`prelude::draw_cube`], [`prelude::draw_sphere`],
//! [`prelude::draw_line`]
//! - Text: [`prelude::spawn_text`], [`prelude::set_text`], [`prelude::spawn_label`]
//!
//! ## Dropping down to the engine
//!
//! Every function here takes the real engine [`prelude::World`] and bottoms
//! out in normal nightshade calls. Nothing is hidden behind a wrapper type,
//! so when a program outgrows the facade you replace one call site at a time.
//! The full engine is re-exported at [`nightshade`], one path away:
//!
//! ```ignore
//! use nightshade_api::nightshade::prelude::*;
//! ```
//!
//! ## Examples
//!
//! The `examples/` directory is the tour. Run one with
//! `just run-example solar_system` from the repo root, or
//! `cargo run -r -p nightshade-api --example solar_system`.
pub use nightshade;
/// Everything in one import.
///
/// ```ignore
/// use nightshade_api::prelude::*;
/// ```
///
/// Pulls in the full api surface plus the engine types it hands you:
/// [`World`], [`Entity`], the math types, [`KeyCode`], and [`MouseButton`].