Skip to content
This repository has been archived by the owner on Dec 21, 2022. It is now read-only.

Basic concepts

Alex Goldring edited this page Jan 28, 2022 · 2 revisions

The engine's is built around ECS architecture. ECS stands for Entity Component System

  • Entity is any object in the world, and in meep it's just a number, a unique integer like 0,1,2,3
  • Component is some aspect of a world object. Multiple components are "attached to" each entity to make something useful. For example, if you wanted to add a box in into your world, you would need 2 components: Mesh (for the 3d model of the box) and Transform (for defining the position, scale and rotation of the said entity).
  • System is something defined behaviour on a set of component types. For example, if you wanted to add a very simple gravity into your world, you could create a system that world on Transform components and moves them down every simulation update. The system has 3 major parts:
    • update(time_delta:number){...} this is called by the simulator every update tick, and gives you a chance to do something useful. Like iterate over a set of components for each entity and modify them in some way. Like in the example above, you could apply some downwards displacement on each Transform by doing transform.position.y -= GRAVITY * time_delta where GRAVITY is some constant value like 10.
    • observed component tuple. This is a defined set of component types that the system observes, link and unlink are called by the simulator and the corresponding set of components is passed in. Example: if you declare observed tuple [Mesh, Transform] - then the link signature will look like this: link(mesh:Mesh, transform:Transform, entity:number) and the engine will guarantee that the entity has both of those components attached before link is called.
    • link<T>(component:T, entity:number)/unlink<T>(component:T, entity:number) these are called by the simulator whenever a tuple of observed components is completed (link) or broken - that is one or more components of the tuple are removed or the entity is destroyed (inlink)

Here's a very simple gravity system described earlier:

class Falling{
   // this is a component for things that can fall
}

class SimpleGravitySystem extends System{
   constructor(){
      super();
      this.dependencies = [Falling, Transform];
   }
   
   update(time_delta){
      this.entityManager.dataset.traverseEntities([Falling, Transform], (falling, transform, entity)=>{

         // stop falling at Y=0, mimicking a floor
         if(transform.position.y > 0){
            const fall_distance = -10 * time_delta;
            // move entity down
            transform.position._add(0, fall_distance, 0);
         }

      });
   }
}

When you configure the engine, you register systems like so:

engine.entityManager.addSystem(new SimpleGravitySystem());

And finally you would create, say a box that is affected by gravity like so:

new EntityBuilder()
   .add(Mesh.fromJSON({
      url:"/my/assets/box.gltf"
   }))
   .add(Transform.fromJSON({
      position:{ x:0, y:50, z:0 }
   }))
   .add(new Falling())
   .build(engine.entityManager.dataset);
Clone this wiki locally