Crates.io | chunked |
lib.rs | chunked |
version | 0.1.1 |
source | src |
created_at | 2021-05-08 19:22:38.520837 |
updated_at | 2021-05-08 19:23:59.027933 |
description | An Entity Component System that works by organising like entities into chunks |
homepage | https://github.com/ricky26/chunked |
repository | https://github.com/ricky26/chunked |
max_upload_size | |
id | 394967 |
size | 136,239 |
This repository houses the Chunked ECS.
Entity Component Systems model data and behaviour separately and are commonly used for games. One of the benefits of an ECS is that you can isolate individual behaviours (increasing reuse) and manage components en masse (which can lead to some pretty nice optimisations).
Honestly, at this point, you probably shouldn't. It's essentially just a toy project. However, if you're interested anyway:
Chunked organises like entities into chunks, rather than organising by component, or by entity. This can reduce allocation load and still allow the benefits of structures-of-arrays for parallel compute.
All components must implement Copy
, which makes updating chunks require
very little processing.
All operations on the world are done via snapshots, which are copied on write. This allows you to take snapshots.
This can be used, for example, to copy the latest snapshot to the rendering thread between updates, allowing for a blocking-free rendering thread.
Worlds are exceptionally cheap to create.
Worlds are a wrapper around a current snapshot. Archetypes and chunk free lists are stored in a Universe. Universes are shared between snapshots and Worlds.
World-level transactions can be done in parallel. Waiting for a transaction to be possible is done with async/await.
Rayon is supported and is recommended for entity updates.
#[derive(Debug, Clone, Copy, Default)]
pub struct MyComponent(i32);
component!(MyComponent);
fn main() {
let universe = Universe::new();
let mut command_buffer = CommandBuffer::new();
let entity = universe.allocate_entity();
command_buffer.set_component(entity, &MyComponent(3));
let mut snapshot = Arc::new(Snapshot::empty(universe.clone()));
snapshot.modify(command_buffer.iter_edits());
println!("snapshot: {:?}", snapshot);
println!("entity: {:?}", entity);
let entity_reader = snapshot.entity(entity).unwrap();
for component in entity_reader.component_types().as_slice() {
println!("component: {:?}", component);
}
}
Instead of managing all components of a type together, this library sorts entities of a similar 'shape' into fixed-size chunks.
This also crate implements a Copy-on-Write approach to the entire world state, which means that you can take snapshots. The particular use-case for this was rendering in a separate thread to running world updates.
To be honest, it was mostly just for the challenge. ;)
Rust is a very performant and ergonomic systems programming language. As an ECS library designed for use in games, performance is key. Rust's safety and ergonomics make it ideal for implementing the low-level systems needed in games. Additionally, if it needed to be used in a higher-level language, it would probably be better to expose a simpler abstraction.
packages/chunked
- The core package imlpementing the ECS.examples/orbits
- An N-Body simulation example.This project is licensed under the MIT license.