You will make the default cube spin and bob up and down, then check the
motion with an automated test. You need a project made as in
Getting started; this page calls it Hello Cube.
1. Look at the starting code
Open src/main.rs (in the editor, switch an area to Code Editor):
use rusting_engine::prelude::*;
fn update(_scene: &mut GameScene<'_>, _time: &FrameTime) {
// Add game behaviour here.
}
rusting_game!(update);rusting_game! writes main for you. It loads the cooked scene and calls
update once per frame with:
scene: access to the objects in the scene, by name.time: the frame’sFrameTime(delta_seconds(),elapsed_seconds(),fixed_tick, …).
2. Spin and bob the cube
Replace the file with:
use rusting_engine::prelude::*;
fn update(scene: &mut GameScene<'_>, time: &FrameTime) {
let t = time.elapsed_seconds();
scene
.object("Cube")
.rotate_y(1.5 * time.delta_seconds())
.set_position([0.0, (t * 2.0).sin(), 0.0]);
}
rusting_game!(update);scene.object("Cube")finds the object namedCube. It panics with a clear message if there is none; usescene.try_object(name)when the object may be missing.rotate_yadds an angle in radians. Multiplying bydelta_seconds()makes the speed 1.5 radians per second on any frame rate.set_positionsets the position directly. Other methods:move_by,move_x/y/z,set_rotation,rotate_by,rotate_x/z,set_scale, andposition()to read it. They chain.
3. Run it
In the editor, press Play. From a terminal:
rusting run "Hello Cube"(Run the CLI from the engine checkout as ./target/debug/rusting, or put it
on your PATH.)
The cube spins and moves up and down once every π seconds.
4. Add objects in the editor
- Press the add button (
+, “Add object”) at the top of the Hierarchy, openMeshes, and chooseSphere. - Rename it to
Moon(double-click the row, orF2). - With the Moon selected, hover the Scene View, press
RthenX, and move the mouse to slide it along X. Left-click to confirm; right-click orEscapecancels. - Save the scene with
Ctrl+S.
Now add one line to update to make it orbit:
scene.object("Moon").set_position([3.0 * t.cos(), 0.0, 3.0 * t.sin()]);Every edit in the editor goes through Undo (Ctrl+Z).
5. Spawn objects from code
For objects made by code, spawn them once with scene.once, which runs its
closure the first time only:
scene.once("make_ring", |scene| {
let cube = CubeSpawn::new();
for index in 0..12 {
let angle = index as f32 / 12.0 * std::f32::consts::TAU;
scene.spawn_cube(
format!("Ring {index}"),
Transform::new([5.0 * angle.cos(), 0.0, 5.0 * angle.sin()]),
&cube,
);
}
});Spawned names must be unique, like any object name. spawn_sphere,
create_material, spawn_cube_with_material, and
set_background_color work the same way.
6. Test it without a window
Save this as bob.scenario.json in the project folder:
{
"name": "the cube bobs and spins",
"seed": 1,
"ticks": 30,
"steps": [
{"tick": 30, "expect": {"entity": "Cube", "path": "/transform/position/1", "greater_than": 0.5}},
{"tick": 30, "expect": {"entity": "Cube", "path": "/transform/rotation/1", "greater_than": 0.5}}
]
}rusting test "Hello Cube" "Hello Cube/bob.scenario.json"Scenario "the cube bobs and spins": passed after 30 ticks, seed 1After 30 ticks (half a second) the cube is at sin(1.0) ≈ 0.84 and has
turned 0.75 radians. A scenario runs one tick per update, so the numbers are
the same on every machine. Break the code (remove rotate_y) and the test
fails with the tick, the step, and the value it saw.
What you learned
rusting_game!and the per-frameupdatefunction.- Finding objects by name and changing their transforms.
- Spawning objects once from code.
- Scenario tests.
The short API has no input access. For keyboard control, ECS systems, and your own components, see Tutorial 3. Next, Tutorial 2 builds a whole game from built-in pieces.