Skip to main content

A simple attribute-based approach to ECS.

Project description

punyecs

GitHub Actions Workflow Status

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 dataclasses import dataclass
from punyecs import World, requirements

w = World()

@dataclass
class Player:
    x: float
    y: float

@dataclass
class Enemy:
    x: float
    y: float

@requirements(w, {"x", "y"})
def move(e, dt):
    e.x += 0.1
    e.y += 0.1

player = Player(0.0, 0.0)
enemy = Enemy(1.0, 1.0)
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 putting it in the excluded objects list. The function f becomes:

@requirements(w, {"x", "y"}, exclude_objs=[player])
def move(e, dt):
    e.x += 0.1
    e.y += 0.1

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

Even More Sophistication!

It might be inconvenient to exclude individual objects if a large number of objects need to be excluded. punyecs provides a couple more filtering options. One way around this is to specify which attributes an object should not have.

For instance, we may have many different kinds of creatures. Most can follow the usual movement update function, but some creatures have a wiggle attribute. wiggle could be a Boolean, or even something more sophisticated like a function that describes how the creature wiggles.

To illustrate this consider:

from dataclasses import dataclass
from punyecs import World, requirements

w = World()

@dataclass
class Player:
    x: float
    y: float

@dataclass
class Enemy:
    x: float
    y: float

@dataclass
class Wiggler:
    x: float
    y: float
    wiggle: lambda x: x + 2

@requirements(w, {"x", "y"}, exclude={"wiggle"})
def move(e, dt):
    e.x += 0.1
    e.y += 0.1

@requirements(w, {"wiggle", "x", "y"})
def wiggle(e, dt):
    e.x = wiggle(e.x)
    e.y = wiggle(e.y)


player = Player(0.0, 0.0)
enemy = Enemy(1.0, 1.0)
wiggler = Wiggle(3.0, 3.0)
w.add(player)
w.add(enemy)
w.add(wiggler)

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

print(wiggler.x)
# Prints 5.0
print(wiggler.y)
# Prints 5.0

Thus, move does not operate on wiggler but wiggle does.

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.)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

punyecs-0.3.0.tar.gz (4.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

punyecs-0.3.0-py3-none-any.whl (5.0 kB view details)

Uploaded Python 3

File details

Details for the file punyecs-0.3.0.tar.gz.

File metadata

  • Download URL: punyecs-0.3.0.tar.gz
  • Upload date:
  • Size: 4.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for punyecs-0.3.0.tar.gz
Algorithm Hash digest
SHA256 7cc671eb97c58adb35805fe726ff12864df531954fe56b98353857fbf387faf0
MD5 a33c43b5d9a879394587f26b1cd40137
BLAKE2b-256 f79a9a77afe560169eb21057276809b765f564c4a669653f4a8ff50714607f95

See more details on using hashes here.

Provenance

The following attestation bundles were made for punyecs-0.3.0.tar.gz:

Publisher: python-publish.yml on Modular-Game-Components/punyecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file punyecs-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: punyecs-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 5.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for punyecs-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8935c2ebfc391fb161bb3370cc017e284df6865d51ed36604f4ef0018b9c4d6
MD5 2116d5660f1535894b053e056b02362a
BLAKE2b-256 21867c77f101cda5a1f1c43a199fbf599bb2ec237f6cb8a70fd5bc7c0c1e22cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for punyecs-0.3.0-py3-none-any.whl:

Publisher: python-publish.yml on Modular-Game-Components/punyecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page