2个版本
0.1.1 | 2021年5月8日 |
---|---|
0.1.0 | 2021年5月8日 |
947 在 游戏开发
130KB
3K SLoC
Chunked ECS
此仓库包含Chunked ECS。
它是做什么的?
实体组件系统(ECS)将数据和行为分开建模,通常用于游戏。ECS的一个优点是可以隔离单个行为(提高复用性)并批量管理组件(这可能会导致一些非常棒的优化)。
为什么我应该使用Chunked?
说实话,到现在为止,你可能不应该使用它。它基本上只是一个玩具项目。然而,如果你仍然感兴趣
-
Chunked将类似的实体组织到块中,而不是按组件或实体组织。这可以减少分配负载,同时仍然允许结构化数组在并行计算中的优势。
-
所有组件都必须实现
Copy
,这使得更新块需要很少的处理。 -
对世界的所有操作都是通过快照完成的,快照在写入时被复制。这使得您可以拍摄快照。
例如,这可以用于在更新之间将最新的快照复制到渲染线程,从而允许无阻塞的渲染线程。
-
创建世界非常便宜。
世界是一个当前快照的包装器。Archetypes和块自由列表存储在宇宙中。宇宙在快照和世界之间共享。
-
可以并行执行世界级别的交易。等待交易成为可能使用async/await完成。
-
Rayon 支持,并推荐用于实体更新。
它看起来像什么?
#[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);
}
}
为什么还需要另一个ECS crate?
此库将类似“形状”的实体排序到固定大小的块中,而不是管理同一类型的所有组件。
此crate还实现了整个世界状态的Copy-on-Write方法,这意味着您可以拍摄快照。这种特定用例是在单独的线程中进行渲染和运行世界更新。
说实话,这主要是因为挑战。 ;)
为什么是 Rust?
Rust 是一种非常高性能且易于使用的系统编程语言。作为一个为游戏设计的ECS库,性能至关重要。Rust的安全性使其成为实现游戏中所需低级系统的理想选择。此外,如果需要在高级语言中使用,可能最好公开一个更简单的抽象。
项目结构
packages/chunked
- 实现ECS的核心包。examples/orbits
- 一个N-Body模拟示例。
许可证
本项目采用MIT许可证授权。
依赖项
约4-6MB
约107K SLoC