@awesome-ecs/abstract

A comprehensive Entity-Component-System (ECS) Architecture implementation. Abstract components.


Keywords
entity, component, system, ecs, architecture, runtime, abstract, engine, game, typescript
License
Apache-2.0
Install
npm install @awesome-ecs/abstract@0.18.0

Documentation

Awesome ECS (Entity-Component-System)

What is it?

The Entity-Component-System is a well-known Architecture type used for responsive, complex applications, not only restricted to the Web. It's mostly associated with Game Engines, because of it's way of segregating Behavior from State, and allowing fine-control of the Runtime.

Considerations & Restrictions

Since this ECS implementation is meant to run in the Browser, there's a few considerations to keep in mind:

  • we're using Javascript, so every Tick and any work being done on the Main Thread counts, no matter how small
  • limit the number of Entity updates needed, to strictly needed. If an Entity doesn't require an update, don't update it
    • this restriction made the current implementation move away from 'run Systems over all Components' approach, that some ECS implementation afford on Desktop environments, or written in native languages (e.g. C, C++)
  • have fine-tuned control on how often Ticks run
  • have fine-tuned control on how much a Tick can afford to run for
  • allow easy access between Entities (Entities have 'proxy' relationships between each other)
  • create abstractions for Building Blocks of the ECS, and provide good implementations to reuse functionality
  • the ECS system can allow, by design, writing and loading of Mods (useful in extending Game functionality by the Community)
  • provide debug/performance tools by the means of abstraction
  • Composition over Inheritance by design - thus, a Dependency Injection container is needed (and very useful!)
  • Web Workers are just an extension point of this ECS implementation. Work is queued to the Thread, Messages are Entity Updates queued for Runtime in the main thread

The current implementation provides good defaults to use directly, or you can roll your own implementation using the Typescript abstractions provided within.

Building blocks

Entities

Entities are really just collections of Components.

In this Awesome ECS Architecture implementation, an Entity is built of:

  • one or more Components
  • proxies to other Entities

Entity changes can triggered from outside systems (e.g. UI events, data from backend, a Redux Store change), or on ran a Schedule (e.g. Engine Loop).

Components

Components are data-holders. They are instantiated for each Entity, and hold the state for the Entity. An Entity can have many different types of Components, based on what the Entity State is.

Components should not contain any behavior, only keep data (e.g. Plain-Objects).

Systems

Systems are behaviors of the ECS Architecture. They receive an Entity as input, and run Behaviors, altering the data contained in the Entity's Components. Systems are usually Entity-specific, but they can be shared (e.g. Two Entities having the same Component Type, can in fact, share a System's Behavior).

Awesome ECS Architecture

Pipeline

The Pipelines are at the heart of the Easy ECS Architecture implementation, and it's a way of declaring which Systems are run as part of the Runtime Loop.

Middleware

The Middleware is the Unit-of-Work implementation of a System, and allows for a System to achieve Single-Responsibility (part of SOLID principles.).

A Middleware has 3 methods:

  • shouldRun: boolean -> specifies whether the current System should run it's action method, to introduce State changes on the Entity's Components
  • action: void -> the System implementation that allows for altering Entity Component state, can use Entity Proxies, or Schedule updates for itself or other Entities
  • cleanup: void -> the System implementation method that gets called when the Entity Model Change Type is Removed. It handles the disposal of any internal objects the System might have instantiated

Each Middleware method will receive a context: SystemPipelineContext<TEntity>, which contains the current Entity state, as well as the Entity Model Change, and any Entity changes Scheduled for Dispatch at the end of the current Tick

Entity Changes

Each Entity has a mandatory Identity Component. This Identity Component will hold the current Entity Model, and it's Entity Unique Identifier. Model changes will prompt an Entity to introduce itself on a Entity Change Queue, to be processed on the next Tick by the Runtime.

The Runtime

The Awesome ECS Architecture implementation Runtime is structured in Loops of Ticks.

Each Tick has an allocated time for running, and will process Entity Changes during that Tick. If there is more time left in the current Loop, and the Entity Change Queue is not empty, the next Entity Change in the Entity Change Queue, will be processed.

The Ticks

Each Tick will receive as an input an Entity Model Change, which will contain: the Current Model, the Previous Model (if available), and the Change Type (Added, Updated or Removed).

Based on the Change Type and Model, the Entity Identifier is being searched. Based on the found Entity Identifier and Change Type, The Runtime instantiates the System Pipeline associated with that change.

Runtime Stages

The Runtime has a few Stages, that will run in this order:

  • Initializer Systems
  • Updater Systems
  • Renderer Systems
  • (Dispatcher) Systems

Each Stage is a System Pipeline, which will run it's associated System Middlewares, in the order they were registered in.

Generator Systems

The Generator Systems will be ran once per Entity, when the Model Change Type is Added. All the Middlewares registered for this stage will contribute to enrich the Entity Components with bootstrap data.

Updater Systems

The Updater Systems will be ran on each Model Change, and it's the main way of altering the Entity's Components state.

Render Systems

The Render Systems will make sure to update the underlying Render system with the Entity's RenderingComponent state. It's useful as an abstraction layer to lower-lever Rendering (e.g. a Game Engine, WebGL, Canvas)

The Render Systems can be skipped from the Runtime, if needed. That can be useful to simulate the same Runtime in a non-rendered system, like the Backend.

(Dispatch) Systems

The Dispatch Systems are built-in Systems in the Awesome ECS, and will take care of Dispatching Actions, Scheduling Entity updates, or synchronizing the Entity Repository with the latest Entity State in the current Context.

The Dispatch Systems, as well as any other Runtime Stage, can be extended as needed by registering more System Middlewares in the Stage Pipeline.

Integrating the Awesome ECS Architecture implementation

-- to do --

Examples

-- to do --

References & Inspiration