### Component and Tag Setup Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Functions for pre-registering components, creating tags, and setting component metadata. ```luau jecs.component() -- Pre-register component jecs.tag() -- Create tag jecs.meta(e, id, value) -- Set component metadata ``` -------------------------------- ### ComponentRecord Access Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Shows how to get the component record for a specific component (e.g., 'Position') and access its total size (number of entities using it). ```luau local rec = jecs.component_record(world, Position) print(`Entities with Position: {rec.size}`) ``` -------------------------------- ### SIMD Vectorization Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Demonstrates how contiguous component data arrays are suitable for SIMD instruction optimization. ```c float pos_x[N], pos_y[N], pos_z[N] -- Can be vectorized with SIMD instructions ``` -------------------------------- ### Create Entity Instance Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Example of creating an entity with a specific component data type and a generic entity. ```luau local Position = world:component() :: jecs.Id -- Entity local myEntity = world:entity() :: jecs.Entity -- Entity ``` -------------------------------- ### Create and Use a World in jecs Source: https://github.com/ukendio/jecs/blob/main/_autodocs/README.md Demonstrates the basic setup for creating a jecs world, defining components, creating entities, setting components, and querying entities with their components. ```Lua local jecs = require("@jecs") -- Create component types local Position = jecs.component() :: jecs.Id local Velocity = jecs.component() :: jecs.Id -- Create world local world = jecs.world() -- Create entity with components local entity = world:entity() world:set(entity, Position, vector.create(0, 0, 0)) world:set(entity, Velocity, vector.create(1, 0, 0)) -- Query and iterate for ent, pos, vel in world:query(Position, Velocity) do local newPos = pos + vel world:set(ent, Position, newPos) end ``` -------------------------------- ### Cached Query Lifecycle Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/CachedQuery.md Demonstrates the typical lifecycle of a cached query: creation, configuration, caching, repeated use in a loop, and final cleanup. ```luau -- 1. Create and configure query local query = world:query(Position, Velocity) :with(Active) -- 2. Cache it local cached = query:cached() -- 3. Use repeatedly for i = 1, numFrames do for entity, pos, vel in cached do updateEntity(entity, pos, vel) end end -- 4. Clean up when done cached:fini() ``` -------------------------------- ### Query Iteration Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Demonstrates how to iterate over entities that possess specific components (Position and Velocity) using a world query. ```lua for entity, pos, vel in world:query(Position, Velocity) do -- For each archetype with both Position and Velocity: -- For each entity in that archetype: -- Fetch Position and Velocity values from columns -- Yield (entity, pos, vel) end ``` -------------------------------- ### Archetype Iteration Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Demonstrates how to iterate over entities and their components within a specific archetype obtained from a query. Assumes Position and Velocity components are defined. ```luau local query = world:query(Position, Velocity) local archetypes = query:archetypes() for _, archetype in archetypes do local entities = archetype.entities local positions = archetype.columns_map[Position] local velocities = archetype.columns_map[Velocity] for i = 1, #entities do local entity = entities[i] local pos = positions[i] local vel = velocities[i] end end ``` -------------------------------- ### Iterate Entities with Query Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Example of creating and iterating over entities that possess both Position and Velocity components. ```luau local query = world:query(Position, Velocity) :: jecs.Query<[Position, Velocity]> for entity, pos, vel in query do -- entity: Entity -- pos: vector -- vel: vector end ``` -------------------------------- ### Create Pair Instance Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Example of creating a pair to represent an ownership relationship between a component ID and an entity. ```luau local Owns = world:component() :: jecs.Id<{ purchaseDate: string }> local car = world:entity() local ownershipPair = jecs.pair(Owns, car) :: jecs.Pair<{purchaseDate: string}, unknown> ``` -------------------------------- ### InferComponent Usage Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Illustrates how `InferComponent` works by inferring the type of a 'Position' component, which is expected to be 'vector'. It also shows how to get a component value using `world:get`. ```luau local Position = world:component() :: jecs.Id -- InferComponent = vector local pos = world:get(entity, Position) -- Returns vector | nil ``` -------------------------------- ### API Reference - Query Methods Source: https://github.com/ukendio/jecs/blob/main/_autodocs/DOCUMENTATION_INDEX.md Documentation for Query methods covers query creation, iteration, filtering with 'with' and 'without', checking for components, caching, and retrieving archetype information. Includes performance tips and usage examples. ```APIDOC ## Query Methods ### Description Provides methods for creating, configuring, and iterating over queries to retrieve entities based on their components. ### Methods - **iter()**: Iterates over the query results. - **with(component)**: Filters entities that have the specified component. - **without(component)**: Filters entities that do not have the specified component. - **has(component)**: Checks if entities have a specific component. - **cached()**: Creates a cached version of the query. - **archetypes()**: Retrieves the archetypes matching the query. ### Endpoint N/A (SDK/Library methods) ### Parameters Parameters vary per method. Refer to specific method documentation for details on component types and query configurations. ``` -------------------------------- ### EntityRecord Access Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Demonstrates how to retrieve and access the archetype, row, and dense indices for a given entity using `jecs.record`. ```luau local rec = jecs.record(world, entity) print(`Archetype ID: {rec.archetype.id}`) print(`Row: {rec.row}`) print(`Dense: {rec.dense}`) ``` -------------------------------- ### Cache Locality Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Contrasts cache-efficient column-major storage with less efficient row-major storage for processing component data. ```lua Processing Position data: for i = 1, 1000 do pos = positions_column[i] -- Linear access pattern update_position(pos) -- CPU cache hit! end vs. Row-major (Entity-centric): for _, entity in entities do local pos = entity.position -- Cache miss (scattered memory) local vel = entity.velocity -- Cache miss local mass = entity.mass -- Cache miss end ``` -------------------------------- ### API Reference - World Methods Source: https://github.com/ukendio/jecs/blob/main/_autodocs/DOCUMENTATION_INDEX.md Documentation for World methods includes creating a World, entity and component management, query operations, relationship handling, lifecycle hooks, and maintenance functions. It provides complete method signatures and usage examples. ```APIDOC ## World Methods ### Description Provides methods for managing the ECS World, including entity and component operations, querying, and lifecycle hooks. ### Methods - **create World()**: Creates a new World instance. - **entity()**: Creates a new entity. - **delete(entity)**: Deletes an entity. - **exists(entity)**: Checks if an entity exists. - **contains(entity)**: Checks if an entity is in the World. - **set(entity, component)**: Sets a component on an entity. - **add(entity, component)**: Adds a component to an entity. - **remove(entity, component)**: Removes a component from an entity. - **clear(entity, component)**: Clears a component from an entity. - **get(entity, component)**: Gets a component from an entity. - **has(entity, component)**: Checks if an entity has a component. - **query()**: Creates a query. - **target(entity, relationship)**: Gets the target of a relationship. - **targets(entity, relationship)**: Gets all targets of a relationship. - **parent(entity, relationship)**: Gets the parent of an entity in a relationship. - **children(entity, relationship)**: Gets all children of an entity in a relationship. - **each(entity, relationship, callback)**: Iterates over relationships. - **added(callback)**: Registers a lifecycle hook for added entities. - **changed(callback)**: Registers a lifecycle hook for changed entities. - **removed(callback)**: Registers a lifecycle hook for removed entities. - **cleanup()**: Cleans up the World. - **range(entity, count)**: Gets a range of entities. ### Endpoint N/A (SDK/Library methods) ### Parameters Parameters vary per method. Refer to specific method documentation for details on entity identifiers, component types, and callback functions. ``` -------------------------------- ### Iterating Entities with a Component Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Example of using the `world:each` method to iterate over all entities that possess a specific component (e.g., 'Position'). ```luau for entity in world:each(Position) do -- Iterates over all entities with Position end ``` -------------------------------- ### World:get Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Retrieves values of up to 4 components on a given entity. Missing components will return `nil`. ```APIDOC ## World:get ### Description Retrieves values of up to 4 components on an entity. Missing components return `nil`. ### Method `get` ### Parameters #### Path Parameters - **entity** (Entity) - Required - The entity to query - **components** (Id[]) - Required - 1-4 component IDs to retrieve ### Request Example ```luau local pos = world:get(entity, Position) local pos, vel = world:get(entity, Position, Velocity) local pos, vel, mass, health = world:get(entity, Position, Velocity, Mass, Health) ``` ### Response #### Success Response - Returns component values in order. Missing components return `nil`. #### Response Example ``` -- Example return values based on the request examples: -- local pos -- local pos, vel -- local pos, vel, mass, health ``` ``` -------------------------------- ### Get Component Usage Metadata Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/ModuleFunctions.md Use `component_record()` to get metadata about how a component is used across archetypes, including counts and total size. ```luau local Position = world:component() :: jecs.Id local record = jecs.component_record(world, Position) print(`Total entities with Position: {record.size}`) ``` -------------------------------- ### Store and Retrieve Data with Pairs Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Shows how to associate data with pairs, similar to components, using `world:set()` and retrieve it using `world:get()`. This allows for storing relationship-specific information. ```luau local Owns = world:component() :: jecs.Id<{ purchaseDate: string }> local car = world:entity() world:set(player, jecs.pair(Owns, car), { purchaseDate = "2024-01-01" }) -- Retrieve the data local ownershipData = world:get(player, jecs.pair(Owns, car)) print(ownershipData.purchaseDate) ``` -------------------------------- ### Column Iteration Example Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Shows how to access and iterate over component data, specifically 'Position' components, stored in a Column within an archetype. Requires a 'Position' component and a 'vector' type. ```luau local archetype = query:archetypes()[1] local positions = archetype.columns_map[Position] :: jecs.Column for i = 1, #positions do print(`Position {i}: {positions[i]}`) end ``` -------------------------------- ### Component Operations on Entities Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Functions for setting, adding, removing, clearing, getting, and checking for components on entities. ```luau world:set(entity, comp, value) -- Add/update component world:add(entity, comp) -- Add tag world:remove(entity, comp) -- Remove component world:clear(entity) -- Remove all world:get(entity, comp1, comp2) -- Read values world:has(entity, comp1, comp2) -- Check presence ``` -------------------------------- ### Use Cached Query for Efficient Iteration Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Example demonstrating the use of a cached query for efficient iteration over entities, followed by cleanup. ```luau local cachedQuery = world:query(Position, Velocity):cached() for i = 1, 100 do for entity, pos, vel in cachedQuery do -- Efficient iteration with cached archetypes end end cachedQuery:fini() -- Clean up when done ``` -------------------------------- ### Relationship and Parent-Child Operations Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Creating pairs for relationships, and functions to get targets, parents, children, and entities with specific components. ```luau jecs.pair(Relationship, Target) -- Create pair world:target(entity, Relation) -- Get target world:targets(entity, Relation) -- Get all targets world:parent(child) -- Get parent world:children(parent) -- Get children world:each(Component) -- Get all with component ``` -------------------------------- ### Setting Up Components Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Functions for pre-registering components, creating tags, and setting component metadata. ```APIDOC ## Setting Up Components ### Description Provides functions to initialize and configure components and tags within the ECS. ### Methods - `jecs.component()`: Pre-registers a component type. - `jecs.tag()`: Creates a new tag. - `jecs.meta(e, id, value)`: Sets metadata for a component on an entity. ``` -------------------------------- ### Batch Initialization with .bulk_insert() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Use `.bulk_insert()` for efficient initialization of multiple components on a new entity. Provide lists of components and their corresponding values. ```luau local function spawn_entity(world, position, velocity) local entity = world:entity() jecs.bulk_insert(world, entity, {Position, Velocity, Active}, {position, velocity, nil} -- nil for tags ) return entity end ``` -------------------------------- ### Create and Use Pairs Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Demonstrates how to create pairs using the `pair()` function and then use them in world operations to establish relationships between entities. ```luau local Likes = world:entity() local alice = world:entity() local bob = world:entity() -- Create pairs local alice_likes_bob = jecs.pair(Likes, bob) local bob_likes_alice = jecs.pair(Likes, alice) -- Use in world operations world:add(alice, alice_likes_bob) world:add(bob, bob_likes_alice) ``` -------------------------------- ### record() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/ModuleFunctions.md Gets the internal storage record for an entity, providing details about its archetype, row, and dense index. ```APIDOC ## record() ### Description Gets the internal storage record for an entity. ### Parameters #### Path Parameters - **world** (World) - Required - The world instance - **entity** (Entity) - Required - The entity to query ### Returns `EntityRecord` with fields: - `archetype: Archetype` — The entity's current archetype - `row: number` — Position in archetype's entity array - `dense: number` — Position in the dense entity index ### Example ```luau local entity = world:entity() local rec = jecs.record(world, entity) print(`Row: {rec.row}, Dense: {rec.dense}`) ``` ``` -------------------------------- ### Pre-registering Components Source: https://github.com/ukendio/jecs/blob/main/_autodocs/README.md Components should be registered at module load time for benefits like fast lookup IDs and consistent definitions across worlds. ```luau -- components.lua return { Position = jecs.component() :: jecs.Id, Health = jecs.component() :: jecs.Id, Velocity = jecs.component() :: jecs.Id, Walking = jecs.tag(), } ``` -------------------------------- ### Lazy Component Initialization Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Illustrates adding expensive components only when they are needed, typically within a query loop. This pattern optimizes performance by avoiding unnecessary computations. ```luau local query = world:query(Position):with(Moving) for entity, pos in query do -- Add expensive components only when needed if not world:has(entity, CachedPath) then world:set(entity, CachedPath, compute_path(pos)) end end ``` -------------------------------- ### ECS_PAIR_SECOND() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Gets the second entity (object) from a pair ID. This function returns the raw ID of the second entity in the pair. ```APIDOC ## ECS_PAIR_SECOND() ### Description Gets the second entity (object) from a pair ID. ### Signature ```luau function ECS_PAIR_SECOND(pair: Pair): number ``` ### Parameters #### Path Parameters - **pair** (Pair) - Required - The pair ID ### Returns - **number** — The raw ID of the second entity. ### Example ```luau local p = jecs.pair(Likes, bob) local second = jecs.ECS_PAIR_SECOND(p) -- Returns raw ID ``` ``` -------------------------------- ### ECS_PAIR_FIRST() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Gets the first entity (predicate) from a pair ID. This function returns the raw ID of the first entity in the pair. ```APIDOC ## ECS_PAIR_FIRST() ### Description Gets the first entity (predicate) from a pair ID. ### Signature ```luau function ECS_PAIR_FIRST(pair: Pair): number ``` ### Parameters #### Path Parameters - **pair** (Pair) - Required - The pair ID ### Returns - **number** — The raw ID of the first entity. ### Note Returns raw ID. Use `pair_first()` for alive entity resolution. ### Example ```luau local p = jecs.pair(Likes, bob) local first = jecs.ECS_PAIR_FIRST(p) -- Returns raw ID ``` ``` -------------------------------- ### Create and Traverse Parent-Child Entity Hierarchies Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Illustrates how to establish parent-child relationships between entities using `ChildOf` pairs and how to traverse these hierarchies to find parents or children. This is fundamental for organizing entities. ```luau -- Create hierarchy local parent = world:entity() local child1 = world:entity() local child2 = world:entity() world:add(child1, jecs.pair(jecs.ChildOf, parent)) world:add(child2, jecs.pair(jecs.ChildOf, parent)) -- Traverse local p = world:parent(child1) -- Returns parent for child in world:children(parent) do print(`Child: {child}`) end ``` -------------------------------- ### Implementing a System with JECS Source: https://github.com/ukendio/jecs/blob/main/_autodocs/README.md Systems can be implemented as objects with an update method. Queries can be pre-defined and cached for performance within the system. ```luau local PhysicsSystem = {} function PhysicsSystem.new(world) return { world = world, query = world:query(Position, Velocity) :with(Active) :cached() } end function PhysicsSystem:update(dt) for entity, pos, vel in self.query do local newPos = pos + vel * dt self.world:set(entity, Position, newPos) end end ``` -------------------------------- ### Set Component Metadata Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Demonstrates how to attach metadata, such as a name, to a component before creating worlds. ```lua local Position = jecs.component() jecs.meta(Position, jecs.Name, "Position") local world = jecs.world() -- Position already has metadata in world ``` -------------------------------- ### World:target Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Gets the target entity of a specific relationship from a given entity. For instance, it can retrieve the parent of an entity through the `ChildOf` relationship. ```APIDOC ## World:target ### Description Gets the target of a relationship pair. For example, `world:target(entity, ChildOf)` returns the parent. ### Method `target` ### Parameters #### Path Parameters - **entity** (Entity) - Required - The entity with the relationship - **relation** (Entity) - Required - The relationship component - **index** (number) - Optional - Which target to get (default: 0) ### Request Example ```luau local parent = world:target(child, jecs.ChildOf) if parent then print(`Parent is {parent}`) end ``` ### Response #### Success Response - **Entity | undefined** - The target entity, or nil if not found. #### Response Example ``` -- If the entity has the ChildOf relationship, the parent entity is returned. -- Otherwise, undefined is returned. ``` ``` -------------------------------- ### Using Query Iterator Source: https://github.com/ukendio/jecs/blob/main/_autodocs/types.md Demonstrates how to obtain and use an iterator from a query to loop through entities and their associated component values (e.g., Position and Velocity). ```luau local iter = query:iter() for entity, pos, vel in iter() do -- Process entity and components end ``` -------------------------------- ### Get Parent Entity Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Retrieves the parent entity of a given entity using the ChildOf relationship. Returns undefined if the entity has no parent. ```luau function World:parent(entity: Entity): Entity | undefined -- The child entity -- `Entity` or `undefined` — The parent entity. ``` ```luau local parent = world:parent(child) ``` -------------------------------- ### Create and Query Parent-Child Relationships Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Illustrates how to use the built-in `jecs.ChildOf` relationship to establish parent-child hierarchies. It shows adding the relationship, retrieving a parent, and iterating through children. ```luau local parent = world:entity() local child = world:entity() -- Create parent-child relationship world:add(child, jecs.pair(jecs.ChildOf, parent)) -- Retrieve parent local p = world:parent(child) -- Get all children for c in world:children(parent) do print(`Child: {c}`) end ``` -------------------------------- ### Pre-register Component IDs Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Explains how to pre-register component IDs at module load time for faster access across multiple worlds. ```lua -- At module load time local Position = jecs.component() :: jecs.Id local Velocity = jecs.component() :: jecs.Id -- Later, in many worlds local world1 = jecs.world() local world2 = jecs.world() -- Both worlds use same component IDs (1, 2, ...) ``` -------------------------------- ### Get Target of a Relationship Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Retrieves the target entity of a specific relationship from a given entity. For instance, it can find the parent of an entity through the ChildOf relationship. ```luau function World:target( entity: Entity, relation: Entity, index?: number ): Entity | undefined -- The entity with the relationship -- The relationship component -- Which target to get (default: 0) -- `Entity` or `undefined` — The target entity, or nil if not found. ``` ```luau local parent = world:target(child, jecs.ChildOf) if parent then print(`Parent is {parent}`) end ``` -------------------------------- ### Create and Iterate a Basic Query Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Create a query for entities with Position and Velocity components and iterate over them. This is the most common way to use queries. ```luau local query = world:query(Position, Velocity) for entity, pos, vel in query do -- entity: Entity -- pos: vector -- vel: vector end ``` -------------------------------- ### API Reference - Module Functions Source: https://github.com/ukendio/jecs/blob/main/_autodocs/DOCUMENTATION_INDEX.md Documentation for Module Functions covers component registration, metadata retrieval, entity information utilities, bulk operations, and built-in hooks and components. Includes complete signatures and parameter/return type details. ```APIDOC ## Module Functions ### Description Utility functions for component registration, metadata access, entity information, and bulk operations within the ECS. ### Functions - **component(name, type)**: Registers a component. - **tag(name)**: Registers a tag. - **meta(component)**: Retrieves metadata for a component. - **is_tag(component)**: Checks if a component is a tag. - **record(entity)**: Gets information about an entity. - **component_record(entity, component)**: Gets information about a component on an entity. - **ECS_ID(entity)**: Gets the ID of an entity. - **ECS_GENERATION(entity)**: Gets the generation of an entity. - **ECS_GENERATION_INC(entity)**: Increments the generation of an entity. - **ECS_COMBINE(id, generation)**: Combines ID and generation into an entity. - **bulk_insert(entities, components)**: Inserts multiple entities with components. - **bulk_remove(entities, components)**: Removes multiple entities with components. ### Endpoint N/A (SDK/Library functions) ### Parameters Parameters include component names, types, entity identifiers, and data structures for bulk operations. ``` -------------------------------- ### pair_second() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Gets the second entity of a pair with alive entity resolution. This function resolves the second entity of a pair to its current alive entity representation. ```APIDOC ## pair_second() ### Description Gets the second entity of a pair with alive entity resolution. ### Signature ```luau function pair_second(world: World, p: Pair): Entity ``` ### Parameters #### Path Parameters - **world** (World) - Required - The world instance - **p** (Pair) - Required - The pair ID ### Returns - **Entity** — The second entity (object) with generation. ### Example ```luau local likes_pair = jecs.pair(Likes, bob) local target = jecs.pair_second(world, likes_pair) ``` ``` -------------------------------- ### pair_first() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Gets the first entity of a pair with alive entity resolution. This function resolves the first entity of a pair to its current alive entity representation. ```APIDOC ## pair_first() ### Description Gets the first entity of a pair with alive entity resolution. ### Signature ```luau function pair_first(world: World, p: Pair): Entity

