Title: An Entity Component System in Javascript
Slug: ecs-in-javascript
Date: 2023-12-21 11:50:00
Author: Kartones
Lang: en
Tags: Development, Game Dev, Javascript, Architecture
og_image:
Description: An implementation of an Entity Component System (ECS) architecture pattern in JavaScript, with code and demo both provided.


Taking advantage of my Christmas holidays, one topic I had pending exploring was the [Entity component system (ECS)](https://en.wikipedia.org/wiki/Entity_component_system) architecture pattern. It is used primarily in video-games, but it is fascinating because of the radical departure from object inheritance, heavily leaning into object composition instead.

One of the best ways to learn is to a) read and then b) experiment, so I went and built a minimal (but representative) vanilla Javascript ECS implementation. 

For the impatient, the code is available here: [https://github.com/Kartones/ecs](https://github.com/Kartones/ecs), and a basic HTML demo is here: [https://kartones.net/demos/028/](https://kartones.net/demos/028/).

I'll remark on a few technical details, but if you want to see how everything fits, the code is compact and easy to read.

I created three systems:

- `InputSystem`: To handle (keyboard) input. It interacts with `PositionComponent` components, by modifying their velocity "vectors" and/or changing positions when the `Spacebar` is pressed (resets all entities to new random positions).
- `MovementSystem`: Updates `PositionComponent` components movement logic: update position based on velocity, or stop if at a boundary (edge)
- `RenderSystem`: Initializes the screen (an HTML canvas) and tells `RenderComponent` components to render based on their `PositionComponent` values.

As you might have noticed, there are two components:

- `PositionComponent`: Keeps `(x,y)` and a velocity vector
- `RenderComponent`: Keeps the "sprite" data

And finally, a few managers:

- `EntityManager`: Entities do not exist as a class; they are mere identifiers. The sole purpose of `EntityManager` is to generate the entity IDs and keep track of them
- `ComponentManager`: Keeps track of all components of each entity. When a system is going through an update sweep, queries this manager to ask for all components required; e.g., the `RenderSystem` asks for `PositionComponent` and `RenderComponent`, ensuring that any entity has both (or will be skipped)
- `SystemManager`: A simple list of all configured systems, plus an `update()` method that, surprise, triggers an update cycle on all systems


And that is mostly everything! At first, I tried to plug in [Phaser](https://phaser.io/) for rendering graphics and handling input, but it is already an ECS! So, instead of doing weird code to access some of the systems, I discarded it and implemented a simple keyDown handler for the input and an HTML canvas for the renderer. Still, Phaser looks so nice and well-structured, that I'll try it as a complete game engine in the future.