The engine

by Arturo Castro

Namave is developed using rin, a creative coding framework / game engine hybrid based on the Rust programming language that I've developed while working on the game.

I started working on rin around 2014, first as a way to learn Rust but with time, what was a little experiment, became a useful toolkit. At some point Carolina and I decided to do videogames together and I started adding game engine features to rin that until then had a structure much more similar to a traditional creative coding framework.

While this happened more or less coincidentally, that mixed nature gives rin some very interesting properties.

For example, rin it's purely code oriented: the only way to create an application is to write code, there's no gui in which you can add elements or add code to specific objecs as in most traditional game engines. But at the same time the gui in rin happens in a very natural way. For example everytime you add an addon to your application it can create a gui by itself which makes it really straightforward to change properties for anything in the application.

Also, rin allows to draw to the screen in immediate mode as in any traditional creative coding framework, for example:

renderer.draw_circle(pnt2(window.width() / 2., window.height() / 2.), 50.);

Draws a circle in the middle of the screen.

But it can also be used as a full featured scenegraph with materials, cascaded shadow maps, static and dynamic flags for optimizations or postprocessing effects among other features. in which case you don't draw things to the screen but just add entities to the scene and rin makes sure to render them in the most optimized way possible.

Here's an example of how to use rin to draw a simple scene:


let camera = arcball_camera::Builder::new(scene.events_stream(), scene.window().size())
    .position(pnt3(0., 3., 3.))
    .look_at(Pnt3::origin())
    .up_axis(Vec3::z_axis())
    .create();
scene.set_camera(camera);

let cube = graphics::cube(1.);
let cube = scene.add_mesh(cube);
let red_material = StandardMaterialBuilder::default().color(RED).build();
let red_material = scene.register_material("red", red_material);
scene.add_model("cube")
    .geometry(cube)
    .material(red_material)
    .build();


let ground = graphics::plane(vec2(10., 10.), 1, 1);
let ground = scene.add_mesh(ground);
let white_material = StandardMaterialBuilder::default().color(WHITE).build();
let white_material = scene.register_material("white", white_material);
scene.add_model("ground")
    .geometry(ground)
    .material(white_material)
    .transformation(pnt3(0., 0., -0.5))
    .build();

let light_trafo = Node::new_look_at(pnt3(3., 3., 3.), Pnt3::origin(), Vec3::z());
let shadow_params = shadow::Parameters{
    map_size: 1024,
    resolution: shadow::Resolution::_32,
    left: -10.,
    right: 10.,
    bottom: -10.,
    top: 10.,
    near_clip: 2.,
    far_clip: 20.,
    bias: 0.0005,
    depth_clamp: false,
};
let light0 = scene.add_directional_light("light0")
    .radius(0.4)
    .shadow_map(shadow_params)
    .shadow_type(shadow::Type::PCSS)
    .dynamic_transformation(light_trafo)
    .build();

Which renders:

red cube

Most of the video game engine aspects for rin where added while developing Namave which meant that the game took longer than it would have taken if we had use a premade game engine but at this point rin has pretty much everything we need and although I keep adding some features or fixing some APIs from time to time adding new elements to the game is really straightforward now.

The engine

by Arturo Castro

Namave is developed using rin, a creative coding framework / game engine hybrid based on the Rust programming language that I've developed while working on the game.

I started working on rin around 2014, first as a way to learn Rust but with time, what was a little experiment, became a useful toolkit. At some point Carolina and I decided to do videogames together and I started adding game engine features to rin that until then had a structure much more similar to a traditional creative coding framework.

While this happened more or less coincidentally, that mixed nature gives rin some very interesting properties.

For example, rin it's purely code oriented: the only way to create an application is to write code, there's no gui in which you can add elements or add code to specific objecs as in most traditional game engines. But at the same time the gui in rin happens in a very natural way. For example everytime you add an addon to your application it can create a gui by itself which makes it really straightforward to change properties for anything in the application.

Also, rin allows to draw to the screen in immediate mode as in any traditional creative coding framework, for example:

renderer.draw_circle(pnt2(window.width() / 2., window.height() / 2.), 50.);

Draws a circle in the middle of the screen.

But it can also be used as a full featured scenegraph with materials, cascaded shadow maps, static and dynamic flags for optimizations or postprocessing effects among other features. in which case you don't draw things to the screen but just add entities to the scene and rin makes sure to render them in the most optimized way possible.

Here's an example of how to use rin to draw a simple scene:


let camera = arcball_camera::Builder::new(scene.events_stream(), scene.window().size())
    .position(pnt3(0., 3., 3.))
    .look_at(Pnt3::origin())
    .up_axis(Vec3::z_axis())
    .create();
scene.set_camera(camera);

let cube = graphics::cube(1.);
let cube = scene.add_mesh(cube);
let red_material = StandardMaterialBuilder::default().color(RED).build();
let red_material = scene.register_material("red", red_material);
scene.add_model("cube")
    .geometry(cube)
    .material(red_material)
    .build();


let ground = graphics::plane(vec2(10., 10.), 1, 1);
let ground = scene.add_mesh(ground);
let white_material = StandardMaterialBuilder::default().color(WHITE).build();
let white_material = scene.register_material("white", white_material);
scene.add_model("ground")
    .geometry(ground)
    .material(white_material)
    .transformation(pnt3(0., 0., -0.5))
    .build();

let light_trafo = Node::new_look_at(pnt3(3., 3., 3.), Pnt3::origin(), Vec3::z());
let shadow_params = shadow::Parameters{
    map_size: 1024,
    resolution: shadow::Resolution::_32,
    left: -10.,
    right: 10.,
    bottom: -10.,
    top: 10.,
    near_clip: 2.,
    far_clip: 20.,
    bias: 0.0005,
    depth_clamp: false,
};
let light0 = scene.add_directional_light("light0")
    .radius(0.4)
    .shadow_map(shadow_params)
    .shadow_type(shadow::Type::PCSS)
    .dynamic_transformation(light_trafo)
    .build();

Which renders:

red cube

Most of the video game engine aspects for rin where added while developing Namave which meant that the game took longer than it would have taken if we had use a premade game engine but at this point rin has pretty much everything we need and although I keep adding some features or fixing some APIs from time to time adding new elements to the game is really straightforward now.

Coming in 2021 to