Skip to main content

punyecs

punyecs

GitHub Actions Workflow Status PyPI Python Version

punyecs is a tiny Entity Component System (ECS) inspired by tiny-ecs for Python. punyecs operates directly on class attributes as opposed to creating components along with querying mechanisms for fine grain control over which objects are operated on by systems similar to how tiny-ecs works on Lua tables. Decouple what an object can do from what it inherits.

Quick Install

If you use pip:

pip install punyecs

If you use uv:

uv add punyecs

What is it?

Instead of requiring inheritance, one can specify which attributes to operate on and any object (regardless of class) that has those attributes is operated on. That is, if a Player has an x and y attribute and an (unrelated) Enemy class has an x and y attribute you can have them both influenced by a World object. This avoids complicated inheritance hierarchies.

Here is a small example to illustrate the above:

from punyecs import World, requirements, Trait, give_traits

w = World()
Pos = Trait(x=0.0, y=0.0)

@give_traits(Pos)
class Player:
    pass

@give_traits(Pos, override={"x": 1.0, "y": 1.0})
class Enemy:
    pass

@requirements(w, Pos)
def move(e, dt):
    e.x += 0.1 * dt
    e.y += 0.1 * dt

player = Player()
enemy = Enemy()
w.add(player)
w.add(enemy)

w.update(1)
print(player.x) # Prints 0.1
print(player.y) # Prints 0.1

print(enemy.x) # Prints 1.1
print(enemy.y) # Prints 1.1

A Bit More Sophistication

We may also do exclusions for fine grain control. Returning to the example above, we may want various enemies to move like above but instead want to allow controller input for the player object. We can avoid influencing the player object by using a querying DSL. The function move becomes:

from punyecs import c

# ...

@requirements(w, Pos, subject_to=c.isnot(player))
def move(e, dt):
    e.x += 0.1 * dt
    e.y += 0.1 * dt

Then after every world.update(1), the player object will still remain at x=0.0, y=0.0.

A Graphical Pygame Example

https://github.com/user-attachments/assets/682ea45e-18a1-4d3e-9176-59686a80a524

Check out the examples folder or read a step-by-step guide on how to make it!

How does punyecs compare to Esper?

Esper is a well-established, performance-focused ECS for Python, and a reasonable default choice for most games. punyecs takes a different set of trade-offs — here's how they differ in practice:

  • Esper — you want a mature, widely-used, performance-oriented ECS, and you're comfortable with the classic "entities are IDs, components are separate objects" model.
  • punyecs — you want your entities to stay as normal Python objects (dataclasses you can pass around, inspect, and extend), you like declaring filters inline via subject_to, and you're building something small-to-medium where Esper's performance headroom isn't the deciding factor.

For a more detailed comparison see this section of the documentation.

Documentation

Even more filtering options are available. To learn more, see the readthedocs.

Contributing

Feel free to file an issue, make a pull request or, if you really like the project, donate. (No pressure though.)

Metadata

Release files for punyecs 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for punyecs 1.0.0
File Size Uploaded
punyecs-1.0.0.tar.gz 5.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for punyecs 1.0.0
File Interpreter ABI Platform
punyecs-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 12.2 kB

Release files / punyecs-1.0.0.tar.gz

Download URL punyecs-1.0.0.tar.gz
Size 5.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f6855127ada71a992def3b96cb02c502cb4532f73c3fc1494b34f9288dfbe146
BLAKE2b-256 checksum
How to use checksums
9c0d1ea07f786cf84efd76c5336957af00c0cdc2fa2682cf33706b943d994bb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 16, 2026.

Transparency log

Release files / punyecs-1.0.0-py3-none-any.whl

Download URL punyecs-1.0.0-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e5fa72055ac751cdaed69c57bb156f36458503cba4003d641159e02ba3c4a389
BLAKE2b-256 checksum
How to use checksums
091a846a40b3953095c8f926ed8808d74ca25790683233afb5946b2199aea3ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page