``` ### Parameters #### Path Parameters - **world** (World) - Required - The world instance - **p** (Pair) - Required - The pair ID ### Returns - **Entity

** — The first entity (predicate) with generation. ### Example ```luau local likes_pair = jecs.pair(Likes, bob) local relationship = jecs.pair_first(world, likes_pair) ``` ``` -------------------------------- ### Test JECS Queries with Known Data Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Demonstrates how to test JECS queries by setting up a world with known entities and components, then asserting the expected results from the query. This ensures query logic is correct. ```luau local function test_position_query() local world = jecs.world() -- Set up test data local e1 = world:entity() world:set(e1, Position, vector.create(0, 0, 0)) local e2 = world:entity() world:set(e2, Position, vector.create(1, 1, 1)) -- Test query local count = 0 for entity, pos in world:query(Position) do count += 1 end assert(count == 2, "Expected 2 entities with Position") end ``` -------------------------------- ### Archetype Graph Traversal Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Visualizes the directed graph connecting archetypes, where edges represent component add/remove operations, guiding the ECS during component modifications. ```plaintext ROOT_ARCHETYPE │ ├─ (add Position) ──> [Position] │ │ │ (add Velocity) │ │ └──────────────────────> [Position, Velocity] │ (add Mass) │ [Position, Velocity, Mass] ``` -------------------------------- ### Querying with Wildcards Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Demonstrates how to use `jecs.Wildcard` to query for entities that have a specific component paired with any other component. This is useful for finding all entities that 'like' something, regardless of what they like. ```Lua local Likes = world:component() world:set(alice, jecs.pair(Likes, bob), true) world:set(alice, jecs.pair(Likes, cat), true) -- Query all entities that Like something local likesAnythingQuery = world:query(jecs.pair(Likes, jecs.Wildcard)) for entity, data in likesAnythingQuery do print(`Entity {entity} likes something`) end ``` -------------------------------- ### Get Entity's Internal Storage Record Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/ModuleFunctions.md Use `record()` to retrieve the internal storage record for an entity, including its archetype and position within the archetype. ```luau local entity = world:entity() local rec = jecs.record(world, entity) print(`Row: {rec.row}, Dense: {rec.dense}`) ``` -------------------------------- ### Iterate Query Results Explicitly with iter() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Demonstrates using the explicit iter() method to get an iterator function for query results. This is functionally equivalent to direct iteration. ```luau local query = world:query(Position, Velocity) -- Using the iter() method explicitly for entity, pos, vel in query:iter() do print(`Entity at {pos}`) end -- Or iterate directly (syntactic sugar for iter()) for entity, pos, vel in query do print(`Entity at {pos}`) end ``` -------------------------------- ### Get Matching Archetypes Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/CachedQuery.md Retrieve the list of archetypes that match the cached query using the archetypes() method. An optional boolean argument can force a recalculation if the cache is suspected to be stale. ```luau local query = world:query(Position, Velocity):cached() -- Get cached archetypes (fast) local archetypes = query:archetypes() -- Recalculate if you suspect world changed local updated = query:archetypes(true) ``` -------------------------------- ### Pooling Components for Performance Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Demonstrates using pooled component IDs (1-256 range) for performance gains. These IDs can be reused for different data types, reducing overhead. ```luau -- Component IDs are in 1-256 range (fast) local PooledComponent = world:component() :: jecs.Id -- Use for different entity types world:set(entity1, PooledComponent, player_data) world:set(entity2, PooledComponent, enemy_data) ``` -------------------------------- ### Optimizing Memory with Cleanup Source: https://github.com/ukendio/jecs/blob/main/_autodocs/README.md The `world:cleanup()` method removes empty archetypes and optimizes memory usage by consolidating data structures. ```luau -- Remove empty archetypes and optimize memory world:cleanup() ``` -------------------------------- ### Register Components and Tags Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Pre-registers components and tags for fast access. See Module Functions for more information. ```luau function component(): Entity function tag(): Tag function meta(e: Entity, id: Id, value?: T): Entity function is_tag(world: World, id: Id): boolean ``` -------------------------------- ### Debug Visualization with Components Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Explains how to add debug-specific components, like a `Debug` component with color information, which can be conditionally rendered in debug builds. This aids in visualizing entity states. ```luau local Debug = world:component() :: jecs.Id<{ color: Color3 }> -- In debug build if DEBUG then for entity, pos in world:query(Position) do world:set(entity, Debug, { color = Color3.new(1, 0, 0) }) end end ``` -------------------------------- ### Event-Driven Systems with Hooks Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Use hooks for reactive updates based on component additions or changes. This enables event-driven system design. ```luau -- Log all position changes world:changed(Position, function(entity, id, newPos) print(`Entity {entity} moved to {newPos}`) end) -- Trigger callbacks on component add world:added(Solid, function(entity, id) print(`Entity {entity} became solid`) end) ``` -------------------------------- ### Register OnAdd Hook Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Shows how to register a callback function to be executed when a component is added to an entity. ```lua world:set(Position, jecs.OnAdd, function(entity, id, value, oldArchetype) print(`Entity {entity} gained Position`) end) ``` -------------------------------- ### Wildcard Matching for Pair Queries Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Pairs.md Demonstrates how to use `jecs.Wildcard` (or its alias `jecs.w`) in pair queries to match any target entity. This is useful for querying relationships where the object is not specific. ```luau local Likes = world:component() local alice = world:entity() local bob = world:entity() world:add(alice, jecs.pair(Likes, bob)) -- Query "alice likes anyone" local query = world:query(jecs.pair(Likes, jecs.Wildcard)) for entity, _ in query do print(`Entity {entity} likes something`) end ``` -------------------------------- ### Query Creation and Iteration Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Demonstrates how to create a query for entities with specific components and iterate over the results. Direct iteration is syntactic sugar for the iter() method. ```APIDOC ## Query Creation and Iteration ### Description Queries are created via `world:query()`. This example shows how to create a query for entities possessing `Position` and `Velocity` components and then iterate over the results. ### Method `world:query(Component1, Component2, ...)` ### Example ```luau local query = world:query(Position, Velocity) -- Iterate directly over the query results for entity, pos, vel in query do -- entity: Entity -- pos: vector -- vel: vector print(`Entity at {pos}`) end -- Explicitly using the iter() method for entity, pos, vel in query:iter() do print(`Entity at {pos}`) end ``` ``` -------------------------------- ### world() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Creates a new World instance to manage entities and components. Optionally enables debug mode for stricter validation and error messages. ```APIDOC ## world() ### Description Creates a new World instance to manage entities and components. ### Method `function world(DEBUG?: boolean): World` ### Parameters #### Path Parameters - **DEBUG** (boolean) - Optional - Enable debug mode for stricter validation and error messages ### Returns - **World** — A new World instance. ### Example ```lua local jecs = require("@jecs") local world = jecs.world() -- With debug mode enabled local debugWorld = jecs.world(true) ``` ``` -------------------------------- ### Create a JECS World Test Fixture Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Provides a `TestFixture` class for setting up isolated JECS worlds for testing. It includes methods for creating entities and ensuring proper cleanup after tests. ```luau local TestFixture = {} function TestFixture.new() local world = jecs.world() return { world = world, entities = {}, cleanup = function(self) for _, e in ipairs(self.entities) do self.world:delete(e) end end } end function TestFixture:create_entity() local e = self.world:entity() table.insert(self.entities, e) return e end ``` -------------------------------- ### Add Required Components with with() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Use the with() method to add components that an entity must possess to be included in the query results. Their values are not retrieved. ```luau local query = world:query(Position, Velocity) :with(Alive) -- Entity must be Alive but we don't retrieve it :with(Solid) -- Entity must be Solid for entity, pos, vel in query do print(`Entity {entity} is moving`) end ``` -------------------------------- ### Multi-Filter Queries with .with() and .without() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Use `.with()` and `.without()` methods to define complex query conditions. This allows for precise entity selection based on component presence or absence. ```luau local query = world:query(Position, Velocity) :with(Active) -- Must be active :with(Solid) -- Must be solid :without(Dead) -- Not dead :without(Invisible) -- Not invisible :cached() for entity, pos, vel in query do -- Process only entities meeting all criteria end ``` -------------------------------- ### Model Ownership Relationships with Pairs Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Shows how to model ownership relationships between entities using custom pairs. This pattern is effective for querying who owns what or what a specific entity owns. ```luau local Owns = world:component() :: jecs.Id<{ value: number }> local house = world:entity() world:set(person, jecs.pair(Owns, house), { value = 500000 }) -- Query what someone owns for target, data in world:query(jecs.pair(Owns, jecs.Wildcard)) do print(`Person owns something worth {data.value}`) end -- Query who owns a specific asset for owner, data in world:query(jecs.pair(Owns, house)) do print(`Owner: {owner}, Value: {data.value}`) end ``` -------------------------------- ### API Reference - Pair Functions Source: https://github.com/ukendio/jecs/blob/main/_autodocs/DOCUMENTATION_INDEX.md Documentation for Pair functions covers creating pairs, storing pair data, checking for pairs, extracting pair elements, and querying relationships. It explains pair encoding and exclusive relationships. ```APIDOC ## Pair Functions ### Description Functions for creating, manipulating, and querying pair relationships between entities. ### Functions - **pair(first, second)**: Creates a pair. - **IS_PAIR(entity)**: Checks if an entity represents a pair. - **ECS_PAIR_FIRST(entity)**: Extracts the first element of a pair. - **ECS_PAIR_SECOND(entity)**: Extracts the second element of a pair. - **pair_first(entity)**: Extracts the first element of a pair (alternative). - **pair_second(entity)**: Extracts the second element of a pair (alternative). ### Endpoint N/A (SDK/Library functions) ### Parameters Parameters include entity identifiers and relationship types. ``` -------------------------------- ### Inspect World State with Utility Functions Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Presents utility functions for inspecting the JECS world state, such as counting entities with a specific component or listing all components attached to an entity. These are invaluable for debugging and understanding system state. ```luau local function count_entities_with_component(world, component) return select(2, pairs(jecs.component_record(world, component).records)) end local function list_entity_components(world, entity) local record = jecs.record(world, entity) return record.archetype.types end ``` -------------------------------- ### Cached System Loop for Per-Frame Queries Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Create cached queries for systems that run every frame to optimize performance. Ensure to finalize the query when it's no longer needed. ```luau local PhysicsSystem = {} function PhysicsSystem.new(world) local self = { world = world, movingQuery = world:query(Position, Velocity) :with(Active) :cached() } return self end function PhysicsSystem:update(deltaTime) for entity, pos, vel in self.movingQuery do -- Update position based on velocity local newPos = pos + vel * deltaTime self.world:set(entity, Position, newPos) end end function PhysicsSystem:cleanup() self.movingQuery:fini() end ``` -------------------------------- ### Entity Lifecycle Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Create and manage entities. See World API: Entity Management. ```APIDOC ## Entity Lifecycle ### Description Create and manage entities. ### Methods - `function World:entity(): Tag` - `function World:entity(id: T): T` - `function World:delete(id: Entity): ()` - `function World:exists(entity: Entity): boolean` - `function World:contains(entity: Entity): boolean` ``` -------------------------------- ### World Creation Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Creates a new World instance. See World API. ```APIDOC ## World Creation ### Description Creates a new World instance. ### Function Signature `function world(DEBUG?: boolean): World` ``` -------------------------------- ### World:cleanup() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Removes empty archetypes and rebuilds the archetype collection to maintain memory efficiency. ```APIDOC ## World:cleanup() ### Description Removes empty archetypes and rebuilds the archetype collection to maintain memory efficiency. ### Method function World:cleanup(): () ### Example ```luau world:cleanup() ``` ``` -------------------------------- ### Query Pair Relationships Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Demonstrates how to query for pair-based relationships, such as ownership, by using jecs.pair() in the query definition. This allows modeling connections between entities. ```luau local Owns = world:component() local car = world:entity() -- Create a pair relationship world:set(player, jecs.pair(Owns, car), { purchaseDate = "2024-01-01" }) -- Query for ownership relationships local ownershipQuery = world:query(jecs.pair(Owns, car)) for entity, ownershipData in ownershipQuery do print(`Entity {entity} owns this car`) end ``` -------------------------------- ### meta() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/ModuleFunctions.md Assigns metadata to a component at registration time. This is useful for pre-configuring hooks and properties for components. ```APIDOC ## meta() ### Description Assigns metadata to a component at registration time. Useful for pre-configuring hooks and properties. ### Parameters #### Path Parameters - **e** (Entity) - Required - The component entity - **id** (Id) - Required - The metadata component - **value** (T) - Optional - The metadata value ### Returns `Entity` — The component entity. ### Example ```luau local Position = jecs.component() :: jecs.Id -- Set metadata on Position jecs.meta(Position, jecs.Name, "Position") -- Later in a world local world = jecs.world() -- Position is already configured with metadata ``` ``` -------------------------------- ### Efficiently Add/Remove Components in Bulk Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Efficiently adds or removes multiple components from an entity. Refer to Module Functions for usage. ```luau function bulk_insert( world: World, entity: Entity, ids: Id[], values: { any } ): () function bulk_remove(world: World, entity: Entity, ids: Id[]): () ``` -------------------------------- ### Query Entities with Wildcard Pair Relationship Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Illustrates using wildcards to query for entities involved in any relationship of a specific type (e.g., who likes anyone). ```lua -- Query "who likes anyone?" for entity, _ in world:query(jecs.pair(Likes, jecs.Wildcard)) do print(`Entity {entity} likes someone`) end ``` -------------------------------- ### Create a pre-registered component ID Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Allocates a component ID within the range of 1-256 for efficient access. Throws an error if the component limit is reached. ```luau local Position = world:component() :: jecs.Id local Health = world:component() :: jecs.Id local Velocity = world:component() :: jecs.Id ``` -------------------------------- ### Querying Pair Relationships Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Query.md Demonstrates how to query for pair-based relationships between entities, such as ownership. This involves using `jecs.pair()` to define the relationship components. ```APIDOC ## Querying Pair Relationships ### Description Queries support pair-based relationships for modeling connections between entities. This example shows how to query for ownership relationships using `jecs.pair()`. ### Method `world:query(jecs.pair(RelationshipComponent, TargetComponentOrEntity))` ### Example ```luau local Owns = world:component() local car = world:entity() -- Create a pair relationship (e.g., player owns car) world:set(player, jecs.pair(Owns, car), { purchaseDate = "2024-01-01" }) -- Query for ownership relationships local ownershipQuery = world:query(jecs.pair(Owns, car)) for entity, ownershipData in ownershipQuery do print(`Entity {entity} owns this car`) end ``` ``` -------------------------------- ### Entity Querying and Iteration Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Creating queries with filters, exclusions, caching, and iterating over query results. ```luau world:query(Position, Velocity) -- Create query :with(Active) -- Add filter :without(Dead) -- Add exclusion :cached() -- Optimize for entity, pos, vel in query do end -- Iterate ``` -------------------------------- ### Entity Naming for Debugging Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Demonstrates using the `jecs.Name` component to assign human-readable names to entities and components. This greatly improves debugging by making entity identification easier in output and tools. ```luau world:set(entity, jecs.Name, "Player Entity") world:set(Position, jecs.Name, "Position Component") -- In debug output local function debug_entity(world, entity) local name = world:get(entity, jecs.Name) print(`Entity {entity} ({name})`) end ``` -------------------------------- ### Add, Remove, and Retrieve Components Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Manages components for entities, including adding, removing, and retrieving them. See World API: Component Management. ```luau function World:component(): Entity function World:set>(entity: Entity, component: E, value: InferComponent): () function World:add(entity: Entity, component: C): () function World:remove(entity: Entity, component: Id): () function World:clear(entity: Entity): () function World:get(entity: Entity, ...components: T): FlattenTuple>>: () function World:has(entity: Entity, ...components: Id[]): boolean ``` -------------------------------- ### World:component() Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/World.md Creates a new pre-registered component ID for fast access. Component IDs are allocated in the range 1-256. ```APIDOC ## World:component() ### Description Creates a new pre-registered component ID for fast access. Component IDs are allocated in the range 1-256. ### Method `function World:component(): Entity` ### Returns - **Entity** — A typed component ID. ### Throws Error if more than 256 components have been created. ### Example ```lua local Position = world:component() :: jecs.Id local Health = world:component() :: jecs.Id local Velocity = world:component() :: jecs.Id ``` ``` -------------------------------- ### Reactive Update Listeners Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/Exports.md Setting up listeners for component addition, change, and removal events. ```luau world:added(Comp, listener) -- When added world:changed(Comp, listener) -- When changed world:removed(Comp, listener) -- When removed ``` -------------------------------- ### Set Component Value for Pairs Source: https://github.com/ukendio/jecs/blob/main/_autodocs/architecture.md Shows how to use pairs to represent relationships between entities and set their values. ```lua world:set(alice, jecs.pair(Likes, bob), true) world:set(bob, jecs.pair(Likes, alice), true) ``` -------------------------------- ### Create Pre-registered Component ID Source: https://github.com/ukendio/jecs/blob/main/_autodocs/api-reference/ModuleFunctions.md Use `component()` to create a fast-access component ID. This is ideal for frequently used components. ```luau local jecs = require("@jecs") local Position = jecs.component() :: jecs.Id local Velocity = jecs.component() :: jecs.Id ``` -------------------------------- ### Define Typed Component Bundles with Metadata Source: https://github.com/ukendio/jecs/blob/main/_autodocs/patterns-and-best-practices.md Group related components and assign metadata like names. This improves organization and type safety. ```luau local Components = { Position = jecs.component() :: jecs.Id, Velocity = jecs.component() :: jecs.Id, Mass = jecs.component() :: jecs.Id, } jecs.meta(Components.Position, jecs.Name, "Position") jecs.meta(Components.Velocity, jecs.Name, "Velocity") jecs.meta(Components.Mass, jecs.Name, "Mass") ```