Tag components#
A tag has no per-entity value. Presence supplies the entire signal:
local Selected =
tecs.ecs.newTagComponent({name = "Selected"})
local Stunned =
tecs.ecs.newTagComponent({name = "Stunned"})
world:set(entity, Selected)
world:commit()
assert(world:has(entity, Selected))
world:remove(entity, Selected)Use tags for flags, markers, and classifications. Use a scalar or structured component when each entity needs a value.
world:get on a tag returns the tag container rather than row data. Prefer world:has for a presence check.
Query membership#
Tags belong in query filters, not column loops:
local activeEnemies = world:newQuery({
include = {Enemy, Selected, Position},
exclude = {Stunned, tecs.ecs.Disabled, tecs.ecs.Paused},
})
for archetype, length in activeEnemies:iter() do
local entities = archetype.entities
local positions = assert(archetype:get(Position))
for row = 1, length as integer do
updateSelection(entities[row], positions[row])
end
endThe matching archetype signature already guarantees the tag's presence.
Structural cost#
Adding or removing a tag moves the entity between archetypes, just like any component membership change. Stage the changes while iterating a query; the pipeline publishes them after the phase.
for archetype, count in targets:iter() do
for row = 1, count as integer do
world:set(archetype.entities[row], Stunned)
end
endExclude Disabled and Paused explicitly from logic queries. The renderer excludes disabled entities and continues drawing paused ones.
The state stack creates a tag for each named state and adds the current top state's tag to new entities.