===== IEntity ===== An [[IEntity]] is the central runtime structure of the ECS architecture and the primary container for application state. Most state represented by the ECS exists as an Entity composed of one or more [[IComponent|Components]]. An Entity itself intentionally contains very little domain-specific state or behavior. Instead, its purpose is to group Components into a single runtime object, provide access to those Components, retain the [[IEntityStaticData|EntityStaticData]] that defines its composition, and manage the Entity's lifecycle. This separation is fundamental to the architecture: **the Entity represents the object, while its Components represent the individual pieces of state and functionality that make that object what it is.** **Broadcasts Events:** [[EntityIsNullTopic]] === Entity Composition === The composition of an Entity is defined by its [[IEntityStaticData|EntityStaticData]]. EntityStaticData acts as the definition or archetype from which runtime Entities are created and contains the ComponentStaticData entries describing which Components belong to the Entity. {{ :2026-04-27_17h50_45.png?669 |}} Entity creation is handled by the [[IEntityFactory]]. When an Entity is created from a StaticDataID, the factory: * Retrieves the corresponding [[IEntityStaticData|EntityStaticData]]. * Examines the Component Static Data contained within it. * Determines the runtime [[IComponent]] type associated with each Component Static Data type. * Creates each required Component. * Associates each Component with the newly created Entity and its corresponding Component Static Data. * Initializes Component properties configured to receive values from Static Data. * Attaches the completed Component collection to the Entity. As a result, users do not normally construct an Entity and manually decide which Components it contains. The Entity's composition originates from its EntityStaticData and is assembled automatically by the [[IEntityFactory]]. Conceptually, the relationship can be viewed as: **[[IEntityStaticData|EntityStaticData]] → ComponentStaticData → [[IComponent|Runtime Components]] → [[IEntity|Entity Instance]]** EntityStaticData defines **what an Entity is composed of**, ComponentStaticData defines the initial configuration of those Components, and the runtime Components contain the changing state of the individual Entity instance. === Entities and Components === An Entity can contain many [[IComponent|Components]], with each Component type representing a particular capability or piece of state. Systems and services can query an Entity for a specific Component rather than depending on a specialized Entity class. For example, the presence of an [[ITransformComponent]] allows an Entity to contain positional state, while an [[IEntityIdentifierComponent]] allows it to participate in the framework's UID system. These capabilities are determined by composition rather than inheritance. An Entity therefore should generally be treated as a collection of capabilities. Code interested in a particular capability should query for the corresponding Component using ''GetComponent'', ''TryGetComponent'' or ''HasComponent''. === Static Data ID and Entity Identity === The ID stored by [[IEntityStaticData|EntityStaticData]] identifies the **type or definition of Entity being created**, not a unique runtime Entity instance. Multiple Entity instances can be created from the same EntityStaticData and therefore share the same StaticDataID. When an Entity requires a persistent unique runtime identifier, it contains an [[IEntityIdentifierComponent]]. That Component's UID is used by systems such as serialization to identify a specific Entity instance independently of its Static Data definition. === Implementations === There are two internal implementations of [[IEntity]]: ''ArrayEntity'' and ''SetEntity''. Both expose the same IEntity API and this distinction is intentionally hidden from consumers. The [[IEntityFactory]] automatically selects the implementation based on the number of Components defined by the EntityStaticData. * **ArrayEntity** is currently used for Entities with fewer than 10 Components. Components and their Types are stored in arrays and Component lookups perform a small linear search. This avoids the additional overhead of a dictionary for Entities with small Component collections. * **SetEntity** is currently used for Entities with 10 or more Components. Components are stored by Type in a dictionary, providing more efficient type-based lookup as the number of Components increases. This is purely a runtime optimization. Consumers should always interact with [[IEntity]] and should not depend on which concrete implementation the factory selects. === Lifecycle === Entities should normally be created through the [[IEntityFactory]], which performs Component composition, initialization and registration with the rest of the framework. Calling ''Destroy'' begins the Entity's destruction process. Its Components are first unregistered as Message Broker broadcasters and the Entity transitions into its null state, broadcasting an [[EntityIsNullTopic]]. The framework uses this notification to perform the remaining cleanup associated with the Entity. Destroying an Entity that has already been destroyed has no effect. === Properties === ^Property | [[IEntityStaticData]] **StaticData** | ^Description | Returns the [[IEntityStaticData|EntityStaticData]] from which the Entity was created. This describes the Entity's static definition and Component composition. | === Methods === ^Method | void **AddComponents**(Dictionary components) | ^Description | Attaches supplied Components to the Entity. This method is primarily used by the [[IEntityFactory]] during Entity construction after the Component collection has been generated from the Entity's StaticData and should never be called directly by consumers. | ^Method | T **GetComponent**() where T : [[IComponent]] | ^Description | Returns the Component of type T attached to the Entity. Throws an InvalidOperationException if the Entity does not contain a Component of specified type. | ^Method | [[IComponent]] **GetComponent**(Type type) | ^Description | Returns the Component of specified Type attached to the Entity. Throws an InvalidOperationException if the Entity does not contain a Component of specified Type. | ^Method | bool **TryGetComponent**(out T? component) where T : [[IComponent]] | ^Description | Attempts to retrieve the Component of type T attached to the Entity. Returns true and outputs the Component when present. Returns false and outputs null when the Entity does not contain the requested Component. | ^Method | bool **TryGetComponent**(Type componentType, out [[IComponent]]? component) | ^Description | Attempts to retrieve the Component of specified Type attached to the Entity. Returns true and outputs the Component when present. Returns false and outputs null when the Entity does not contain the requested Component. | ^Method | IEnumerable<[[IComponent]]> **GetComponents**() | ^Description | Returns all Components attached to the Entity. | ^Method | IEnumerable **GetComponentTypes**() | ^Description | Returns the Types of all Components attached to the Entity. | ^Method | bool **HasComponent**() where T : [[IComponent]] | ^Description | Returns true if the Entity contains a Component of type T. | ^Method | bool **HasComponent**(Type componentType) | ^Description | Returns true if the Entity contains a Component of specified Type. | ^Method | void **Destroy**() | ^Description | Destroys the Entity. All Components belonging to the Entity are unregistered as Message Broker broadcasters before the Entity transitions into its null state and broadcasts an [[EntityIsNullTopic]], allowing the framework to perform the remaining Entity cleanup. Nothing happens if the Entity has already been destroyed. |