#ecs #component #gamedev #chunks #entities #behavior #systems

bin+lib chunked

一种通过将实体组织到块中来工作的实体组件系统

2个版本

0.1.1 2021年5月8日
0.1.0 2021年5月8日

947游戏开发

MIT 许可证

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