<commit_before>---
title: Entity-Component-System
type: introduction
layout: docs
order: 5
---

[ecs]: https://wikipedia.org/wiki/Entity_component_system

A-Frame is a three.js framework with an [entity-component-system][ecs] (ECS)
architecture. ECS architecture is a common and desirable pattern in 3D and game
development that follows the **composition over inheritance and hierarchy**
principle.

The benefits of ECS include:

1. Greater flexibility when defining objects by mixing and matching reusable parts.
2. Eliminates the problems of long inheritance chains with complex interwoven functionality.
3. Promotes clean design via decoupling, encapsulation, modularization, reusability.
4. Most scalable way to build a VR application in terms of complexity.
5. Proven architecture for 3D and VR development.
6. Allows for extending new features (possibly sharing them as community components).

On the 2D Web, we lay out elements that have fixed behavior in a hierarchy. 3D
and VR is different; there are infinite types of possible objects that with
unbounded behavior. ECS provides a manageable pattern to construct types of
objects.

Below are great introductory materials to ECS architecture. We recommend
skimming through them to get a better grasp of the benefits. ECS is well-suited
for VR development, and A-Frame is based entirely around this paradigm:

- [*Entity-component-system* on Wikipedia](https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system)
- [*What is an Entity System?* by <NAME>](http://t-machine.org/index.php/2007/11/11/entity-systems-are-the-future-of-mmog-development-part-2/)
- [*Decoupling Patterns &mdash; Component* on Game Programming Patterns](http://gameprogrammingpatterns.com/component.html)
- [*Evolve Your Hierarchy* by <NAME>](http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/)

A well-known game engine implementing ECS is Unity. Although there are pain
points in cross-entity communication. But we'll see how A-Frame, the DOM, and
declarative HTML really make ECS shine.

<!--toc-->

## Concept

[entity]: ../core/entity.md
[component]: ../core/component.md
[system]: ../core/systems.md

![ECS Minecraft](https://cloud.githubusercontent.com/assets/674727/20289898/71f7fea0-aa91-11e6-8307-d8dc68dff285.png)

A basic definition of ECS involves:

- **[Entities][entity]** are container objects into which components can be
  attached. Entities are the base of all objects in the scene. Without
  components, entities neither do nor render anything, similar to empty `<div>`s.
- **[Components][component]** are reusable modules or data containers that can
  be attached to entities to provide appearance, behavior, and/or
  functionality. Components are like plug-and-play for objects. All logic is
  implemented through components, and we define different types of objects by
  mixing, matching, and configuring components. Like alchemy!
- **[Systems][system]** provide global scope, management, and services for
  classes of components. Systems are often optional, but we can use them to
  separate logic and data; systems handle the logic, components act as data
  containers.

### Examples

Some abstract examples of different types of entities built from composing
together different components:

- `Box = Position + Geometry + Material`
- `Light Bulb = Position + Light + Geometry + Material + Shadow`
- `Sign = Position + Geometry + Material + Text`
- `VR Controller = Position + Rotation + Input + Model + Grab + Gestures`
- `Ball = Position + Velocity + Physics + Geometry + Material`
- `Player = Position + Camera + Input + Avatar + Identity`

As another abstract example, imagine we want to build a car entity by
assembling components:

- We can attach a `material` component that has properties such as "color" or
  "shininess" that affects the appearance of the car.
- We can attach an `engine` component that has properties such as "horsepower" or
  "weight" that affects the functionality of the car.
- We can attach a `tire` component that has properties such as "number of
  tires" or "steering angle" that affects the behavior of the car.

So we can create different types of cars by varying the properties of the
`material`, `engine`, and `tire` component. The `material`, `engine`, and
`tire` components don't have to know about each other and can even be used in
isolation for other cases. We could mix and match them to create even
different types of vehicles:

- To create a *boat* entity: remove the `tire` component.
- To create a *motorcycle* entity: change `tire` component's number of tires to 2,
  configure the `engine` component to be smaller.
- To create an *airplane* entity: attach `wing` and `jet` components.

Contrast this to traditional inheritance where if we want to extend an object,
we would have to create a large class that tries to handle everything or an
inheritance chain.

## ECS in A-Frame

A-Frame has APIs that represents each piece of ECS:

- **Entities** are represented by the `<a-entity>` element and prototype.
- **Components** are represented by HTML attributes on `<a-entity>`'s. Underneath,
  components are objects containing a schema, lifecycle handlers, and methods.
  Components are registered via the `AFRAME.registerComponent (name, definition)`
  API.
- **Systems** are represented by `<a-scene>`'s HTML attributes. System are
  similar to components in definition. Systems are registered via the
  `AFRAME.registerSystem (name, definition)` API.

### Syntax

[style]: https://developer.mozilla.org/docs/Web/API/HTMLElement/style

We create `<a-entity>` and attach components as HTML attributes. Most
components have multiple properties that are represented by a syntax similar to
[`HTMLElement.style` CSS][style]. This syntax takes the form with a semicolon
(`:`) separating property names from property values, and a colon (`;`)
separating different property declarations:

`<a-entity ${componentName}="${propertyName1}: ${propertyValue1}; ${propertyName2:}: ${propertyValue2}">`

[geometry]: ../components/geometry.md
[material]: ../components/material.md
[light]: ../components/light.md<commit_msg>Docs: Corrected Typo changed word semicolon to colon and vice-versa<commit_after>---
title: Entity-Component-System
type: introduction
layout: docs
order: 5
---

[ecs]: https://wikipedia.org/wiki/Entity_component_system

A-Frame is a three.js framework with an [entity-component-system][ecs] (ECS)
architecture. ECS architecture is a common and desirable pattern in 3D and game
development that follows the **composition over inheritance and hierarchy**
principle.

The benefits of ECS include:

1. Greater flexibility when defining objects by mixing and matching reusable parts.
2. Eliminates the problems of long inheritance chains with complex interwoven functionality.
3. Promotes clean design via decoupling, encapsulation, modularization, reusability.
4. Most scalable way to build a VR application in terms of complexity.
5. Proven architecture for 3D and VR development.
6. Allows for extending new features (possibly sharing them as community components).

On the 2D Web, we lay out elements that have fixed behavior in a hierarchy. 3D
and VR is different; there are infinite types of possible objects that with
unbounded behavior. ECS provides a manageable pattern to construct types of
objects.

Below are great introductory materials to ECS architecture. We recommend
skimming through them to get a better grasp of the benefits. ECS is well-suited
for VR development, and A-Frame is based entirely around this paradigm:

- [*Entity-component-system* on Wikipedia](https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system)
- [*What is an Entity System?* by <NAME>](http://t-machine.org/index.php/2007/11/11/entity-systems-are-the-future-of-mmog-development-part-2/)
- [*Decoupling Patterns &mdash; Component* on Game Programming Patterns](http://gameprogrammingpatterns.com/component.html)
- [*Evolve Your Hierarchy* by <NAME>](http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/)

A well-known game engine implementing ECS is Unity. Although there are pain
points in cross-entity communication. But we'll see how A-Frame, the DOM, and
declarative HTML really make ECS shine.

<!--toc-->

## Concept

[entity]: ../core/entity.md
[component]: ../core/component.md
[system]: ../core/systems.md

![ECS Minecraft](https://cloud.githubusercontent.com/assets/674727/20289898/71f7fea0-aa91-11e6-8307-d8dc68dff285.png)

A basic definition of ECS involves:

- **[Entities][entity]** are container objects into which components can be
  attached. Entities are the base of all objects in the scene. Without
  components, entities neither do nor render anything, similar to empty `<div>`s.
- **[Components][component]** are reusable modules or data containers that can
  be attached to entities to provide appearance, behavior, and/or
  functionality. Components are like plug-and-play for objects. All logic is
  implemented through components, and we define different types of objects by
  mixing, matching, and configuring components. Like alchemy!
- **[Systems][system]** provide global scope, management, and services for
  classes of components. Systems are often optional, but we can use them to
  separate logic and data; systems handle the logic, components act as data
  containers.

### Examples

Some abstract examples of different types of entities built from composing
together different components:

- `Box = Position + Geometry + Material`
- `Light Bulb = Position + Light + Geometry + Material + Shadow`
- `Sign = Position + Geometry + Material + Text`
- `VR Controller = Position + Rotation + Input + Model + Grab + Gestures`
- `Ball = Position + Velocity + Physics + Geometry + Material`
- `Player = Position + Camera + Input + Avatar + Identity`

As another abstract example, imagine we want to build a car entity by
assembling components:

- We can attach a `material` component that has properties such as "color" or
  "shininess" that affects the appearance of the car.
- We can attach an `engine` component that has properties such as "horsepower" or
  "weight" that affects the functionality of the car.
- We can attach a `tire` component that has properties such as "number of
  tires" or "steering angle" that affects the behavior of the car.

So we can create different types of cars by varying the properties of the
`material`, `engine`, and `tire` component. The `material`, `engine`, and
`tire` components don't have to know about each other and can even be used in
isolation for other cases. We could mix and match them to create even
different types of vehicles:

- To create a *boat* entity: remove the `tire` component.
- To create a *motorcycle* entity: change `tire` component's number of tires to 2,
  configure the `engine` component to be smaller.
- To create an *airplane* entity: attach `wing` and `jet` components.

Contrast this to traditional inheritance where if we want to extend an object,
we would have to create a large class that tries to handle everything or an
inheritance chain.

## ECS in A-Frame

A-Frame has APIs that represents each piece of ECS:

- **Entities** are represented by the `<a-entity>` element and prototype.
- **Components** are represented by HTML attributes on `<a-entity>`'s. Underneath,
  components are objects containing a schema, lifecycle handlers, and methods.
  Components are registered via the `AFRAME.registerComponent (name, definition)`
  API.
- **Systems** are represented by `<a-scene>`'s HTML attributes. System are
  similar to components in definition. Systems are registered via the
  `AFRAME.registerSystem (name, definition)` API.

### Syntax

[style]: https://developer.mozilla.org/docs/Web/API/HTMLElement/style

We create `<a-entity>` and attach components as HTML attributes. Most
components have multiple properties that are represented by a syntax similar to
[`HTMLElement.style` CSS][style]. This syntax takes the form with a colon
(`:`) separating property names from property values, and a semicolon (`;`)
separating different property declarations:

`<a-entity ${componentName}="${propertyName1}: ${propertyValue1}; ${propertyName2:}: ${propertyValue2}">`

[geometry]: ../components/geometry.md
[material]: ../components/material.md
[light]: ../components/light.md
{'fraction_non_alphanumeric': 0.08955223880597014, 'fraction_numerical': 0.012329656067488644, 'mean_word_length': 4.658100045892612, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5991185', 'n_tokens_mistral': 3464, 'n_tokens_neox': 3248, 'n_words': 1524}