Minimal (~600 LoC, cloc microecs/) Entity Component System in python and numpy. Examples also use raylib
for rendering.
Usage:
- Via pip:
pip install microecs - From source code:
git clone https://gitlab.com/meehai/microecs # clone the source code cd microecs # go in the cloned directory python -m venv .venv && source .venv/bin/activate # make a virtual env, optional but useful python -m pip install -e . # install micro ecs in this virtual env python -m pytest test/ # run the unit & integration tests to verify installation python examples/01-hello-world.py # run the basic hello world example (others in that dir)
Docs: meehai.gitlab.io/microecs — built by
docs/build_docs.sh (pdoc; no sphinx/config). Build locally with
bash docs/build_docs.sh and open the printed file:// link.
Simple example
from dataclasses import field import numpy as np from microecs import World, Component class HasPosition(Component): position: np.ndarray = field(metadata={"shape": (2, ), "dtype": "float32", "default": np.float32([0, 0])}) class HasVelocity(Component): velocity: np.ndarray = field(metadata={"shape": (2, ), "dtype": "float32", "default": np.float32([0, 0])}) world = World(components=[HasPosition, HasVelocity]) # both velocity and position (data) are optional since they have a default eid1 = world.add_entity(components=[HasPosition, HasVelocity]) # data is passed as kwargs to add_entity eid2 = world.add_entity(components=[HasPosition, HasVelocity], velocity=np.float32([1, 1])) world.update() # add_entity uses a command buffer internally until this is called print(f"Added 2 entities. Id1={eid1}, Id2={eid2}") # Querying: batch operate on all entities at once. qr = world.query(HasVelocity) # qr is a QueryResult object, a numpy-based Structure of Arrays (SoA). qr.velocity += np.float32([0.1, 0.5])
Documentation
- Primitives — the five building blocks (
Component,Entity,Pool,QueryResult,World), mutation timing, and how numpy-like the query views really are. - Systems & Per-Entity Iteration — writing systems, the three ways to touch data (vectorized,
zip-rows, theEntityAPI), and when each is right. - Hello World (raylib) — a complete runnable program, walked through part by part.
- Benchmarks — microecs vs OOP, and microecs vs six other Python ECS libraries (including the C++ EnTT and C flecs bindings) across seven workloads and an N-sweep to 1M.