#ecs #entity #component #scenegraph


Scenegraph for Entity Component System

11 releases

0.3.3 Sep 15, 2020
0.3.2 May 28, 2020
0.2.0 Apr 14, 2020
0.1.5 Apr 1, 2020
0.1.3 Mar 28, 2020

#187 in Game dev

25 downloads per month



Build Status LICENSE LICENSE Crates.io Documentation Demo

What is it?

Scenegraph crate for shipyard ECS

Builds on and re-exports shipyard-hierarchy

Components and Systems

See components.rs for the full list of exported components. They are mainly just thin wrappers around math primitives. systems.rs has the exported systems (these are not exported on the root, but rather as systems::*).

The way it all fits together is that Translation, Rotation, Scale and Origin are in an "update pack". This allows for changes to these to be propagated to LocalTransform automatically and efficiently when the TrsToLocal system is run.

Similarly, the changes to LocalTransform are efficiently propagated to WorldTransform when the LocalToWorld system is run. Currently this does not go through update pack and rather uses a separate DirtyTransform component, though that may change soon

It is possible to set LocalTransform directly. However, doing this will not push the changes in the other direction (e.g. to the TRS components).

Math lib interop

A minimal and efficient math library is included out of the box and there's no need to depend on anything else. However, it's very minimal with only the operations needed to handle basic transform stuff (matrix multiplication, rotation from quaternion, etc.)

If you're using nalgebra, you can convert the math structs via .into() without doing anything special. However this comes at the cost of an allocation, so you may want to use the nalgebra structs directly with no conversion (but you do pay the cost of the heavier math lib, of course). To do that, simply enable the nalgebra_transforms feature here (this will use nalgebra instead of the builtins)

Other math crates may be added in the future fairly easily since there are really only two steps:

  1. Satisfy the traits
  2. Make type aliases for Matrix4, Vec3, and Quat

Currently it's assumed that all the math is done on f64's, with helper methods to write to &[f32]'s when needed.


See code in test_transform.rs as well as the example, but it's essentially like this:

  1. Get a shipyard world (or create a new one)

  2. Call init()

  3. Spawn children via spawn_child() (either via the borrowed storages or the world helper)

  4. Update Translation, Rotation, and Scale however you want. For example, on a given entity hero:

let mut translation_storage = world.borrow::<&mut Translation>();
let translation = (&mut translation_storage).get(hero).unwrap();
translation.0.y = 200.0;
  1. Run the systems TrsToLocal and LocalToWorld


Since this builds on shipyard-hierarchy, the same methods for traversing and updating the hierarchy are available.

In general, methods are on the storages. They can be iterated and worked with more efficiently since the borrow only occurs once. Helpers like set_trs() and spawn_child() that operate on the world, are really just for the sake of convenience and "one-offs".


See issues. Also, ergonomics ;)


~70K SLoC