Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to ECS

Avatar for Gen Gen
July 16, 2021
38

Introduction to ECS

Learning Entity Component System

Avatar for Gen

Gen

July 16, 2021
Tweet

Transcript

  1. IAM Short introduction • Frontend engineer • Experience in browser

    based mini games • Typed Language FTW • Rust beginner @zenoplex
  2. ECS is not a silver bullet. There are yet many

    cases where inheritance-based game-model works better. DISCLAMER
  3. Problems with classical inheritance • Diamond of Death • Root

    of inheritance tree tends to cause overhead • Leaf of inheritance tree tends to be a copy from another • Tend to become less flexible when adding new feature
  4. Brief History Well known games using ECS 1998 *not confirmed

    *1 https://www.gamedevs.org/uploads/data-driven-game-object-system.pdf *2 https://www.youtube.com/watch?v=W3aieHjyNvw *3 Unity DOTS 2007 2002 entity/component*1 2018~*3 2016*2
  5. Component Describes a property • A component represents a single

    behavior or aspects of things • Component is the data for Entity • Component can be an empty “Tag” (ie. `Player`) #[derive(Clone, Copy, Debug, PartialEq)] pub struct Player { pub map_level: u32, } // Tag #[derive(Clone, Copy, Debug, PartialEq)] pub struct Enemy; #[derive(Clone, Copy, Debug, PartialEq)] pub struct Health { pub current: i32, pub max: i32, } #[derive(Clone, PartialEq)] pub struct Name(pub String); // Can even be a message #[derive(Clone, PartialEq)] pub struct MessageToDoSomething;
  6. Entity Can be anything • Sum of Component(s) • Has

    a globally unique id // Legion fn spawn_entity(commands: &mut CommandBuffer) { let entity = commands.push(( Position, Name("some name"), Render { glyph: to_cp437(template.glyph), color: ColorPair::new(WHITE, BLACK), }, )); } // Bevy fn spawn_entity(mut commands: Commands) { let texture = asset_server.load("bird.png"); let entity = commands .spawn_bundle(SpriteBundle { material: materials.add(texture.into()), transform: Transform { translation: Vec3::new(0.0, 0.0, 100.0), ..Default::default() }, ..Default::default() }) .insert_bundle(( Player, Velocity(Vec2::ZERO), Gravity(Vec2::new(0.0, GRAVITY)), )); }
  7. System query entities and components and provide game-play simulation •

    Iterates over lists of components • Read/Write to the state of component(s), resulting behavior • Access to global resources or game states // Legion #[system] #[read_component(Point)] #[write_component(FieldOfView)] pub fn fov_system(ecs: &mut SubWorld, #[resource] map: &Map) { let mut views = <(&Point, &mut FieldOfView)>::query(); views .iter_mut(ecs) .filter(|(_, fov)| fov.is_dirty) .for_each(|(pos, mut fov)| { fov.visible_tiles = field_of_view_set(*pos, fov.radius, map); fov.is_dirty = false; }); } // Bevy fn move_system(t: Res<Time>, mut q: Query<(&mut Velocity, &mut Transform, Option<&Gravity>)>) { let delta = t.delta_seconds(); q.iter_mut().for_each(|(mut v, mut t, gravity)| { t.translation.x += v.0.x * delta; t.translation.y += v.0.y * delta; if let Some(gravity) = gravity { v.0.y += (-gravity.0.y * delta).max(-MAX_VELOCITY_Y); v.0.y = v.0.y.max(-MAX_VELOCITY_Y); } }) }
  8. Component composition Using “Final Fight” as an example Guy Cody

    Hagger Pipe Food Render Position Melee Wall Jump Jump throw Pickupable Consumable
  9. What ESC tries to solve Pros of ECS • Decoupling

    of behavior and data • Flexible entities • Performance • Compact linear memory allocation • Reduce over-fetch in cache line • Parallelism
  10. Challenges of ECS Definitely not a silver bullet • Easy

    to mis-use • Component/System structure needs deep planning • It’s easy to add components/Systems but maintenance can be difficult • Hard to hide data
  11. Learning resource Books/Web pages I’ve used • Rust Sokoban •

    Specs + GGEZ by Olivia Ifrim • Hands on Rust • Excellent book on creating tile-based game with legion(ECS) and bracket- lib by Herbert Wolverson