Welcome to tcod-ecs’s documentation!#
About#
tcod-ecs
is a Sparse-set Entity-component-system implemented using Python’s dict
and set
types.
See the ECS FAQ for more info.
This implementation focuses on type-hinting, organization, and is designed to work well with Python. The following features are currently implemented:
Entities can store components which are instances of any Python object. Components are looked up by their type.
Entities can have one instance of a type, or multiple instances of a type using a hashable tag to differentiate them.
Entity relationships are supported, either as many-to-many or many-to-one relationships.
ECS Queries can be made to fetch entities having a combination of components/tags/relations or excluding such.
The ECS Registry object can be serialized with Python’s pickle module for easy storage.
A lightweight version which implements only the entity-component framework exists called tcod-ec.
tcod-ec
was geared towards a dynamic-typed-dict style of syntax and is missing a lot of important features such as queries and named components.
Installation#
Use pip to install this library:
pip install tcod-ecs
If tcod
is installed and the version is less than 14.0.0
then import tcod.ecs
will fail.
Remove or update tcod
to fix this issue.
Examples#
Registry#
The ECS Registry is used to create and store entities and their components.
>>> import tcod.ecs
>>> registry = tcod.ecs.Registry() # New empty registry
Entity#
Each Entity is identified by its unique id (uid
) which can be any hashable object combined with the registry
it belongs.
New unique entities can be created with Registry.new_entity
which uses a new object()
as the uid
, this guarantees uniqueness which is not always desireable.
An entity always knows about its assigned registry, which can be accessed with the Entity.registry
property from any Entity instance.
Registries only know about their entities once the entity is assigned a name, component, tag, or relation.
>>> entity = registry.new_entity() # Creates a unique entity using `object()` as the uid
>>> entity
<Entity(uid=object at ...)>
>>> entity.registry is registry # Registry can always be accessed from their entity
True
>>> registry[entity.uid] is entity # Entities with the same registry/uid are compared using `is`
True
# Reference an entity with the given uid, can be any hashable object:
>>> entity = registry["MyEntity"]
>>> entity
<Entity(uid='MyEntity')>
>>> registry["MyEntity"] is entity # Matching entities ALWAYS share a single identity
True
Use Registry.new_entity
to create unique entities and use Registry[x]
to reference a global entity or relation with an id.
registry[None]
is recommend for use as a global entity when you want to store components in the registry itself.
Do not save the uid
’s of entities to be used later with registry[uid]
, this process is slower than holding onto the Entity instance.
Serialization#
Registries are normal Python objects and can be pickled as long as all stored components are pickleable.
>>> import pickle
>>> pickled_data: bytes = pickle.dumps(registry)
>>> registry = pickle.loads(pickled_data)
Stability is a priority but changes may still break older saves. Backwards compatibility is not a priority, pickled registries should not be unpickled with an older version of the library. This project follows Semantic Versioning, major version increments will break the API, the save format or both, minor version increments may break backwards compatibility. Check the changelog to be aware of format changes and breaks. There should always be a transition period before a format break, so keeping up with the latest version is a good idea.
Components#
Components are instances of any Python type.
These can be accessed, assigned, or removed from entities via the dict-like Entity.components
attribute.
The type is used as the key to access the component.
The types used can be custom classes or standard Python types.
>>> import attrs
>>> entity = registry.new_entity()
>>> entity.components[int] = 42
>>> entity.components[int]
42
>>> int in entity.components
True
>>> del entity.components[int]
>>> entity.components[int] # Missing keys raise KeyError
Traceback (most recent call last):
...
KeyError: <class 'int'>
>>> entity.components.get(int, "default") # Test keys with `.get()` like a dictionary
'default'
>>> @attrs.define
... class Vector2:
... x: int = 0
... y: int = 0
>>> entity.components[Vector2] = Vector2(1, 2)
>>> entity.components[Vector2]
Vector2(x=1, y=2)
>>> entity.components |= {int: 11, Vector2: Vector2(0, 0)} # Multiple values can be assigned like a dict
>>> entity.components[int]
11
>>> entity.components[Vector2]
Vector2(x=0, y=0)
# Queries can be made on all entities of a registry with matching components
>>> for e in registry.Q.all_of(components=[Vector2]):
... e.components[Vector2].x += 10
>>> entity.components[Vector2]
Vector2(x=10, y=0)
# You can match components and iterate over them at the same time. This can be combined with the above
>>> for pos, i in registry.Q[Vector2, int]:
... print((pos, i))
(Vector2(x=10, y=0), 11)
# You can include `Entity` to iterate over entities with their components
# This always iterates over the entity itself instead of an Entity component
>>> for e, pos, i in registry.Q[tcod.ecs.Entity, Vector2, int]:
... print((e, pos, i))
(<Entity...>, Vector2(x=10, y=0), 11)
Named Components#
Only one component can be assigned unless that component is given a unique name.
You can name components with the key syntax (name, type)
when assigning components.
Names are not limited to strings, they are a tag equivalent and can be any hashable or frozen object.
The syntax [type]
and [(name, type)]
can be used interchangeably in all places accepting a component key.
Queries on components access named components with the same syntax and must use names explicitly.
>>> entity = registry.new_entity()
>>> entity.components[Vector2] = Vector2(0, 0)
>>> entity.components[("velocity", Vector2)] = Vector2(1, 1)
>>> entity.components[("velocity", Vector2)]
Vector2(x=1, y=1)
>>> @attrs.define(frozen=True)
... class Slot:
... index: int
>>> entity.components |= { # Like a dict Entity.components can use |= to update items in-place
... ("hp", int): 10,
... ("max_hp", int): 12,
... ("atk", int): 1,
... str: "foo",
... (Slot(1), str): "empty",
... }
>>> entity.components[("hp", int)]
10
>>> entity.components[str]
'foo'
>>> entity.components[(Slot(1), str)]
'empty'
# Queries can be made on all named components with the same syntax as normal ones
>>> for e in registry.Q.all_of(components=[("hp", int), ("max_hp", int)]):
... e.components[("hp", int)] = e.components[("max_hp", int)]
>>> entity.components[("hp", int)]
12
>>> for e, pos, delta in registry.Q[tcod.ecs.Entity, Vector2, ("velocity", Vector2)]:
... e.components[Vector2] = Vector2(pos.x + delta.x, pos.y + delta.y)
>>> entity.components[Vector2]
Vector2(x=1, y=1)
Relations#
Use Entity.relation_components[component_key][target] = component
to associate a target entity with a component.
Use Entity.relation_tag[tag] = target
to associate a tag exclusively with a target entity.
Use Entity.relation_tags_many[tag].add(target)
to associate a tag with multiple targets.
Relation queries are a little more complex than other queries. Relation tags and relation components share the same space then queried, so ‘normal’ tags should not be in the format of a component key. Relations are unidirectional, but you can query either end of a relation.
>>> @attrs.define
... class OrbitOf: # OrbitOf component
... dist: int
>>> LandedOn = "LandedOn" # LandedOn tag
>>> star = registry.new_entity()
>>> planet = registry.new_entity()
>>> moon = registry.new_entity()
>>> ship = registry.new_entity()
>>> player = registry.new_entity()
>>> moon_rock = registry.new_entity()
>>> planet.relation_components[OrbitOf][star] = OrbitOf(dist=1000)
>>> moon.relation_components[OrbitOf][planet] = OrbitOf(dist=10)
>>> ship.relation_tag[LandedOn] = moon
>>> moon_rock.relation_tag[LandedOn] = moon
>>> player.relation_tag[LandedOn] = moon_rock
>>> set(registry.Q.all_of(relations=[(OrbitOf, planet)])) == {moon}
True
>>> set(registry.Q.all_of(relations=[(OrbitOf, ...)])) == {planet, moon} # Get objects in an orbit
True
>>> set(registry.Q.all_of(relations=[(..., OrbitOf, None)])) == {star, planet} # Get objects being orbited
True
>>> set(registry.Q.all_of(relations=[(LandedOn, ...)])) == {ship, moon_rock, player}
True
>>> set(registry.Q.all_of(relations=[(LandedOn, ...)]).none_of(relations=[(LandedOn, moon)])) == {player}
True
Relation queries#
You can use the following table to help with constructing relation queries.
tag
is a component key if you are querying for a component relation.
Includes |
Syntax |
---|---|
Entities with a relation tag to the given target |
|
Entities with a relation tag to any target |
|
Entities with a relation tag to the targets in the given query |
|
The target entities of a relation of a given entity |
|
The target entities of any entity with the given relation tag |
|
The target entities of the queried entities with the given relation |
|
API reference#
A type-hinted Entity Component System based on Python dictionaries and sets.
Registry management tools.
- class tcod.ecs.registry.Registry#
Bases:
object
A container for entities and components.
- property Q: BoundQuery#
Start a new Query for this registry.
Alias for
tcod.ecs.Query(registry)
.
- __getitem__(uid)#
Return an entity associated with a unique id.
Example:
>>> registry = Registry() >>> foo = registry["foo"] # Referencing a new entity returns a new empty entity >>> foo is registry["foo"] True >>> entity = registry.new_entity() >>> registry[entity.uid] is entity # Anonymous entities can be referred to by their uid True
- __setstate__(state)#
Unpickle this object and handle state migration.
- property global_: Entity#
A unique globally accessible entity.
This can be used to store globally accessible components in the registry itself without any extra boilerplate. Otherwise this entity is not special and will show up with other entities in queries, etc.
This entity has a uid of None and may be accessed that way. This syntax my be better for globals in general since it can use any hashable object.
New in version 1.1.
Example:
>>> registry[None].components[("turn", int)] = 0 >>> registry[None].components[("turn", int)] 0
- property named: Mapping[object, Entity]#
A view into this registries named entities.
Deprecated since version 3.1: This feature has been deprecated.
- new_entity(components=(), *, name=None, tags=())#
Create and return a new entity.
Changed in version 3.1: components can now take a mapping.
Example:
>>> entity = registry.new_entity( ... components={ ... ("name", str): "my name", ... ("hp", int): 10, ... }, ... tags=["Actor"], ... ) >>> entity.components[("name", str)] 'my name' >>> "Actor" in entity.tags True
Entity management and interface tools.
- class tcod.ecs.entity.Entity(registry, uid=<class 'object'>)#
Bases:
object
A unique entity in a registry.
Example:
>>> import tcod.ecs >>> registry = tcod.ecs.Registry() # Create a new registry >>> registry.new_entity() # Create a new entity <Entity(uid=object at ...)> >>> entity = registry["entity"] # Get an entity from a specific identifier >>> other_entity = registry["other"]
- static __new__(cls, registry, uid=<class 'object'>)#
Return a unique entity for the given registry and uid.
If an entity already exists with a matching registry and uid then that entity is returned.
The uid default of object will create an instance of
object
as the uid. An entity created this way will never match or collide with an existing entity.Example:
>>> registry = tcod.ecs.Registry() >>> Entity(registry, "foo") <Entity(uid='foo')> >>> Entity(registry, "foo") is Entity(registry, "foo") True >>> Entity(registry) is Entity(registry) False
- __reduce__()#
Pickle this Entity.
Note that any pickled entity will include the registry it belongs to and all the entities of that registry.
- __repr__()#
Return a representation of this entity.
Example:
>>> registry.new_entity() <Entity(uid=object at ...)> >>> registry["foo"] <Entity(uid='foo')>
- Return type:
- clear()#
Deletes all of this entities components, tags, and relations.
Relations targeting this component are still kept.
New in version 4.2.0.
- Return type:
None
- property components: EntityComponents#
Access an entities components.
Example:
>>> entity.components[str] = "foo" # Assign component >>> entity.components[("name", str)] = "my_name" # Assign named component >>> entity.components |= { # Update components in-place ... ("hp", int): 10, ... ("attack", int): 4, ... ("defense", int): 1, ... } >>> ("name", str) in entity.components True >>> {str, ("name", str)}.issubset(entity.components.keys()) True >>> list(registry.Q.all_of(components=[str])) # Query components [<Entity(uid='entity')>] >>> list(registry.Q[tcod.ecs.Entity, str, ("name", str)]) # Query zip components [(<Entity(uid='entity')>, 'foo', 'my_name')]
- instantiate()#
Return a new entity which inherits the components, tags, and relations of this entity.
This creates a new unique entity and assigns an
IsA
relationship with self to the new entity. TheIsA
relation is the only data this new entity directly holds.Example:
# 'child = entity.instantiate()' is equivalent to the following: >>> from tcod.ecs import IsA >>> child = registry[object()] # New unique entity >>> child.relation_tag[IsA] = entity # Configure IsA relation
Example:
>>> parent = registry.new_entity() >>> parent.components[str] = "baz" >>> child = parent.instantiate() >>> child.components[str] # Inherits components from parent 'baz' >>> parent.components[str] = "foo" >>> child.components[str] # Changes in parent and reflected in children 'foo' >>> child.components[str] += "bar" # In-place assignment operators will copy-on-write immutable objects >>> child.components[str] 'foobar' >>> parent.components[str] 'foo' >>> del child.components[str] >>> child.components[str] 'foo' # Note: Mutable objects have the same gotchas as in other Python examples: >>> from typing import List, Tuple >>> parent.components[List[str]] = ["foo"] >>> child.components[List[str]] += ["bar"] # Will modify list in-place then assign that same list to child >>> parent.components[List[str]] # Parent references the same list as the child now ['foo', 'bar'] >>> child.components[List[str]] ['foo', 'bar'] >>> parent.components[List[str]] is child.components[List[str]] True >>> parent.components[Tuple[str, ...]] = ("foo",) # Prefer immutable types to avoid the above issue >>> child.components[Tuple[str, ...]] += ("bar",) >>> child.components[Tuple[str, ...]] ('foo', 'bar') >>> parent.components[Tuple[str, ...]] ('foo',)
New in version 5.0.
- Return type:
- property name: object#
The unique name of this entity or None.
You may assign a new name, but if an entity of the registry already has that name then it will lose it.
Deprecated since version 3.1: This feature has been deprecated.
- property relation_components: EntityComponentRelations#
Access an entities relation components.
Example:
>>> entity.relation_components[str][other_entity] = "foo" # Assign component to relation >>> entity.relation_components[("distance", int)][other_entity] = 42 # Also works for named components >>> other_entity in entity.relation_components[str] True >>> list(registry.Q.all_of(relations=[(str, other_entity)])) [<Entity(uid='entity')>] >>> list(registry.Q.all_of(relations=[(str, ...)])) [<Entity(uid='entity')>] >>> list(registry.Q.all_of(relations=[(entity, str, None)])) [<Entity(uid='other')>] >>> list(registry.Q.all_of(relations=[(..., str, None)])) [<Entity(uid='other')>]
- property relation_tag: EntityRelationsExclusive#
Access an entities exclusive relations.
Example:
>>> entity.relation_tag["ChildOf"] = other_entity # Assign relation >>> list(registry.Q.all_of(relations=[("ChildOf", other_entity)])) # Get children of other_entity [<Entity(uid='entity')>] >>> list(registry.Q.all_of(relations=[(entity, "ChildOf", None)])) # Get parents of entity [<Entity(uid='other')>] >>> del entity.relation_tag["ChildOf"]
- property relation_tags: EntityRelationsExclusive#
Access an entities exclusive relations.
Deprecated since version 3.2: This attribute was renamed to
relation_tag
.
- property relation_tags_many: EntityRelations#
Access an entities many-to-many relations.
Example:
>>> entity.relation_tags_many["KnownBy"].add(other_entity) # Assign relation
- property tags: EntityTags#
Access an entities tags.
Example:
>>> entity.tags.add("tag") # Add tag >>> "tag" in entity.tags # Check tag True >>> list(registry.Q.all_of(tags=["tag"])) # Query tags [<Entity(uid='entity')>] >>> entity.tags.discard("tag") >>> entity.tags |= {"IsPortable", "CanBurn", "OnFire"} # Supports in-place syntax >>> {"CanBurn", "OnFire"}.issubset(entity.tags) True >>> entity.tags -= {"OnFire"} >>> {"CanBurn", "OnFire"}.issubset(entity.tags) False
- class tcod.ecs.entity.EntityComponentRelationMapping(entity, key, traverse)#
Bases:
Generic
[T
],MutableMapping
[Entity
,T
]An entity-component mapping to access the relation target component objects.
See
Entity.relation_components
.- Parameters:
- __attrs_post_init__()#
Validate attributes.
- Return type:
None
- __delitem__(target)#
Delete a component assigned to the target entity.
- Parameters:
target (Entity) –
- Return type:
None
- __getitem__(target)#
Return the component related to a target entity.
- Parameters:
target (Entity) –
- Return type:
T
- class tcod.ecs.entity.EntityComponentRelations(entity, traverse)#
Bases:
MutableMapping
[Union
[Type
[Any
],Tuple
[object
,Type
[Any
]]],EntityComponentRelationMapping
[Any
]]Proxy to access the component relations of an entity.
See
Entity.relation_components
.- ..versionchanged:: 4.2.0
Is now a
collections.abc.MutableMapping
subtype.
- __attrs_post_init__()#
Validate attributes.
- Return type:
None
- __call__(*, traverse)#
Update this view with alternative parameters, such as a specific traversal relation.
New in version 5.0.
- __contains__(key)#
Return True if this entity contains a relation component for this component key.
- __delitem__(key)#
Remove all relations associated with this component key.
- __getitem__(key)#
Access relations for this component key as a {target: component} dict-like object.
- Parameters:
- Return type:
- __iter__()#
Iterates over the component keys this entity has relations for.
- __len__()#
Returns the number of unique component keys this entity has relations for.
- Return type:
- __setitem__(_EntityComponentRelations__key, _EntityComponentRelations__values)#
Redefine the component relations for this entity.
..versionadded:: 4.2.0
- clear()#
Clears the relation components this entity directly has with other entities.
Does not clear relations targeting this entity.
- Return type:
None
- keys()#
Returns the components keys this entity has relations for.
- class tcod.ecs.entity.EntityComponents(entity, traverse)#
Bases:
MutableMapping
[Union
[Type
[Any
],Tuple
[object
,Type
[Any
]]],Any
]A proxy attribute to access an entities components like a dictionary.
See
Entity.components
.- __call__(*, traverse)#
Update this view with alternative parameters, such as a specific traversal relation.
New in version 5.0.
- __contains__(key)#
Return True if this entity has the provided component.
- __delitem__(key)#
Delete a directly held component from an entity.
- __getitem__(key)#
Return a component belonging to this entity, or an indirect parent.
- __ior__(value: SupportsKeysAndGetItem[ComponentKey[Any], Any]) Self #
- __ior__(value: Iterable[tuple[Type[Any] | Tuple[object, Type[Any]], Any]]) Self
Update components in-place.
New in version 3.4.
- __iter__()#
Iterate over the component types belonging to this entity.
- __setitem__(key, value)#
Assign a component directly to an entity.
- by_name_type(name_type, component_type)#
Iterate over all of an entities component keys with a specific (name_type, component_type) combination.
New in version 3.0.
Deprecated since version 3.1: This method has been deprecated. Iterate over items instead.
- get(_EntityComponents__key, _EntityComponents__default=None)#
Return a component, returns None or a default value when the component is missing.
- keys()#
Return the components held by this entity, including inherited components.
- set(value, *, _stacklevel=1)#
Assign or overwrite a component, automatically deriving the key.
Deprecated since version 3.1: Setting values without an explicit key has been deprecated.
- setdefault(_EntityComponents__key, _EntityComponents__default)#
Assign a default value if a component is missing, then returns the current value.
- class tcod.ecs.entity.EntityRelations(entity, traverse)#
Bases:
MutableMapping
[object
,EntityRelationsMapping
]A proxy attribute to access entity relations like a dict of sets.
See
Entity.relation_tags_many
.- __call__(*, traverse)#
Update this view with alternative parameters, such as a specific traversal relation.
New in version 5.0.
- __delitem__(key)#
Clear the relation tags of an entity.
This does not remove relation tags towards this entity.
- Parameters:
key (object) –
- Return type:
None
- __setitem__(key, values)#
Overwrite the targets of a relation tag with the new values.
- clear()#
Discard all tag relations from an entity.
- Return type:
None
- class tcod.ecs.entity.EntityRelationsExclusive(entity, traverse)#
Bases:
MutableMapping
[object
,Entity
]A proxy attribute to access entity relations exclusively.
See
Entity.relation_tag
.- __call__(*, traverse)#
Update this view with alternative parameters, such as a specific traversal relation.
New in version 5.0.
- __delitem__(key)#
Clear the relation targets of a relation key.
- Parameters:
key (object) –
- Return type:
None
- __getitem__(key)#
Return the relation target for a key.
If the relation has no target then raises KeyError. If the relation is not exclusive then raises ValueError.
- __setitem__(key, target)#
Set a relation exclusively to a new target.
- clear()#
Discard all tag relations from an entity.
- Return type:
None
- class tcod.ecs.entity.EntityRelationsMapping(entity, key, traverse)#
Bases:
MutableSet
[Entity
]A proxy attribute to access entity relation targets like a set.
See
Entity.relation_tags_many
.- __attrs_post_init__()#
Validate attributes.
- Return type:
None
- __contains__(target)#
Return True if this relation contains the given value.
- clear()#
Discard all targets for this tag relation.
- Return type:
None
- discard(target)#
Discard a directly held relation target from this tag.
- Parameters:
target (Entity) –
- Return type:
None
- class tcod.ecs.entity.EntityTags(entity, traverse)#
Bases:
MutableSet
[Any
]A proxy attribute to access an entities tags like a set.
See
Entity.tags
.- __call__(*, traverse)#
Update this view with alternative parameters, such as a specific traversal relation.
New in version 5.0.
- __contains__(x)#
Return True if this entity has the given tag.
- __ior__(other)#
Add tags in-place.
New in version 3.3.
- __isub__(other)#
Remove tags in-place.
New in version 3.3.
Tools for querying Registry objects.
- class tcod.ecs.query.BoundQuery(registry, query=_Nothing.NOTHING)#
Bases:
object
Collect a set of entities with the provided conditions.
This query is bound to a specific registry.
- Parameters:
registry (Registry) –
query (_Query) –
- __getitem__(key: tuple[Type[_T1] | Tuple[object, Type[_T1]]]) Iterable[tuple[_T1]] #
- __getitem__(key: tuple[Type[_T1] | Tuple[object, Type[_T1]], Type[_T2] | Tuple[object, Type[_T2]]]) Iterable[tuple[_T1, _T2]]
- __getitem__(key: tuple[Type[_T1] | Tuple[object, Type[_T1]], Type[_T2] | Tuple[object, Type[_T2]], Type[_T3] | Tuple[object, Type[_T3]]]) Iterable[tuple[_T1, _T2, _T3]]
- __getitem__(key: tuple[Type[_T1] | Tuple[object, Type[_T1]], Type[_T2] | Tuple[object, Type[_T2]], Type[_T3] | Tuple[object, Type[_T3]], Type[_T4] | Tuple[object, Type[_T4]]]) Iterable[tuple[_T1, _T2, _T3, _T4]]
- __getitem__(key: tuple[Type[_T1] | Tuple[object, Type[_T1]], Type[_T2] | Tuple[object, Type[_T2]], Type[_T3] | Tuple[object, Type[_T3]], Type[_T4] | Tuple[object, Type[_T4]], Type[_T5] | Tuple[object, Type[_T5]]]) Iterable[tuple[_T1, _T2, _T3, _T4, _T5]]
- __getitem__(key: tuple[Type[object] | Tuple[object, Type[object]], ...]) Iterable[tuple[Any, ...]]
Collect components from a query.
- all_of(components=(), *, tags=(), relations=(), traverse=(<IsA>, ), depth=None)#
Filter entities based on having all of the provided elements.
- get_entities()#
Return entities matching the current query as a read-only set.
This is useful for post-processing the results of a query using set operations.
New in version 4.4.
- Return type:
Set[Entity]
- none_of(components=(), *, tags=(), relations=(), traverse=(<IsA>, ), depth=None)#
Filter entities based on having none of the provided elements.
- tcod.ecs.query.WorldQuery#
alias of
BoundQuery
ECS callback management.
- tcod.ecs.callbacks.register_component_changed(*, component)#
Return a decorator to register on-component-changed callback functions.
Example:
>>> import tcod.ecs.callbacks >>> @tcod.ecs.callbacks.register_component_changed(component=int) ... def on_int_changed(entity: Entity, old: int | None, new: int | None) -> None: ... if old is not None and new is not None: ... print(f"int changed from {old} to {new}") ... elif old is not None and new is None: ... print(f"int value {old} was deleted") ... else: ... assert old is None and new is not None ... print(f"int value {new} was added") >>> entity.components[int] = 2 int value 2 was added >>> entity.components[int] = 5 int changed from 2 to 5 >>> del entity.components[int] int value 5 was deleted >>> tcod.ecs.callbacks.unregister_component_changed(callback=on_int_changed, component=int)
- tcod.ecs.callbacks.unregister_component_changed(callback, *, component)#
Unregister a registered on-component-changed callback function.
- Parameters:
callback (_OnComponentChangedFunc[_T]) –
component (ComponentKey[_T]) –
- Return type:
None
Special constants and sentinel values.
- tcod.ecs.constants.IsA: Final = <IsA>#
The default is-a relationship tag used for entity inheritance.
Common type-hints for tcod.ecs.