Skip to main content

KEG

KEG is an Engine for Games. More specifically, it is a small, typed, archetype-based ECS for Python 3.12 and newer.

KEG does not require components to inherit from anything. A dataclass will do. So will any other arbitrary object, although please exercise some judgment.

from dataclasses import dataclass

from keg import World


@dataclass(slots=True)
class Position:
    x: float
    y: float


@dataclass(slots=True)
class Velocity:
    x: float
    y: float


world = World()
player = world.spawn(
    Position(10.0, 20.0),
    Velocity(4.0, -2.0),
)

for entities, positions, velocities in world.query(Position, Velocity):
    for row in range(len(entities)):
        position = positions[row]
        velocity = velocities[row]
        position.x += velocity.x
        position.y += velocity.y

Queries return columns

A query yields one batch per matching archetype. Each batch contains the entity IDs followed by the requested component columns, in request order:

for entities, positions, velocities in world.query(Position, Velocity):
    ...

The sequences in a batch are aligned: entities[row], positions[row], and velocities[row] all belong to the same entity. They expose KEG's underlying column storage and should be treated as read-only. The component objects remain yours to mutate.

This avoids manufacturing a tuple for every entity merely to take it apart again in a hot loop. Queries are precisely typed for up to sixteen component types.

An entity may contain at most one component of each exact runtime type. Component inheritance has no special meaning to KEG.

Structural changes

Spawning and despawning entities, or adding and removing components, can move entities between archetypes. KEG applies those operations immediately during ordinary use and defers them automatically while a query is being iterated. The pending changes are committed after the last active query finishes.

You can request the same behaviour explicitly when applying a batch of changes:

with world.defer_structural_changes():
    projectile = world.spawn(Position(0.0, 0.0))
    world.add_component(projectile, Velocity(12.0, 3.0))

Pending entities and components remain accessible through get_component() and set_component(), while queries continue to see the committed archetype layout until the changes are flushed.

Queries release their structural guard when exhausted or explicitly closed. If you retain a query iterator and stop consuming it early, whether through break or an exception in surrounding code, call its close() method so pending structural work can be committed. Do not rely on garbage collection.

Installation

KEG currently has no runtime dependencies:

python -m pip install .

Example

The bouncing-balls example uses Kivy to exercise a small position and velocity system in a real update loop:

python -m pip install -e '.[examples]'
python examples/bouncing_balls/main.py

License

KEG is distributed under the MIT license.

Download files

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

Source Distribution

keg_engine-0.1.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

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

keg_engine-0.1-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file keg_engine-0.1.tar.gz.

File metadata

  • Download URL: keg_engine-0.1.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for keg_engine-0.1.tar.gz
Algorithm Hash digest
SHA256 c96713f2903ca32fd24bb1d9e0519ff374909f973c8df6988a4b7f378793b4c2
MD5 183f2e47a6d5addb59d64d73973bf19e
BLAKE2b-256 2d43a5cc0bcdcf7911da8eea340b8da547df74efbc726b0b0a1a018e63feefa5

See more details on using hashes here.

File details

Details for the file keg_engine-0.1-py3-none-any.whl.

File metadata

  • Download URL: keg_engine-0.1-py3-none-any.whl
  • Upload date:
  • Size: 9.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for keg_engine-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7495e7790a8d1d98576a8601abbd4652e9aaf4c3f0e64e193785c716e883c691
MD5 d12793b243306d744bac82545fdd6cc6
BLAKE2b-256 1531fe716a2c00648ca4ce506a25f68ef3e8c82b1971ddb739483f9aeb187dd7

See more details on using hashes here.

Supported by

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