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-