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.4.tar.gz (85.4 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.4-py3-none-any.whl (81.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for arepy-0.5.4.tar.gz
Algorithm Hash digest
SHA256 62c2db2f8b1c366e2a42d8094a4d004a0cce7724a805f4567843a2a67e79dacf
MD5 db0e81b9c5d8a48daeb44b2020097159
BLAKE2b-256 8016d0b6060e068c59f4077c0b8165c2bd0367c7a776d8061f5b5d5bb5d7c717

See more details on using hashes here.

Provenance

The following attestation bundles were made for arepy-0.5.4.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.4-py3-none-any.whl.

File metadata

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

File hashes

Hashes for arepy-0.5.4-py3-none-any.whl
Algorithm Hash digest
SHA256 ddaa4507be3e4fb66d0f7a442d3529f12c8122649959b164459db8cdea971cd0
MD5 ef0ed77a1ab18a614a8207d8d9bf02de
BLAKE2b-256 12f66e0060bfb70e7fde2eaffd7907c447876f5aaadb44aac910a325b8f0049e

See more details on using hashes here.

Provenance

The following attestation bundles were made for arepy-0.5.4-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