Skip to main content

Implementation of the ECS pattern for creating games

Project description

Implementation of the ECS pattern for creating games.

Make a game instead of architecture for a game.

Документация на Русском.

https://img.shields.io/pypi/dm/ecs_pattern.svg?style=social

Python version

3.3+

License

Apache-2.0

PyPI

https://pypi.python.org/pypi/ecs_pattern/

Dependencies

dataclasses before 3.7, typing before 3.5

Intro

ECS - Entity-Component-System - it is an architectural pattern created for game development.

It is great for describing a dynamic virtual world.

Basic principles of ECS:

  • Composition over inheritance

  • Data separated from logic (Data Oriented Design)

Component - Property with object data
Entity - Container for properties
System - Data processing logic

Installation

$ pip install ecs-pattern

Guide

Component
Property with object data. Contains only data, no logic.
The component is used as a mixin in entities.
Use the ecs_pattern.component decorator to create components:
@component
class ComPosition:
    x: int = 0
    y: int = 0

@component
class ComPerson:
    name: str
    health: int
Entity
Container for properties. Consists of components only.
It is forbidden to add attributes to an entity dynamically.
Use the ecs_pattern.entity decorator to create entities:
@entity
class Player(ComPosition, ComPerson):
    pass

@entity
class Ball(ComPosition):
    pass
System
Data processing logic - components and entities.
Does not contain data about entities and components.
Use the ecs_pattern.System abstract class to create concrete systems:
class SysInit(System):
    def __init__(self, entities: EntityManager):
        self.entities = entities

    def start(self):
        self.entities.init(
            TeamScoredGoalEvent(Team.LEFT),
            Spark(spark_sprite(pygame.display.Info()), 0, 0, 0, 0)
        )
        self.entities.add(
            GameStateInfo(play=True, pause=False),
            WaitForBallMoveEvent(1000),
        )

class SysGravitation(System):
    def __init__(self, entities: EntityManager):
        self.entities = entities

    def update(self):
        for entity_with_pos in self.entities.get_with_component(ComPosition):
            if entity_with_pos.y > 0:
                entity_with_pos.y -= 1
EntityManager
Entity database.
A single point of access to all entities.
Use the ecs_pattern.EntityManager class to create systems.
entities.add - add entities.
entities.delete - delete entities.
entities.delete_buffer_add - save entities to the delete buffer to delete later.
entities.delete_buffer_purge - delete all entities from the delete buffer.
entities.init - initialize entities (let manager know about entities).
entities.get_by_class - get all entities of the specified classes.
entities.get_with_component - Get all entities with the specified components.
entities = EntityManager()
entities.add(Player('Ivan', 20, 1, 2), Player('Vladimir', 30, 3, 4), Ball(0, 7))
for entity_with_pos in self.entities.get_with_component(ComPosition):
    print(entity_with_pos.x, entity_with_pos.y)
for player_entity in entities.get_by_class(Player):
    print(player_entity.name)
    entities.delete_buffer_add(player_entity)
entities.delete_buffer_purge()
entities.delete(*tuple(next(entities.get_by_class(Ball), [])))
SystemManager
Container for systems.
Works with systems in a given order.
Use the ecs_pattern.SystemManager class to manage systems.
system_manager.start_systems - initialize systems. Call once before the main systems update cycle.
system_manager.update_systems - update systems status. Call in the main loop.
system_manager.stop_systems - stop systems. Call once after the main loop completes.
entities = EntityManager()
entities.add(Player('Ivan', 20, 1, 2), Player('Vladimir', 30, 3, 4), Ball(0, 7))
system_manager = SystemManager([SysPersonHealthRegeneration(entities), SysGravitation(entities)])
system_manager.start_systems()
while play:
    system_manager.update_systems()
    clock.tick(24)  # *pygame clock
system_manager.stop_systems()

Examples

Advantages

  • Weak code cohesion - easy to refactor and expand the codebase

  • Modularity and testability of logic - easy to test and reuse code in other projects

  • Hard to write bad code

  • Easy to follow Single Responsibility logic

  • Easy to combine entity properties

  • Easy to analyze performance

  • Easy to parallelize processing

  • Easy to work with clean data

Difficulties

It can take a lot of practice to learn how to cook ECS properly:

  • Data is available from anywhere - hard to find errors

  • Systems work strictly one after another

  • Recursive logic is not directly supported

Newbie mistakes

  • Inheritance of components, entities, systems

  • Ignoring the principles of ECS, such as storing data in the system

  • Raising ECS to the absolute, no one cancels the OOP

  • Adaptation of the existing project code under ECS “as is”

  • Use of recursive or reactive logic in systems

  • Using EntityManager.delete in get_by_class, get_with_component loops

Good Practices

  • Use components - flags

  • Minimize component change locations

  • Use event entities and event systems

  • In large projects, placing ECS objects by type is not convenient (components.py, systems.py …). Group by responsibilities (movement.py …)

  • Do not use methods in components and entities

Releases

History of important changes: release_notes.rst

Help the project

  • Found a bug or have a suggestion - issue / merge request 🎯

  • There is nothing to help this project with - help another open project that you are using ✋

  • Nowhere to put the money - spend it on family, friends, loved ones or people around you 💰

  • Star the project ⭐

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

ecs-pattern-1.1.1.tar.gz (9.5 kB view details)

Uploaded Source

Built Distribution

ecs_pattern-1.1.1-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file ecs-pattern-1.1.1.tar.gz.

File metadata

  • Download URL: ecs-pattern-1.1.1.tar.gz
  • Upload date:
  • Size: 9.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.2

File hashes

Hashes for ecs-pattern-1.1.1.tar.gz
Algorithm Hash digest
SHA256 425dc00012e0b493026a2f5a50ae745d4391537a7eb0a812ffa0354788e6b13a
MD5 53dc5b911df72526b15008fb468e92bc
BLAKE2b-256 aabc28fbf92cca2feb3d9d9c83591b5fdb945584a9c064a768afc0a76cc65df6

See more details on using hashes here.

File details

Details for the file ecs_pattern-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: ecs_pattern-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.2

File hashes

Hashes for ecs_pattern-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 17a170b77edf0b5d1787e0e3aab92f60398adebc3058f563fdd0da729c527244
MD5 99da1ce9b240eea8728201559843c047
BLAKE2b-256 108453b63306a761ba20d7b9a1d935e093a9a7c02f122d64a67e115c89e11ae0

See more details on using hashes here.

Supported by

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