# Common Entity Components in Equilibrium Engine: Transform, GUI, and Input Guide

> Learn about core Equilibrium Engine entity components like Transform, GUI, and Input. Understand spatial matrix data, ImGui state, and peripheral input in this essential ECS guide.

- Repository: [Alexander/equilibriumengine](https://github.com/clibequilibrium/equilibriumengine)
- Tags: deep-dive
- Published: 2026-02-27

---

**Equilibrium Engine uses the flecs ECS framework where Transform, GUI, and Input are the three core entity components that store spatial matrix data, ImGui interface state, and peripheral input respectively.**

The **Equilibrium Engine** (`clibequilibrium/equilibriumengine`) implements a pure **entity component system** (ECS) architecture using the flecs library. In this design, game objects are entities—empty containers identified by unique IDs—while data lives in **entity components**: plain C structs that attach to entities and drive rendering, input handling, and UI logic. Understanding how the Transform, GUI, and Input components work is essential for building any application with this engine.

## What Are Entity Components?

In the Equilibrium Engine source code, a component is a plain C struct registered with the ECS world via boilerplate macros. Components contain no logic—only state—making them lightweight and cache-friendly. The engine organizes these definitions in the `equilibrium/components` directory and exposes import functions that register the structs with the flecs world during initialization.

Every piece of data that can be attached to an entity follows this pattern:

- A core struct (e.g., `Transform`, `Input`)
- A registration macro (`ECS_COMPONENT_DECLARE`)
- An import function (`TransformComponentsImport`, `GuiComponentsImport`, `InputComponentsImport`)

## The Three Core Entity Components

The engine provides three foundational components that appear in nearly every application: **Transform** for spatial data, **GUI** for ImGui-based interfaces, and **Input** for keyboard and mouse state.

### Transform Component

The **Transform** component stores an entity’s position, rotation, and scale as a 4×4 matrix (`mat4`) ready for the rendering pipeline. Defined in [`equilibrium/components/transform.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/transform.h), this struct is attached to any renderable entity including meshes, lights, and cameras.

Key implementation details:

- **Core struct**: `Transform` containing `mat4 value`
- **Registration**: `ECS_COMPONENT_DECLARE(Transform)`
- **Import function**: `TransformComponentsImport(world_t *world)`

The rendering system reads this matrix during the update loop in [`equilibrium/systems/transform_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/systems/transform_system.c) to compute world-space transformations.

### GUI Component

The **GUI** component group manages ImGui integration and window handling. Rather than a single struct, this module registers several related components including `GuiSystem`, `GuiContext`, `AppWindow`, `AppWindowHandle`, and `Renderer`. These are defined in [`equilibrium/components/gui.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/gui.h) and imported via `GuiComponentsImport(world_t *world)`.

The `GuiSystem` struct contains:

- `Update` callback pointer for ImGui frame logic
- Context pointer for ImGui state
- Window handle references
- Renderer backend type

Typically attached to a singleton UI entity, this component drives the immediate-mode interface rendered by systems like [`editor/systems/imgui_overlay_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/editor/systems/imgui_overlay_system.c).

### Input Component

The **Input** component aggregates raw SDL events into queryable keyboard and mouse state. Defined in [`equilibrium/components/input.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/input.h), the `Input` struct contains:

- `KeyState keys[128]` array for keyboard buttons
- `MouseState mouse` struct with position and button states
- `InputEventCallback callback` for custom event handling

Import this component using `InputComponentsImport(world_t *world)`. The [`equilibrium/systems/sdl_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/systems/sdl_system.c) file populates this component each frame, while gameplay systems query it to respond to user actions.

## Registering and Using Entity Components

Before attaching components to entities, you must import their definitions into the flecs world. This registration typically happens during engine initialization.

### Importing Component Modules

```c
#include "equilibrium/components/transform.h"
#include "equilibrium/components/gui.h"
#include "equilibrium/components/input.h"

world_t *world = ecs_init();

/* Register the three common component groups */
TransformComponentsImport(world);  // Registers Transform, Position, Scale, Rotation
GuiComponentsImport(world);        // Registers GuiSystem, GuiContext, AppWindow, Renderer
InputComponentsImport(world);      // Registers Input with KeyState and MouseState

```

*Source references: [`equilibrium/components/transform.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/transform.h), [`equilibrium/components/gui.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/gui.h), [`equilibrium/components/input.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/input.h)*

### Attaching Components to Entities

Once imported, create entities and attach components using flecs API functions:

**Adding a Transform:**

```c
ecs_entity_t player = ecs_new(world, 0);
ecs_add(world, player, Transform);

/* Initialize matrix to identity (no transform) */
Transform *t = ecs_get_mut(world, player, Transform, NULL);
glm_mat4_identity(t->value);

```

**Setting up GUI:**

```c
ecs_entity_t ui = ecs_new(world, GuiSystem);
GuiSystem *gui = ecs_get_mut(world, ui, GuiSystem, NULL);
gui->Update = MyImGuiDrawFunction;

```

**Capturing Input:**

```c
ecs_entity_t input_entity = ecs_new(world, Input);
Input *in = ecs_get_mut(world, input_entity, Input, NULL);

/* Query specific keys */
bool is_jumping = in->keys[ECS_KEY_SPACE].pressed;
float cursor_x = in->mouse.wnd.x;

```

### Combining Components in Systems

The ECS architecture shines when systems query multiple components simultaneously. A player entity can possess both Transform and Input components, allowing movement systems to update position based on key presses:

```c
void MovePlayerSystem(ecs_iter_t *it) {
    Transform *t = ecs_field(it, Transform, 1);
    Input *in = ecs_field(it, Input, 2);
    
    for (int i = 0; i < it->count; i++) {
        if (in->keys[ECS_KEY_W].pressed) {
            /* Move forward along Z axis */
            t[i].value[3][2] += 0.1f;
        }
    }
}

```

## System Integration

These entity components connect to engine systems that process their data each frame:

- **[`equilibrium/systems/transform_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/systems/transform_system.c)**: Reads `Transform` components and updates world matrices for the renderer
- **[`equilibrium/systems/sdl_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/systems/sdl_system.c)**: Polls SDL events and writes to the `Input` component
- **[`editor/systems/imgui_overlay_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/editor/systems/imgui_overlay_system.c)**: Uses `GuiSystem` and `GuiContext` to render ImGui widgets

Because components are plain data, they impose no inheritance overhead, allowing the engine to batch process thousands of entities with identical component signatures efficiently.

## Summary

- **Equilibrium Engine** uses the flecs ECS where entity components are pure C structs attaching data to entity IDs
- **Transform** components store 4×4 matrices in [`equilibrium/components/transform.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/transform.h) and attach to all renderable objects
- **GUI** components defined in [`equilibrium/components/gui.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/gui.h) manage ImGui state through `GuiSystem` and related structs
- **Input** components in [`equilibrium/components/input.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/input.h) encapsulate keyboard and mouse state via the `Input` struct with `KeyState keys[128]`
- Import components using `TransformComponentsImport()`, `GuiComponentsImport()`, and `InputComponentsImport()` before creating entities
- Combine components freely on entities and query them in systems using `ecs_field()` for data-driven gameplay logic

## Frequently Asked Questions

### What ECS framework does Equilibrium Engine use?

Equilibrium Engine uses the **flecs** ECS framework, a fast and portable entity component system written in C. The engine extends flecs by defining domain-specific entity components like Transform and Input in the `equilibrium/components` directory and registering them via import functions during world initialization.

### How do I add a Transform component to an entity?

First import the component module with `TransformComponentsImport(world)`, then create an entity and attach the component using `ecs_add(world, entity, Transform)`. Access the matrix data with `ecs_get_mut()` to set position, rotation, or scale values using standard GLM matrix functions like `glm_mat4_identity()`.

### Can multiple components exist on a single entity?

Yes. The ECS architecture allows unlimited component composition. For example, a player entity can simultaneously hold `Transform`, `Input`, and custom gameplay components. Systems query specific combinations using `ecs_field()` to process only entities possessing the required component set.

### Where are component definitions located in the source code?

Component structs and their registration macros reside in [`equilibrium/components/transform.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/transform.h), [`equilibrium/components/gui.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/gui.h), and [`equilibrium/components/input.h`](https://github.com/clibequilibrium/equilibriumengine/blob/main/equilibrium/components/input.h). Systems that process these components live in `equilibrium/systems/` and `editor/systems/`, with [`transform_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/transform_system.c), [`sdl_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/sdl_system.c), and [`imgui_overlay_system.c`](https://github.com/clibequilibrium/equilibriumengine/blob/main/imgui_overlay_system.c) serving as primary examples.