Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Your First Application

Let's create a simple application that displays a 3D scene with a camera, lighting, and some cubes.

Basic Structure

Every Nightshade application implements the State trait:

use nightshade::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    nightshade::launch(MyGame::default())
}

#[derive(Default)]
struct MyGame;

impl State for MyGame {
    fn title(&self) -> &str {
        "My First Game"
    }

    fn initialize(&mut self, world: &mut World) {
    }

    fn run_systems(&mut self, world: &mut World) {
    }
}

Adding a Camera

The camera determines what the player sees:

#![allow(unused)]
fn main() {
fn initialize(&mut self, world: &mut World) {
    let camera = spawn_camera(
        world,
        Vec3::new(0.0, 5.0, 10.0),
        "Main Camera".to_string(),
    );
    world.resources.active_camera = Some(camera);
}
}

Adding Lighting

Without lights, everything is dark. Add a directional light (sun):

#![allow(unused)]
fn main() {
fn initialize(&mut self, world: &mut World) {
    spawn_sun(world);
}
}

Enabling the Grid

For development, a ground grid is helpful:

#![allow(unused)]
fn main() {
fn initialize(&mut self, world: &mut World) {
    world.resources.graphics.show_grid = true;
    world.resources.graphics.atmosphere = Atmosphere::Sky;
}
}

Adding Geometry

Spawn a cube using the built-in primitive (available from the prelude):

#![allow(unused)]
fn main() {
fn initialize(&mut self, world: &mut World) {
    spawn_cube_at(world, Vec3::new(0.0, 1.0, 0.0));
}
}

Camera Controls

Add a fly camera system so you can navigate the scene:

#![allow(unused)]
fn main() {
fn run_systems(&mut self, world: &mut World) {
    fly_camera_system(world);
    escape_key_exit_system(world);
}
}

Complete Example

use nightshade::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    nightshade::launch(MyGame::default())
}

#[derive(Default)]
struct MyGame;

impl State for MyGame {
    fn title(&self) -> &str {
        "My First Game"
    }

    fn initialize(&mut self, world: &mut World) {
        world.resources.graphics.show_grid = true;
        world.resources.graphics.atmosphere = Atmosphere::Sky;

        let camera = spawn_camera(
            world,
            Vec3::new(0.0, 5.0, 10.0),
            "Main Camera".to_string(),
        );
        world.resources.active_camera = Some(camera);

        spawn_sun(world);

        spawn_cube_at(world, Vec3::new(0.0, 1.0, 0.0));
        spawn_cube_at(world, Vec3::new(3.0, 0.5, 0.0));
        spawn_cube_at(world, Vec3::new(-2.0, 1.5, 2.0));
    }

    fn run_systems(&mut self, world: &mut World) {
        fly_camera_system(world);
        escape_key_exit_system(world);
    }
}

Controls

With the fly camera system enabled:

KeyAction
W/A/S/DMove forward/left/back/right
SpaceMove up
ShiftMove down
MouseLook around
EscapeExit

Next Steps

Now that you have a basic scene, explore: