8.1. DECS, Daslang entity component system¶
The DECS module implements a Data-oriented Entity Component System. Entities are identified by integer IDs and store components as typed data. Systems query and process entities by their component signatures, enabling cache-friendly batch processing of game objects.
See tutorial_decs for a hands-on tutorial.
All functions and symbols are in “decs” module, use require to get access to it.
require daslib/decs
8.1.1. Type aliases¶
- ComponentHash = uint64¶
daslang Entity Component System (DECS).
A pure-daslang ECS runtime: entities with dynamic component
composition, archetypal storage, queries, commit/deferred
create/delete, and serialization. Use with decs_boost for
the query macro syntax.
Hash value of the ECS component type
- TypeHash = uint64¶
Hash value of the individual type
- DeferEval = lambda<(var act:DeferAction):void>¶
Lambda which holds deferred action. Typically creation of destruction of an entity.
- ComponentMap = array<ComponentValue>¶
Table of component values for individual entity.
- PassFunction = function<void>¶
One of the callbacks which form individual pass.
8.1.2. Constants¶
- INVALID_ENTITY_ID = struct<decs::EntityId>(uninitialized)¶
Entity ID which represents invalid entity.
8.1.3. Structures¶
- CTypeInfo¶
Type information for the individual component subtype. Consists of type name and collection of type-specific routines to control type values during its lifetime, serialization, etc.
- Fields:
basicType : Type - basic type of the component
mangledName : string - mangled name of the type
fullName : string - full name of the type
hash : TypeHash - hash of the type
size : uint - size of the type
eraser : function<(arr:array<uint8>):void> - function to erase component value
clonner : function<(dst:array<uint8>;src:array<uint8>):void> - function to clone component value
serializer : function<(arch: Archive;arr:array<uint8>;name:string):void> - function to serialize component value
dumper : function<(elem:void?):string> - function to dump component value as text
mkTypeInfo : function<void> - function to make TypeInfo for the component type
gc : function<(src:array<uint8>):lambda<void>> - function to perform GC marking on the component value
- Component¶
Single ECS component. Contains component name, data, and data layout.
- Fields:
name : string - name of the component
hash : ComponentHash - hash of the component
stride : int - stride of the component data
data : array<uint8> - raw data of the component
info : CTypeInfo - type information of the component
gc_dummy : lambda<void> - this is here so that GC can find real representation of data
- EntityId¶
- Fields:
id : uint - Unique identifier of the entity. Consists of id (index in the data array) and generation.
generation : int - index of the entity
- Archetype¶
ECS archetype. Archetype is unique combination of components.
- Fields:
hash : ComponentHash - hash of the archetype (combination of component hashes)
components : array< Component> - list of components in the archetype
size : int64 - number of entities in the archetype (int64 — entity counts can exceed INT_MAX)
eidIndex : int - index of the ‘eid’ component in the components array
- ComponentValue¶
Value of the component during creation or transformation.
- Fields:
name : string - name of the component
info : CTypeInfo - type information of the component
data : float4[4] - raw data of the component
- EcsRequestPos¶
Location of the ECS request in the code (source file and line number).
- Fields:
file : string - source file
line : uint - line number
- EcsRequest¶
Individual ECS requests. Contains list of required components, list of components which are required to be absent. Caches list of archetypes, which match the request.
- Fields:
hash : ComponentHash - hash of the request
req : array<string> - required components
reqn : array<string> - required components which are not present
archetypes : array<int> - sorted list of matching archetypes
at : EcsRequestPos - location of the request in the code
- DecsState¶
Entire state of the ECS system. Contains archetypes, entities and entity free-list, entity lookup table, all archetypes and archetype lookups, etc.
- Fields:
archetypeLookup : table< ComponentHash;int> - lookup of archetype by its hash
allArchetypes : array< Archetype> - all archetypes in the system
entityFreeList : array< EntityId> - list of free entity IDs
entityLookup : array<tuple<generation:int;archetype: ComponentHash;index:int64>> - lookup of entity by its ID (index : int64 — entity indices can exceed INT_MAX)
componentTypeCheck : table<string; CTypeInfo> - lookup of component type info by its name
ecsQueries : array< EcsRequest> - all ECS requests
queryLookup : table< ComponentHash;int> - lookup of ECS request by its hash
- DecsPass¶
Individual pass of the update of the ECS system. Contains pass name and list of all pass callbacks.
- Fields:
name : string - name of the pass
calls : array< PassFunction> - list of all pass callbacks
8.1.4. Comparison and access¶
- ComponentMap.(cmp: ComponentMap; name: string): ComponentValue&¶
Access to component value by name. For example:
create_entity <| @ ( eid, cmp )
cmp.pos := float3(i) // same as cmp |> set("pos",float3(i))
- Arguments:
cmp : ComponentMap
name : string
- EntityId!=(a: EntityId; b: EntityId): bool¶
Inequality operator for entity IDs.
- EntityId==(a: EntityId; b: EntityId): bool¶
Equality operator for entity IDs.
8.1.5. Access (get/set/clone)¶
get (var cmp: ComponentMap; name: string; var value: auto(TT)) : auto
get_component (eid: EntityId; name: string; defval: auto(TT)) : TT
set (var cmp: ComponentMap; name: string; value: auto(TT)) : auto
set_direct (var arch: Archetype; name: string; eidx: int; value: auto(TT)) : auto
set_direct_at (var arch: Archetype; comp_idx: int; eidx: int; value: auto(TT)) : auto
8.1.5.1. clone¶
- clone(cv: ComponentValue; val: EntityId)¶
Sets individual component value. Verifies that the value is of the correct type.
- Arguments:
cv : ComponentValue
val : EntityId
- clone(cv: ComponentValue; val: bool)
- clone(cv: ComponentValue; val: double)
- clone(cv: ComponentValue; val: float)
- clone(cv: ComponentValue; val: float2)
- clone(cv: ComponentValue; val: float3)
- clone(cv: ComponentValue; val: float3x3)
- clone(cv: ComponentValue; val: float3x4)
- clone(cv: ComponentValue; val: float4)
- clone(cv: ComponentValue; val: float4x4)
- clone(cv: ComponentValue; val: int)
- clone(cv: ComponentValue; val: int16)
- clone(cv: ComponentValue; val: int2)
- clone(cv: ComponentValue; val: int3)
- clone(cv: ComponentValue; val: int4)
- clone(cv: ComponentValue; val: int64)
- clone(cv: ComponentValue; val: int8)
- clone(cv: ComponentValue; val: range)
- clone(cv: ComponentValue; val: range64)
- clone(cv: ComponentValue; val: string)
- clone(cv: ComponentValue; val: uint)
- clone(cv: ComponentValue; val: uint16)
- clone(cv: ComponentValue; val: uint2)
- clone(cv: ComponentValue; val: uint3)
- clone(cv: ComponentValue; val: uint4)
- clone(cv: ComponentValue; val: uint64)
- clone(cv: ComponentValue; val: uint8)
- clone(cv: ComponentValue; val: urange)
- clone(cv: ComponentValue; val: urange64)
- clone(dst: Component; src: Component)
- find_component_index(arch: Archetype; name: string): int¶
Returns the index of a named component within the archetype’s component array. Used to resolve component locations once, then write many entities via set_direct_at.
- Arguments:
arch : Archetype
name : string
8.1.5.2. get¶
- get(arch: Archetype; name: string; value: auto(TT)): auto¶
Creates temporary array of component given specific name and type of component. If component is not found - panic.
- Arguments:
arch : Archetype
name : string
value : auto(TT)
- get(cmp: ComponentMap; name: string; value: auto(TT)): auto
- get_component(eid: EntityId; name: string; defval: auto(TT)): TT¶
Returns a copy of the named component for the given entity.
If the entity is dead or the component is not found, returns defval.
The type of the component is inferred from the type of defval.
Panics if the component exists but its type does not match.
- Arguments:
eid : EntityId
name : string
defval : auto(TT)
8.1.5.3. has¶
- has(arch: Archetype; name: string): bool¶
Returns true if object has specified subobjec.
- Arguments:
arch : Archetype
name : string
- has(cmp: ComponentMap; name: string): bool
- remove(cmp: ComponentMap; name: string)¶
Removes specified value from the component map.
- Arguments:
cmp : ComponentMap
name : string
8.1.5.4. set¶
- set(cmp: ComponentMap; name: string; value: auto(TT)): auto¶
Set component value specified by name and type. If value already exists, it is overwritten. If already existing value type is not the same - panic.
- Arguments:
cmp : ComponentMap
name : string
value : auto(TT)
- set(cv: ComponentValue; val: auto): auto
- set_direct(arch: Archetype; name: string; eidx: int; value: auto(TT)): auto¶
Writes a component value directly into archetype storage at the given entity index. Convenience wrapper — does a name lookup per call. For bulk writes, prefer find_component_index + set_direct_at to resolve the name once.
- Arguments:
arch : Archetype
name : string
eidx : int
value : auto(TT)
- set_direct_at(arch: Archetype; comp_idx: int; eidx: int; value: auto(TT)): auto¶
Writes a component value directly into archetype storage by pre-resolved component index. O(1) per write — use find_component_index once, then this for each entity.
- Arguments:
arch : Archetype
comp_idx : int
eidx : int
value : auto(TT)
8.1.6. Entity status¶
- entity_count(): int¶
Returns the total number of alive entities across all archetypes.
Panics if the total exceeds INT_MAX — use long_entity_count for the
int64-safe accessor. Mirrors the length / long_length contract.
- is_alive(eid: EntityId): bool¶
Returns true if the entity is alive (exists and has not been deleted). An entity is alive when its id is within bounds and its generation matches the lookup table.
- Arguments:
eid : EntityId
8.1.7. Debug and serialization¶
- debug_dump()¶
Prints out state of the ECS system to LOG_DEBUG.
- debug_dump_string(): string¶
Returns state of the ECS system as a string.
- debug_dump_writer(writer: StringBuilderWriter)¶
Writes state of the ECS system to a StringBuilderWriter.
- Arguments:
writer : StringBuilderWriter
- describe(info: CTypeInfo): string¶
Returns textual description of the type.
- Arguments:
info : CTypeInfo
- finalize(cmp: Component)¶
Deletes component.
- Arguments:
cmp : Component
- serialize(arch: Archive; src: Component)¶
Serializes component value.
8.1.8. Stages¶
- commit()¶
Finishes all deferred actions.
- decs_stage(name: string)¶
Invokes specific ECS pass. commit is called before and after the invocation.
- Arguments:
name : string
- register_decs_stage_call(name: string; pcall: PassFunction)¶
Registration of a single pass callback. This is a low-level function, used by decs_boost macros.
- Arguments:
name : string
pcall : PassFunction
8.1.9. Deferred actions¶
- create_entities(count: int; blk: block<(eid:EntityId;i:int;var cmp:ComponentMap):void>)¶
Creates count entities in bulk. All entities must have the same archetype (same set of components). This is much faster than calling create_entity in a loop because it does a single archetype lookup and a single resize per component array for the entire batch.
Unlike create_entity, this is immediate — entities are visible to queries right after the call returns (no commit needed).
Example:
create_entities(100) $(eid : EntityId; i : int; var cmp : ComponentMap)
apply_decs_template(cmp, Particle(pos = origin, vel = compute_vel(i)))
- Arguments:
count : int
blk : block<(eid: EntityId;i:int;cmp: ComponentMap):void>
- create_entities_from_cmp(count: int; cmp: ComponentMap; fill_blk: block<(var arch:Archetype;eidx:int;eid:EntityId;i:int):void>)¶
Creates count entities in bulk with maximum performance. Takes a pre-built ComponentMap (used once to establish the archetype shape), then calls fill_blk for each entity to write directly into archetype storage, bypassing ComponentMap.
Typically called by macro-generated create_entities`T functions rather than
directly. See create_entities for the simpler ComponentMap-based API.
- Arguments:
count : int
cmp : ComponentMap
fill_blk : block<(arch: Archetype;eidx:int;eid: EntityId;i:int):void>
- create_entity(blk: lambda<(eid:EntityId;var cmp:ComponentMap):void>): EntityId¶
Creates deferred action to create entity.
- Arguments:
blk : lambda<(eid: EntityId;cmp: ComponentMap):void>
- delete_entity(entityid: EntityId)¶
Creates deferred action to delete entity specified by id.
- Arguments:
entityid : EntityId implicit
- update_entity(entityid: EntityId; blk: lambda<(eid:EntityId;var cmp:ComponentMap):void>)¶
Creates deferred action to update entity specified by id.
- Arguments:
entityid : EntityId implicit
blk : lambda<(eid: EntityId;cmp: ComponentMap):void>
8.1.10. GC and reset¶
- after_gc()¶
Low level callback to be called after the garbage collection. This is a low-level function typically used by live.
- before_gc()¶
Low level callback to be called before the garbage collection. This is a low-level function typically used by live.
- restart()¶
Restarts ECS by erasing all deferred actions and entire state.
8.1.11. Iteration¶
decs_array (atype: auto(TT); src: array<uint8>; capacity: int64) : auto
for_each_archetype (var erq: EcsRequest; blk: block<(arch:Archetype):void>)
get_default_ro (arch: Archetype; name: string; value: auto(TT)) : iterator<TT const&>
get_optional (arch: Archetype; name: string; value: auto(TT)?) : iterator<TT?>
get_ro (arch: Archetype; name: string; value: auto(TT)) : array<TT>
get_ro (arch: Archetype; name: string; value: auto(TT)[]) : array<TT[-2]>
- decs_array(atype: auto(TT); src: array<uint8>; capacity: int64): auto¶
Warning
This is unsafe operation.
Low level function returns temporary array of component given specific type of component. capacity is int64 — archetypes can hold >INT_MAX entities (Phase 8c widening).
- Arguments:
atype : auto(TT)
src : array<uint8>
capacity : int64
8.1.11.1. for_each_archetype¶
- for_each_archetype(hash: ComponentHash; erq: function<():void>; blk: block<(arch:Archetype):void>)¶
Invokes block for each entity of each archetype that can be processed by the request. Request is returned by a specified function.
- Arguments:
hash : ComponentHash
erq : function<void>
blk : block<(arch: Archetype):void>
- for_each_archetype(erq: EcsRequest; blk: block<(arch:Archetype):void>)
- for_each_archetype_find(hash: ComponentHash; erq: function<():void>; blk: block<(arch:Archetype):bool>): bool¶
Invokes block for each entity of each archetype that can be processed by the request. Request is returned by a specified function. If block returns true, iteration is stopped.
- Arguments:
hash : ComponentHash
erq : function<void>
blk : block<(arch: Archetype):bool>
- for_eid_archetype(eid: EntityId; hash: ComponentHash; erq: function<():void>; blk: block<(arch:Archetype;index:int):void>): bool¶
Invokes block for the specific entity id, given request. Request is returned by a specified function.
- Arguments:
eid : EntityId implicit
hash : ComponentHash
erq : function<void>
blk : block<(arch: Archetype;index:int):void>
- get_default_ro(arch: Archetype; name: string; value: auto(TT)): iterator<TT const&>¶
Returns const iterator of component given specific name and type of component. If component is not found - iterator will keep returning the specified value.
- Arguments:
arch : Archetype
name : string
value : auto(TT)
- get_optional(arch: Archetype; name: string; value: auto(TT)?): iterator<TT?>¶
Returns const iterator of component given specific name and type of component. If component is not found - iterator will keep returning default value for the component type.
- Arguments:
arch : Archetype
name : string
value : auto(TT)?
8.1.11.2. get_ro¶
- get_ro(arch: Archetype; name: string; value: auto(TT)): array<TT>¶
Returns const temporary array of component given specific name and type of component for regular components.
- Arguments:
arch : Archetype
name : string
value : auto(TT)
- get_ro(arch: Archetype; name: string; value: auto(TT)[]): array<TT[-2]>
8.1.12. Request¶
- EcsRequestPos(at: LineInfo): EcsRequestPos
Constructs EcsRequestPos from rtti::LineInfo.
- Arguments:
at : LineInfo
- compile_request(erq: EcsRequest)¶
Compiles ECS request, by creating request hash.
- Arguments:
erq : EcsRequest
- lookup_request(erq: EcsRequest): int¶
Looks up ECS request in the request cache.
- Arguments:
erq : EcsRequest
- verify_request(erq: EcsRequest): tuple<ok:bool;error:string>¶
Verifies ECS request. Returns pair of boolean (true for OK) and error message.
- Arguments:
erq : EcsRequest
8.1.13. Uncategorized¶
- long_entity_count(): int64¶
int64-safe variant of entity_count. Returns the total number of
alive entities across all archetypes without panicking past INT_MAX.