Skip to main content

An ECS python game engine with Raylib

Project description

image

CI Docs Upload Python Package codecov PyPI package Python versions License: MIT

Arepy is a lightweight and expressive ECS game engine built in Python, designed to make building 2D games simple, fast, and enjoyable. It provides a clean API, a modern architecture, and first-class integration with Raylib and ImGui.


Features

  • High-performance ECS architecture optimized for games
  • Raylib integration for hardware-accelerated 2D graphics
  • ImGui debugging overlay with real-time tools
  • Memory-efficient component pools
  • Flexible query system with With / Without filters
  • Simple and intuitive API design
  • Fluent entity builder system

Installation

From PyPI

pip install arepy

Development Installation

git clone https://github.com/Scr44gr/arepy.git
cd arepy
pip install -e ".[testing]"

Quick Start

Basic Example – Moving Square

from arepy import ArepyEngine, Color, Rect, Renderer2D, SystemPipeline
from arepy.bundle.components import RigidBody2D, Transform
from arepy.ecs import Entities, Query, With
from arepy.math import Vec2

# Colors
WHITE = Color(255, 255, 255, 255)
RED = Color(255, 0, 0, 255)

def movement_system(query: Query[Entities, With[Transform, RigidBody2D]], renderer: Renderer2D):
    delta_time = renderer.get_delta_time()
    
    for transform, rigidbody in query.iter_components(Transform, RigidBody2D):
        velocity = rigidbody.velocity
        
        transform.position.x += velocity.x * delta_time
        transform.position.y += velocity.y * delta_time

def render_system(query: Query[Entities, With[Transform]], renderer: Renderer2D):
    renderer.start_frame()
    renderer.clear(color=WHITE)
    
    for transform, in query.iter_components(Transform):
        renderer.draw_rectangle(
            Rect(transform.position.x, transform.position.y, 50, 50),
            color=RED
        )
    renderer.end_frame()

if __name__ == "__main__":
    game = ArepyEngine(title="Arepy Example")
    
    world = game.create_world("main_world")
    
    entity = (world.create_entity()
              .with_component(Transform(position=Vec2(0, 0)))
              .with_component(RigidBody2D(velocity=Vec2(50, 10)))
              .build())
    
    world.add_system(SystemPipeline.UPDATE, movement_system)
    world.add_system(SystemPipeline.RENDER, render_system)
    
    game.set_current_world("main_world")
    game.run()

Demo


Core Concepts

Entities

Lightweight identifiers that represent objects in the game world:

entity = world.create_entity()

player = (world.create_entity()
          .with_component(Transform(position=Vec2(100, 100)))
          .with_component(PlayerController())
          .build())

empty_entity = world.create_entity().build()

Components

Pure data containers attached to entities:

from arepy.ecs import Component

class Health(Component):
    def __init__(self, value: int = 100):
        super().__init__()
        self.value = value
        self.max_value = value

class Weapon(Component):
    def __init__(self, damage: int = 10, range: float = 100.0):
        super().__init__()
        self.damage = damage
        self.range = range

Systems

Systems implement game logic:

def damage_system(query: Query[Entity, With[Health, Weapon]]):
    for entity, health, weapon in query.iter_entities_components(Health, Weapon):
        
        if health.value <= 0:
            entity.kill()

Queries

Filter entities based on their components:

Query[Entity, With[Transform, Velocity]]
Query[Entity, Without[Dead]]
Query[Entity, tuple[With[Transform, Velocity], Without[Frozen]]]

Use iter_components(...) when you only need component data in the hot path:

def movement_system(
    query: Query[Entity, tuple[With[Transform, Velocity], Without[Frozen]]],
    renderer: Renderer2D,
) -> None:
    delta_time = renderer.get_delta_time()

    for transform, velocity in query.iter_components(Transform, Velocity):
        transform.position.x += velocity.x * delta_time
        transform.position.y += velocity.y * delta_time

Use Without[...] to exclude entities that should not be processed:

def active_projectiles_system(
    query: Query[Entity, tuple[With[Transform, Velocity], Without[Destroyed]]],
) -> None:
    for transform, velocity in query.iter_components(Transform, Velocity):
        transform.position.x += velocity.x
        transform.position.y += velocity.y

Testing

pytest                   # Run all tests
pytest --cov=arepy       # Coverage report
pytest tests/test_registry.py -v

Contributing

We welcome contributions. Refer to the Contributing Guide.

  1. Fork the repository
  2. Create a feature branch
  3. Implement your changes and tests
  4. Ensure tests pass
  5. Commit and push
  6. Open a Pull Request

Requirements

  • Python 3.11+
  • Raylib 5.5.0+
  • Bitarray 3.4.2+

Roadmap

  • Advanced query system
  • Scene management
  • Asset pipeline improvements
  • Physics integration
  • Audio system
  • Networking support
  • Visual editor

📄 License

This project is licensed under the MIT License – see the LICENSE file for details.


🙏 Acknowledgments


Made with ❤️ by Abrahan Gil

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

arepy-0.5.2.tar.gz (69.3 kB view details)

Uploaded Source

Built Distribution

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

arepy-0.5.2-py3-none-any.whl (72.1 kB view details)

Uploaded Python 3

File details

Details for the file arepy-0.5.2.tar.gz.

File metadata

  • Download URL: arepy-0.5.2.tar.gz
  • Upload date:
  • Size: 69.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for arepy-0.5.2.tar.gz
Algorithm Hash digest
SHA256 a49bdebb2fff79cb0fbc81dcf92ac2b552e41f24f784d095b1fc8180da56c96c
MD5 bb8fd53285448e8bc2076729149bdb23
BLAKE2b-256 13457fbf4c3fb04e509cee7156c3a069ed8ffcdd81fa433880b5fda1d705d034

See more details on using hashes here.

Provenance

The following attestation bundles were made for arepy-0.5.2.tar.gz:

Publisher: python-publish.yml on Scr44gr/arepy

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

File details

Details for the file arepy-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: arepy-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 72.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for arepy-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a48be4bef7bf7bf6b84efabceb287c3a079c5980b0baf5897bf7814bde1793e5
MD5 24a49bf036d052e20f367ead60ab409b
BLAKE2b-256 550ab4718b62826337936b428d872e43e46c8c325a1fa1954224c235f0f7e595

See more details on using hashes here.

Provenance

The following attestation bundles were made for arepy-0.5.2-py3-none-any.whl:

Publisher: python-publish.yml on Scr44gr/arepy

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