Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 66 additions & 57 deletions docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,96 @@
<!-- import { TechnicalNote } from '@site/src/components/TechnicalNote'; -->

# The ECS Pattern
The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) is a pattern used to organize our code when writing software.
In this pattern:
- Logic is represented as `Systems`, and they define the behavior of the application
- Data is represented as `Components` that have no behavior or identifiers attached to them
- Components are attached to Entities
- `Entities` are identifiers

<TechnicalNote title="Technical Summary">
The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior.
The behavior of the application is then controlled by having separate Systems (logic) that process that data.
Systems don't need to know where that data is coming from. They only know what data is stored in the Components that they can operate on.
</TechnicalNote>
# The ECS pattern

The [Entity-Component-System (ECS)](https://en.wikipedia.org/wiki/Entity_component_system) is a software architecture pattern used to structure code efficiently.

:::note
Clicking on the `Technical Summary` note right above will open a drop-down with information about what the ECS pattern is in more advanced/technical terms.
In this pattern:

- **Logic** is represented as `systems`, which define the application's behavior.
- **Data** is stored in `components`, which do not have behavior or identifiers.
- **Entities** are identifiers that group components together.

You will find a lot of these `Technical` drop-downs throughout the guides.
Their goal is to give you extra information that is not mandatory to understand to follow the guide, but is very useful to achieve a deeper understanding of the content.
:::hint{type="info"}
**How this works**:

Don't worry if you don't fully understand what some of them explain just yet. We will get there.
- The ECS pattern represents [objects](https://en.wikipedia.org/wiki/Object_\(computer_science\)) by attaching components (data) to an entity (identifier) without behavior
- Application behavior is controlled by separate systems (logic) that process that data.
- Systems do not need to know where data comes from—they only operate on the components available to them.
:::

## Creating an Entity
Creating an Entity is as simple as calling the `createEntity()` function from iR Engine's `ECS`.
This function will return an identifier that can be used to group Components into a unique and distinct Object.
```ts
## Creating an entity

Creating an entity is as simple as calling the `createEntity()` function from iR Engine’s `ECS`.
This function returns an identifier that allows grouping components into a unique object.

```typescript
const entity = ECS.createEntity()
```

## Adding Components
Components represent data that has no behavior or identification.
The way to attach Components to Entities is by calling the `setComponent` function from iR Engine's `ECS`.
## Adding components

Components store data and have no behavior or unique identifiers.
To attach components to an entity, use the `setComponent` function from iR Engine’s `ECS`.

:::hint{type="info"}
The `setComponent` function does not return a value, but it:

<TechnicalNote>
The `setComponent` function will not return anything, but it will:
- Add the given Component to the Entity.
- Store the Component's data in the internal records of the ECS, so it can used by the engine or accessed through the API _(eg: with `getComponent` and similar functions)_.
</TechnicalNote>
- Adds the specified component to the entity.
- Stores the component’s data in the ECS, making it accessible through the API (e.g., `getComponent` and similar functions).
:::

To display an entity in iR Engine, it must have specific components:

iR Engine requires a specific set of Components in order to create an object that can be presented on the screen:
- **VisibleComponent**
- **TransformComponent**
- **PrimitiveGeometryComponent** or **MeshComponent**
- _(optional)_ **NameComponent**: Not required, but good practice.
- *(Optional)* **NameComponent**: Not required but recommended for better debugging.

### NameComponent

A `NameComponent` provides a human-readable identifier for an entity.
The assigned name appears in the **Studio** and the **debugger**, making it easier to manage entities.

### `NameComponent`
Gives a human-readable identifier to an Entity.
Whatever name you add on this field is the name that will show up in the Studio and the debugger.
They are not mandatory, but it is good practice to add them to all your entities.
```ts
```typescript
ECS.setComponent(entity, NameComponent, 'hello-world')
```
<TechnicalNote title="Clarification">
We said that an entity is an identifier, but we are also giving that identifier a `NameComponent`.
Every Entity represents its internal "name" _(aka identifier)_ as an [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which does not need to be human-readable.
And `NameComponents` give a human-readable identifier to an Entity, independent of what its UUID is.
</TechnicalNote>

:::hint{type="info"}
An entity is an identifier, yet we assign it a `NameComponent`.
Internally, every entity is identified by a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which is not human-readable.
A `NameComponent` provides a readable name while keeping the UUID unchanged.
:::

### VisibleComponent

A `VisibleComponent` makes an entity visible on the screen. Entities without this component are ignored by the renderer.

### `VisibleComponent`
Gives the Entity the ability to be visible on the screen.
Entities without this Component will be ignored by the renderer.
```ts
```typescript
ECS.setComponent(entity, VisibleComponent)
```

### `TransformComponent`
In simple terms, `TransformComponents` give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix).
There would be no way to position the Entity in 3D space without attaching this Component to the Entity.
```ts
### TransformComponent

A `TransformComponent` gives an entity a **position** in 3D space. Without this component, the entity cannot be placed in the world.

```typescript
ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) })
```
> In more technical terms, `TransformComponents` give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation).

### `PrimitiveGeometryComponent`
This Component gives Entities a primitive "visual body".
Entities without it would not have any [3D geometry](https://en.wikipedia.org/wiki/Polygon_mesh), so the renderer would not be able to draw them on the screen.
```ts
:::hint{type="info"}
In technical terms, a `TransformComponent` allows an entity to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation).
:::

### PrimitiveGeometryComponent

A `PrimitiveGeometryComponent` assigns a **primitive shape** to an entity. Without this component, the entity lacks a [3D geometry](https://en.wikipedia.org/wiki/Polygon_mesh) and will not be rendered.

```typescript
ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 })
```
> The `1` here means that we are creating a [`SphereGeometry`](https://github.com/ir-engine/ir-engine/blob/dev/packages/engine/src/scene/constants/GeometryTypeEnum.ts#L28) object.
> We will create the component using a more readable name in the next section of the tutorial.

:::hint{type="info"}
The `1` here represents a [`SphereGeometry`](https://github.com/ir-engine/ir-engine/blob/dev/packages/engine/src/scene/constants/GeometryTypeEnum.ts#L28) object.
In the next section, we will use a more readable name to create this component.
:::

Loading