Rdbms With Code In Systems

The RDBMS with "all code in external systems" approach to ES design

(based on: RDBMS Inspired)
(a.k.a. "ES Alpha")

Build an API for your ES that is conceptually identical to a relational Database, plus:

  • disallow mixing "code" with your data
  • create monolithic, opaque "Systems" which contain all the code necessary for a chunk of functionality
    • e.g. "Physics System" runs once every 10 game-ticks, iterates over all physical objects, runs a frame of the physics-simulation
    • e.g. "Rendering System" runs once per game-tick, iterates over all objects that have a 2D/3D representation, and renders them to screen
    • e.g. "Positioning System" runs once per game-tick, combines physics-sim data, and player input, and info about the game-HUD, to set the positions of all renderable items

Extensions to this Approach

* RDBMS Beta - adds some practical improvements

Discussion and documentation

The T-Machine articles claim this is "anti OOP" (splitting code and data, instead of keeping them together in classes). A very long and detailed discussion of this approach, with thousands of comment-posts, can be found on T-Machine.org:

Implementation

Concepts

  • (integer) Entity
  • (enum) ComponentType
  • (interface OR empty base-class) Component
  • (interface OR empty base-class) System
  • (class with implementation) EntityManager

Data Classes

Entity

This is a non-negative integer, and uniquely identifies an entity within the ES. If you serialize your ES, this SHOULD be the same after serialization. New entities have to be assigned a new, unique, integer value when they are created. When an entity is destroyed, its integer value is freed, available for re-use.

ComponentType

This is needed because this ES is so simplistic it has no other way of identifying which Component you're talking about when you're looking at a single Entity.

(richer EntitySystems MAY not need this type)

Component

This exists purely to make method-signatures type-safe. We need to know that certain objects are valid instances of a "component" (so we use this superclass to indicate that), but we also need a method that's guaranteed to work on all those objects (see below).

(richer EntitySystems make more use of this, and require it to be a class, but for this simple ES, you can use an interface/header file)

System

This exists purely to contain a known method-signature that your game-loop can call once per game-tick.

EntitySystem Implementation Classes

Each subclass of Component

Internally, the class has the following functions:

  • (ComponentType) getComponentType();

System

Just one method, that gives you a common interface to trigger each of the systems:

  • processOneGameTick( long previousFrameTime );

EntityManager

This contains:

  • The master collections (arrays, hashmaps, whatever) that contain all the data for all the entities
  • Logic for creating, modifying, fetching, and deleting entities
  • Logic for fetching and modifying components-from-entities

Internally, the class has the following variables:

  • LIST: all entities in existence (so it never duplicates entity-IDs!)
  • MAP: from "Entity + ComponentType" to "concrete Component subclass"

Internally, the class has the following functions:

  • (Component) getComponent( Entity, ComponentType );
  • (List) getAllComponentsOfType( ComponentType );
  • (List) getAllEntitiesPossessingComponent( ComponentType );
  • (void) addComponent( Entity, Component );
  • (int) createEntity;
  • (void) killEntity( Entity );

Source Code

Java

Change notes

  • Because "System" is a reserved classname in Java, the "System" class has been renamed to "SubSystem"; maybe we need a better name for this.

Github

GitHub: https://github.com/adamgit/Entity-System-RDBMS-Inspired-Java

Suggestions for Improvement

  • Leverage Java's UUID as a drop in replacement for the standard Entity "object", which is typically just a non-negative integer. The upside is that UUID is universally unique, such that multiple computing agents could potentially share a set of entities. Secondly, UUID has some helpful serialization functions (toString / fromString). The downside is that UUID has a slightly heavier memory footprint than just a primitive data type.

Objective-C

Change notes

Entity is implemented as a class instead of a plain uint; this is technically incorrect, although the rest of the system works as expected

GitHub

NB2: Wikidot.com is broken in how it handles links - you MUST copy/paste this link, sadly:

https://github.com/adamgit/Entity-System--RDBMS-Inspired--Objective-C-

Ruby / JRuby

The Ruby Entity Component Framework (RECF) is a complete and working entity-component system written for the elegant Ruby language.

Documentation

The RECF has been documented in a series of blog posts by the author, "Entity-Component game programming using JRuby and libGDX".

Source code and examples

http://github.com/cpowell/ruby-entity-component-framework

Python

ecs is a young but complete Entity/Component System for games in Python. While the concepts are identical, the API has been adapted slightly to be more Pythonic. Source code and documentation can be found through the home page:

https://github.com/seanfisk/ecs

It is also available for download from PyPi:

https://pypi.python.org/pypi/ecs

Contributors welcome!