An ECS Library based on the JavaScript geotic library.
Project description
ECStremity
ECStremity is an Entity-Component library. It is a Python port of the JavaScript library geotic by Dalton Mills.
- entity : a unique id and a collection of components
- component : a data container
- query : a way to gather collections of entities that match some criteria, for use in systems
- event : a message to an entity and its components
Installation
pip install ecstremity
Usage
To start using ECStremity, import the library and make some components.
from ecstremity import (Engine, Component)
ecs = Engine()
class Position(Component):
def __init__(self, x: int, y: int) -> None:
self.x = x
self.y = y
class Velocity(Component):
def __init__(self, x: int, y: int) -> None:
self.x = x
self.y = y
class Frozen(Component):
"""Tag component denoting a frozen character."""
All components must be registered with the engine. Component registration must use the class symbol (i.e. do not use the component name attribute).
ecs.register_component(Position)
ecs.register_component(Velocity)
ecs.register_component(Frozen)
Instruct the engine to make a new entity, then add components to it. Once a component is registered, it can be accessed using the class symbol or a string representing the class. The name attribute is not case-sensitive.
entity = ecs.create_entity()
entity.add(Position)
entity.add("Velocity")
The ecstremity library has no actual "system" class. Instead, instruct the engine to produce a query. For example, make a query that tracks all components that have both a Position and Velocity component, but not a Frozen component. A query can have any combination of the all_of, any_of, and none_of quantifiers.
kinematics = ecs.create_query(
all_of = ['Position', 'Velocity'],
none_of = ['Frozen']
)
Loop over the result set to update the position for all entities in the query. The query will always return an up-to-date list containing entities that match.
def loop(dt):
for entity in kinematics.result:
entity['Position'].x += entity['Velocity'].x * dt
entity['Position'].y += entity['Velocity'].y * dt
Changelog
v.1.0.1
Initial release
v.1.0.2
-
Changed how component names are handled. Previously creating a component required setting a class variable
namewith a string in all-caps that is identical to the class name, e.g. if a component was created asclass Position, the class required a variablename = "POSITION". Now all components inherit fromcomponentmetawhich handles this automatically. All references to component names inside the engine also convert the name string to the required casing. -
Added the ability to make use of the
EntityEventsystem. Useentity.fire_event('event_name', data)where data can be any object (typically a dict) that you want to pass to an entity's components. The'event_name'should have a correspondingon_event_namemethod on one or more components of the entity, which will have the event passed to it. -
Added a prefab system. This is a work-in-progress addition, but essentially you can now define component structures that can be applied all at once to an entity, allowing for templating of entity types.
v.1.0.3
- Miscellaneous fixes and performance updates.
- Fixed an issue with queries not updating their cache when components are added/removed from an entity.
v.1.0.4
- Added an
EngineAdapterclass that allows for passing in a reference to the game client. - Added entity cloning. Use
entity.clone()to make a copy of an entity with all attached components. - Added an
EventDataclass to pass in as the data argument ofentity.fire_event. This base class is meant to be extensible, but by default it has five optional parameters:instigator: Entity
Used to pass reference to the entity that fired the event.target: Union[Tuple[int, int], Entity]
Used to pass reference to an entity or position that can be used for various things, like forwarding an event or querying for data.interactions: List[Dict[str, str]]
Used to get back a list of interactions from a component. Typical format is{'name': 'event_name', 'event': 'on_event_method'}.callback: Callable[[Any], Any]
A callback that can be executed inside a component.cost: float
An event cost, for use with energy-based action systems.
- Added
EntityEvent.routeto trigger forwarding of an event to a target entity. For example, in my project game Anathema, I use this to query a target entity for interactions, say when bumping into it:
class Legs(Component):
# ...
def on_try_move(self, evt: EntityEvent) -> None:
if self.area.is_blocked(*evt.data.target):
if self.area.is_interactable(*evt.data.target):
self.entity.fire_event('try_interact', evt.data)
and then in a separate component:
class Brain(Component):
# ...
def on_try_interact(self, evt: EntityEvent) -> None:
evt.data.instigator = self.entity
evt.data.interactions = []
target: Entity = self.client.interaction_system.get(*evt.dat.target)
routed_evt: EntityEvent = evt.route(
new_event='get_interactions',
target=target
)
routed_evt.handle()
Finally, on a component attached to the target entity, I might have:
class Container(Component):
# ...
def on_get_interactions(self, evt) -> None:
if self._is_open:
evt.data.interactions.append({
"name": "Close",
"event": "try_close_container"
})
# ...
Which requires a corresponding Container.on_try_close_container, and so forth.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ecstremity-1.0.4.tar.gz.
File metadata
- Download URL: ecstremity-1.0.4.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.4.2 requests/2.22.0 setuptools/56.0.0 requests-toolbelt/0.8.0 tqdm/4.30.0 CPython/3.8.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60c4c1105799975b8d2363cf11b9ddecf9e02d75ef087fad76cf6c5b6f064e96
|
|
| MD5 |
dcfcb2b4375b79685913c8bca5510049
|
|
| BLAKE2b-256 |
ceec207324a6f8f1bfa0bb07137f281658ae8722058c1f68188a3a4e2374e160
|
File details
Details for the file ecstremity-1.0.4-py3-none-any.whl.
File metadata
- Download URL: ecstremity-1.0.4-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.4.2 requests/2.22.0 setuptools/56.0.0 requests-toolbelt/0.8.0 tqdm/4.30.0 CPython/3.8.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef109567f152e3e7ae6945f56ca4586e15a27e75b3f6e2a545d50108ce615eac
|
|
| MD5 |
40fd45658faa7326f99bde73294c1524
|
|
| BLAKE2b-256 |
d781390d56aec9ab09f718850bf81001ee8cae4281b1ab399ba5a6b5cb887d4f
|