nightshade-api 0.38.0

Procedural high level API for the nightshade game engine
Documentation

nightshade-api

A procedural high level API over the nightshade engine. Write full 3d scenes and small games as straight-line code: free functions, plain data, no trait to implement, no callbacks to wire up.

The engine's own hello world is a State impl with a camera, a sun, and dirty-flagged transform math. Here it is through this crate:

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);
    }
}

open() gives you a lit, navigable scene before your first line runs: procedural sky, sun with shadows, reference grid, orbit camera focused on the origin, prototype textures, and escape to exit. Every knob is one call to change.

Getting Started

[dependencies]

nightshade-api = "0.38.0"

Two ways to run

Own the loop. Setup is code before the loop, game state is locals across iterations. Native only:

let mut app = open();
spawn_floor(&mut app.world, 20.0);
let mut score = 0;
while frame(&mut app) {
    if let Some(coin) = clicked_entity(&app.world) {
        despawn(&mut app.world, coin);
        score += 1;
    }
}

Or hand the engine the loop with run, which also works on wasm. Setup returns your state and the update closure receives it back every frame:

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 and lives until you despawn it. draw_ is immediate and visible for exactly one frame.

Area Calls
Scene spawn_cube, spawn_sphere, spawn_floor, spawn_model, spawn_object
Looks set_color, set_metallic_roughness, set_emissive, set_texture, load_texture
Placement set_position, rotate, set_scale, set_parent, position
Cameras orbit_camera, fly_camera, first_person, fixed_camera, look_at
Environment set_background, show_grid, set_fog, set_bloom, set_time_of_day
Lights point_light, spot_light, set_sun
Input key_down, key_pressed, wasd, axis, mouse_clicked, mouse_position
Picking clicked_entity, entity_under_cursor, cursor_on_ground
Physics Body::Dynamic on spawn_object, push, set_velocity, raycast, collisions
Immediate draw_cube, draw_sphere, draw_line
Text spawn_text, set_text, spawn_label
Audio load_sound, play_sound, play_sound_at

spawn_object covers the loaded case in one struct literal:

let ball = spawn_object(world, Object {
    shape: Shape::Sphere,
    position: vec3(0.0, 4.0, 0.0),
    color: RED,
    body: Body::Dynamic { mass: 2.0 },
    ..Object::default()
});

Examples

Short programs that do a lot, in examples/. From the repo root:

just run-example physics_playground

Example Shows
spinning_cube The minimal program
spinning_cube_portable The same program in the wasm-capable closure form
gallery Primitives, a metallic and roughness sweep, emissive, textures
solar_system Orbital motion, parenting, emissive sun, bloom
physics_playground A block tower, projectiles, click interaction, HUD text
fps_walk First person walking with collision in fifteen lines
model_viewer Animated glb loading (pass a path, defaults to the fox)
hud Anchored screen text, live fps, runtime setting toggles
day_night Time of day, fog, point lights, a procedural skyline

Set NIGHTSHADE_API_FRAMES=120 to exit after a frame budget, which is what just test-examples uses to smoke test every example against the real renderer.

Dropping down to the engine

Every function takes the engine's World and bottoms out in normal nightshade calls. When a program outgrows the facade, replace one call site at a time. The full engine is re-exported at nightshade_api::nightshade:

use nightshade_api::nightshade::prelude::*;

Features

default = ["audio", "physics", "gamepad", "picking"], each forwarding to the engine feature of the same name.

License

Dual-licensed under either of:

at your option.