> For the complete documentation index, see [llms.txt](https://wise-shepherd-games.gitbook.io/theia-ecs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wise-shepherd-games.gitbook.io/theia-ecs/entities-and-composition.md).

# Entities and Composition

What an entity is

In Theia, an `Entity` is an inert, **version-stamped key** into world storage, issued by the framework and used to access the data the framework holds on its behalf. An `Entity` **acts as a handle** to its metadata, which locates the entity's data in storage, for example, indicating its position within a specific `Archetype`.  An entity is not an object, it has no methods, no fields beyond its handle data, no behavior.

{% hint style="info" %}
An **Archetype** is a **storage** unit for **entities** that **share the same component composition**. Every entity with components A and B (and no others) lives in the same archetype; entities with components A, B, and C live in a different one.&#x20;
{% endhint %}

An `Entity` in Theia **must always hold at least one component**. Entities are not constructed in isolation and then populated; they come into existence **already composed**, and they cease to exist the moment they would be empty.

Entities are created through `Assemblages`, which bind **a fixed component composition to a&#x20;*****factory***. You don't call `world.CreateEntity<T1, T2>(...)` directly; you create an assemblage for the composition you want, then call `Create` on it.&#x20;

```csharp
Assemblage<Axe, Health> dwarf = world.CreateAssemblage<Axe, Health>();

Entity gimli = dwarf.Create(
    new Axe() { Damage = 10 }, 
    new Health() { Current = 100, Max = 100 }
);
```

You may be asking, "*why?*", more at the [Assemblages](/theia-ecs/entities-and-composition/assemblages.md) page.

Destroying an entity in Theia is called *ghoulification*. The term reflects what actually happens: the entity **isn't deleted** in any final sense, its slot **is recycled**, its version is bumped, and any handle still referring to it becomes silently invalid via the version check. It becomes a living dead, but ghoul just sounds better. It can happen in **two ways**:

* **Explicitly**, via world's methods;
* **Implicitly**, when the entity's last component is removed.

Each entity's metadata carries a version counter that increments on ghoulification. When a handle is checked, its version is compared against the metadata's current version; a mismatch means the handle is stale, and the framework treats the entity as a ghoul without needing a separate valid handles registry. This is what makes `IsAlive` O(1) and what lets ghouls silently no-op rather than corrupt state.

#### Entity API

`IsAlive`, `Is`, `Satisfies` and `TryGhoulify` are the four methods that operate on entities directly.

```csharp
if (world.IsAlive(gimli))
{
    /* Safe to access entity related data */
}
```

```csharp
if (world.Is(gimli, dwarf))
{
    /* Entity's current composition matches dwarf assemblage exactly */
}
```

`Is` is **an exact composition check**. The moment an entity gains or loses any component, for example a `Stunned` component, its archetype changes and `Is` returns `false` for the original assemblage. It answers: *"is this entity exactly what this assemblage makes?".*

`Satisfies` is a superset check. It returns `true` as long as the entity's current composition **contains at least every component in the assemblage's signature**. A dwarf with a `Stunned` component added mid-simulation fails `Is(gimli, dwarf)` but still passes `Satisfies(gimli, dwarf)` **since it has everything a dwarf needs and more**.

```csharp
/* Stun is applied */
world.TryAddComponent<Stunned>(gimli, new Stunned() { Duration = 2.0f });

/* Returns false, no longer exact */
world.Is(gimli, dwarf); 

/* Returns true, still has all dwarf components */
world.Satisfies(gimli, dwarf); 
```

The `Try` prefix signals that the method returns `bool` rather than throwing on a failure that isn't a bug. `TryGhoulify` returns `false` when the entity is already a ghoul, a normal occurrence in code that may be holding ghoulified entities, not an exceptional condition.

```csharp
world.TryGhoulify(gimli);
```

With entities established, the next pages cover what they're made of and how they come into being: [Components](/theia-ecs/entities-and-composition/components.md), [Assemblages](/theia-ecs/entities-and-composition/assemblages.md), and [Relations](/theia-ecs/entities-and-composition/relations.md).
