esper - API documentation

Processors

class esper.Processor

Base class for all Processors to inherit from.

Processor instances must contain a process method, but you are otherwise free to define the class any way you wish. Processors should be instantiated, and then added to a esper.World instance by calling esper.World.add_processor(). For example:

my_world = World()

my_processor_instance = MyProcessor()
my_world.add_processor(my_processor_instance)

After adding your Processors to a esper.World, Processor.world will be set to the World it is in. This allows easy access to the World and it’s methods from your Processor methods. All Processors in a World will have their process methods called by a single call to esper.World.process(), so you will generally want to iterate over entities with one (or more) calls to the appropriate world methods:

def process(self):
    for ent, (rend, vel) in self.world.get_components(Renderable, Velocity):
        your_code_here()

Components

esper does not define any specific Component base class to inherit from. Instead, a normal Python class can be used. Also, while it’s not required, the the @dataclass decorator from the dataclasses module can be useful to help write compact Component classes.

The World Class

class esper.World(timed=False)

A World object keeps track of all Entities, Components, and Processors.

A World contains a database of all Entity/Component assignments. The World is also responsible for executing all Processors assigned to it for each frame of your game.

add_component(entity: int, component_instance: _C, type_alias: Optional[Type[_C]] = None) → None

Add a new Component instance to an Entity.

Add a Component instance to an Entiy. If a Component of the same type is already assigned to the Entity, it will be replaced.

A type_alias can also be provided. This can be useful if you’re using subclasses to organize your Components, but would like to query them later by some common parent type.

add_processor(processor_instance: esper.Processor, priority=0) → None

Add a Processor instance to the World.

All processors should subclass esper.Processor. An optional priority argument can be provided. A higher priority will be executed first when esper.World.process() is called.

clear_cache() → None

Manually clear the internal cache.

clear_database() → None

Remove all Entities and Components from the World.

component_for_entity(entity: int, component_type: Type[_C]) → _C

Retrieve a Component instance for a specific Entity.

Retrieve a Component instance for a specific Entity. In some cases, it may be necessary to access a specific Component instance. For example: directly modifying a Component to handle user input.

Raises a KeyError if the given Entity and Component do not exist.

components_for_entity(entity: int) → Tuple[_C, ...]

Retrieve all Components for a specific Entity, as a Tuple.

Retrieve all Components for a specific Entity. The method is probably not appropriate to use in your Processors, but might be useful for saving state, or passing specific Components between World instances. Unlike most other methods, this returns all the Components as a Tuple in one batch, instead of returning a Generator for iteration.

Raises a KeyError if the given entity does not exist in the database.

create_entity(*components) → int

Create a new Entity, with optional Components.

This method returns an Entity ID, which is a plain integer. You can optionally pass one or more Component instances to be assigned to the Entity on creation. Components can be also be added later with the esper.World.add_component() method.

delete_entity(entity: int, immediate: bool = False) → None

Delete an Entity from the World.

Delete an Entity and all of it’s assigned Component instances from the world. By default, Entity deletion is delayed until the next call to esper.World.process(). You can, however, request immediate deletion by passing the immediate=True parameter. Note that immediate deletion may cause issues, such as when done during Entity iteration (calls to World.get_component/s).

Raises a KeyError if the given entity does not exist in the database.

entity_exists(entity: int) → bool

Check if a specific Entity exists.

Empty Entities (with no components) and dead Entities (destroyed by delete_entity) will not count as existent ones.

get_component(component_type: Type[_C]) → List[Tuple[int, _C]]

Get an iterator for Entity, Component pairs.

get_components(*component_types) → Iterable[Tuple[int, Tuple[Any, ...]]]

Get an iterator for Entity and multiple Component sets.

get_processor(processor_type: Type[esper.Processor]) → Optional[esper.Processor]

Get a Processor instance, by type.

This method returns a Processor instance by type. This could be useful in certain situations, such as wanting to call a method on a Processor, from within another Processor.

has_component(entity: int, component_type: Type[_C]) → bool

Check if an Entity has a specific Component type.

has_components(entity: int, *component_types) → bool

Check if an Entity has all the specified Component types.

process(*args, **kwargs)

Call the process method on all Processors, in order of their priority.

Call the esper.Processor.process() method on all assigned Processors, respecting their optional priority setting. In addition, any Entities that were marked for deletion since the last call will be deleted at the start of this call.

remove_component(entity: int, component_type: Type[_C]) → _C

Remove a Component instance from an Entity, by type.

A Component instance can only be removed by providing its type. For example: world.delete_component(enemy_a, Velocity) will remove the Velocity instance from the Entity enemy_a.

Raises a KeyError if either the given entity or Component type does not exist in the database.

remove_processor(processor_type: Type[esper.Processor]) → None

Remove a Processor from the World, by type.

Make sure to provide the class itself, not an instance. For example:

# OK:
self.world.remove_processor(MyProcessor)

# NG:
self.world.remove_processor(my_processor_instance)
try_component(entity: int, component_type: Type[_C]) → Optional[_C]

Try to get a single component type for an Entity.

This method will return the requested Component if it exists, or None if it does not. This allows a way to access optional Components that may or may not exist, without having to first query if the Entity has the Component type.

try_components(entity: int, *component_types) → Optional[List[List[_C]]]

Try to get a multiple component types for an Entity.

This method will return the requested Components if they exist, or None if they do not. This allows a way to access optional Components that may or may not exist, without first having to query if the Entity has the Component types.

Events

For convenience, esper includes functionality for dispatching and handling events. This is limited in scope, but should be robust enough for most general use cases.

esper.dispatch_event(name: str, *args) → None

Dispatch an event by name, with optional arguments.

Any handlers set with the esper.set_handler() function will recieve the event. If no handlers have been set, this function call will pass silently.

Note::If optional arguments are provided, but set handlers do not account for them, it will likely result in a TypeError or other undefined crash.
esper.set_handler(name: str, func) → None

Register a function to handle the named event type.

After registering a function (or method), it will receive all events that are dispatched by the specified name.

Note::Only a weak reference is kept to the passed function,
esper.remove_handler(name: str, func) → None

Unregister a handler from receiving events of this name.

If the passed function/method is not registered to receive the named event, or if the named event does not exist, this function call will pass silently.