I've been working on it for quite some time now and I think it's in a state where I can share it.
This is an Entity Component System, if you don't know what it is you can think of it as an in-memory database. You put stuff inside (components), the ECS will give you back an ID (entity) and you can query entities that have the same components to do something with it (systems).
That's not the only way to do it, ECS is just an concept, not a fixed data structure, but I think it's well enough for a one line explanation.
Since Specs is currently the go-to ECS, here's some interesting functionalities of Shipyard:
- No need to specify systems' dependencies
- Can use SIMD on storages you request (with some limitations)
- (Not sure if Specs can do it or not) Add entities inside systems without stopping the world
Here's a simple example:
use shipyard::*;
struct Health(f32);
struct Position { x: f32, y: f32 };
struct InAcid;
impl<'a> System<'a> for InAcid {
type Data = (&'a Position, &'a mut Health);
fn run(&self, (pos, mut health): <Self::Data as SystemData>::View) {
for (pos, health) in (&pos, &mut health).iter() {
if is_in_acid(pos) {
health.0 -= 1.0;
}
}
}
}
fn is_in_acid(pos: &Position) -> bool {
// well... it's wet season
true
}
let world = World::default();
world.new_entity((Position { x: 0.0, y: 0.0 }, Health(1000.0)));
world.add_workload("In acid", InAcid);
world.run_default();
Here is an example showing a little more iterator diversity if you are curious.
And the link to the repo.
Thank you for your time