# ECS Guidelines

Welcome to the core of our game's architecture, the Entity Component System (ECS)! This innovative and efficient system is the backbone of our game's design, allowing for flexible, reusable, and modular game object management. Let's dive into how it works and how you can utilize it for creating other games.

### What is ECS? 🤔

ECS is a design pattern that allows you to decouple your game's logic from the data. It consists of:

* **Entities**: Unique identifiers for game objects.
* **Components**: Raw data containers for different aspects of the game objects.
* **Systems**: Logic that processes components of entities.

This approach differs from traditional object-oriented programming, where an object's data and behavior are intertwined. With ECS, the data is separated into components, and behavior is handled by systems.

### How Does It Work? 🛠️

* **Entities** are minimalistic constructs; they are essentially IDs (like an int). They don't contain any data or behavior themselves.
* **Components** are pure data structures (like structs in C++) that hold information about the entity. For example, a `PositionComponent` might hold x and y coordinates.
* **Systems** work on entities that have a specific set of component types. For instance, a `RenderingSystem` might process every entity that has both `PositionComponent` and `SpriteComponent`.

### Setting Up Entities and Components 🏗️

To create an entity and components in our game:

```cpp
Entity player = registry.createEntity();
registry.addComponent<PositionComponent>(player, xPos, yPos);
registry.addComponent<SpriteComponent>(player, spriteData);

```

### Components Deep Dive 🧐

Components are the building blocks of our ECS. They hold the data for the entities but contain no logic. Let's delve deeper into two fundamental components:

#### PositionComponent 🌐

The `PositionComponent` is crucial for defining the location of an entity in the game world. It typically contains `x` and `y` coordinates that determine where an entity should be rendered or checked for collisions.

Here's how you might define it:

```cpp
struct PositionComponent {
    float x, y;

    PositionComponent(float xCoord, float yCoord) : x(xCoord), y(yCoord) {}
};

```

And here's how you'd add it to an entity:

```cpp
Entity player = registry.createEntity();
registry.addComponent<PositionComponent>(player, 100.0f, 200.0f); // Player starts at (100, 200)

```

#### SpriteComponent 🎨

The `SpriteComponent` holds the visual representation of an entity. It can contain a texture ID, frame information for animations, and other render-related data.

Here's a simplified version:

```cpp
struct SpriteComponent {
    int textureId; // Identifier for the texture resource
    int frameIndex; // Current frame of the sprite for animation
    int frameCount; // Total number of frames for the sprite

    SpriteComponent(int texId, int index, int count)
        : textureId(texId), frameIndex(index), frameCount(count) {}
};

```

Adding a `SpriteComponent` to an entity might look like this:

```cpp
Entity player = registry.createEntity();
registry.addComponent<SpriteComponent>(player, textureId, 0, 5); // Player's sprite with textureId, starting at frame 0 with 5 total frames

```

When implementing the `RenderingSystem`, it would look for entities with both `PositionComponent` and `SpriteComponent` and render them accordingly:

```cpp
class RenderingSystem : public System {
public:
    void update(float deltaTime) override {
        for (const auto& entity : entities) {
            auto posComp = registry.getComponent<PositionComponent>(entity);
            auto spriteComp = registry.getComponent<SpriteComponent>(entity);
            if (posComp && spriteComp) {
                renderSprite(posComp->x, posComp->y, spriteComp->textureId, spriteComp->frameIndex);
            }
        }
    }

    void renderSprite(float x, float y, int textureId, int frameIndex) {
        // Your rendering code goes here
    }
};

```

By keeping the position and sprite data separate from the logic, you can easily move, animate, and reuse entities in various contexts.

### Implementing Systems 🔄

Systems need to be designed to operate on entities with specific components. Here's a simplified example of a movement system:

```cpp
class MovementSystem : public System {
public:
    void update(float deltaTime) {
        for (auto& entity : entities) {
            auto& pos = entity.getComponent<PositionComponent>();
            pos.x += velocity.x * deltaTime;
            pos.y += velocity.y * deltaTime;
        }
    }
};

```

You would register this system and let it run every game loop iteration.

### Advantages of ECS 🌟

* **Flexibility**: Easily add or change features by creating new systems or modifying components.
* **Performance**: Systems can process entities in a cache-friendly way.
* **Modularity**: Swap out components and systems without affecting unrelated parts of the codebase.

### How To Use ECS for Another Game? 🔄

To use ECS in another game, you need to identify the game's distinct aspects that can be broken down into entities, components, and systems. Here’s a quick guide:

1. **Identify Entities**: These could be players, enemies, or interactive objects.
2. **Define Components**: What data describes these entities? Position, health, and graphics could be examples of components.
3. **Implement Systems**: Write logic for rendering, physics, AI, etc., as separate systems.

### Visual Aids 🖼️

To aid understanding, consider adding diagrams or flowcharts that:

* Show the relationship between entities, components, and systems.
* Visualize the game loop processing the systems.
* Illustrate an example of entity creation with components.

### Conclusion and Tips 📝

ECS is a powerful pattern that can revolutionize your game development process. It's all about composition over inheritance, about flexibility and performance. Embrace ECS, and you'll find your game architecture becoming more robust and adaptable

Remember:

* Keep your components granular.
* Systems should be as independent as possible.
* The more you work with ECS, the more intuitive it becomes!

Happy coding, and may your game logic be ever modular and your entities forever dynamic! 🚀


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://r-type-5.gitbook.io/r-type/development-guidelines/ecs-guidelines.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
