ECS API (Articular-ES)

Not sure I have to time to slog through a video at the moment…

Here is an article that you can read and see where the “composition pattern” differs from “entity component sytem”:

Which is actually linked to by the author in the margin-quote I included earlier.

With that in mind, I read his chapter differently.

He’s talking about a decoupling pattern. Composition over inheritance. Composition often leads to the noun “component” so he builds objects up from components and calls them entities.

Never once in the linked chapter does he call this an “entity component system”… though in the margin he does mention that you can take decoupling to the extreme “like these entity component systems”.

So my reading now is he’s saying “here’s a decoupling pattern, if you take it to the extreme then it could be an entity component system”.

His decoupling pattern ignores most of the features of an entity component system.

Maybe his video tells a different story but the text does not.

Edit: this is an even deeper look at ECS:

Edit 2: and from that link, this seems to directly address the discussion here:

3 Likes

Yes, the article on Wikipedia is taken from Sander’s (plus others) flecs ECS and the FAQ repository, I went over an overview of flecs Indeed. Thanks for your recommendations.

He has described something similar to the JME’s AbstractControl and quoted that “Components describe the entity behavior capabilities”, which is not the case in ECS if the component is “only data”, then it’s typically Stateless, my opinion is that the data is a stateless object unless interpreted by a scene graph or the system part in general (in case of game engines), but I noticed that he has also followed the memory layout for the ECS where components of the same type are grouped together, so something hybrid (edit).

That’s not really an ECS thing. In fact, the original memory-constrained ECSs would group data by system.

So if a physics system needed position and velocity then the memory would be organized into rows of position and velocity. The physics system would stream over all of the rows and produce new position components in target memory… which might then be transferred to different system streams and so on.

How the data is organized is really just down to how that particular ECS implementation wants to optimize things.

1 Like

I worked through the API a little more and refactored it to a system-first approach, in which the manager associates the components of an entity to a particular system, In this way, I will be able to retrieve system-relevant components easily.

The general memory layout will be Controller-Associated System(java.lang.String) [] > Entities (IDs) > Components[] > Component.

The Controller interface provides the standards for different types of interactions.

I still need to count the pitfalls of using ConcurrentHashMaps instead of regular arrays.

This would be a dummy example of the new work:

final StandardGameComponent position = new PositionComponent(new Component.Id(2223));
final StandardGameComponent velocity = new VelocityComponent(new Component.Id(344));

final Entity entity = EntityFactory.PLAYER.getEntity();

final EntityComponentManager<Float> ecsManager = new EntityComponentManager<>();

final SystemEntitiesUpdater<Float> updater = new SystemEntitiesUpdater<Float>() {
    @Override
    public void update(Type.EntityMap entityMap, EntityComponentManager<Float> entityComponentManager, Float input) {
        try {
            System.out.println(entityMap.get(entity.getId().intValue())
                                        .get(position.getId().intValue())
                                        .getData("positionVector").toString());
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getAssociatedSystem() {
        return "Demo System";
    }
};

ecsManager.attachAssociatedSystem(updater);
ecsManager.attachEntity(entity, updater);
ecsManager.register(position, entity, updater);
ecsManager.register(velocity, entity, updater);

// updating entities in a specific system
ecsManager.updateSystemEntities(updater, 0.005f);

// other update strategies
// ecsManager.updateSystemComponents();
// ecsManager.updateSystems();

A component example:

    public class PositionComponent extends StandardGameComponent {

        private String positionVector = "(3, 2, 1)";

        /**
         * Instantiates a new game entity component object.
         *
         * @param componentId the game component identifier
         */
        public PositionComponent(Id componentId) {
            super(componentId);
        }
    }

I used the resources linked by Paul and Data-oriented design by Richard Fabian, you can find a website version here.

After working on the main API, I will focus on optimizing the searching and matching algorithms, I would like to hear your remarks, Do you recommend any optimizations or things to put on my mind?

EDIT:
By extending the SystemController and the EntityComponentManager additional filters could be applied.

This is the source-code.

Major-function-1 (ECS Modules): I further extended the model and implemented ECS modules. ECS modules hold ecs components in a system-entity interface. This logical architecture can be implemented from a physical perspective as electronic modules composed of electronic components. The recursive structure of the API where everything is a Component even modules are, which further makes this implementation possible.

I have built a dummy example explaining how to design a human-interface-device (HID) using articular-es:

This is by far, the new architecture that involves everything as Component, and ecs modules:

I know that everything as components might break the rules, but I will try to figure this out soon.

The next challenge I have now is to try to adapt the API to implement embedded designs like FPGA for example which adds more complexity than just [Serial4j + HID], for example this diagram:

Overview Detailed-design
image image

The challenge now is “Will this API be able to address something in the complexity of FPGA-based devices in a clean simple way?”, the addition of ECS modules might be able to extend it to this functionality while everything is still compliant to the original ECS design.

Major-function-2 (Cache Manager): I added another non-standard ecs manager into the play to cache data in a different configuration (entity-[system]-component format) for a quick retrieve. The ArticularManager utility composes a cache manager to cache data in this configuration after the standard manager (system-[entity]-component format), and it can be disabled for low-memory systems.

4 Likes

Data-pipes feature: Today, I added a new interface DataPipe, a data pipe encapsulates data between systems. Data-pipes can be registered for later use and are identifiable objects (just the same as components). The collective activity for this is to have a minimalistic memory-map for data-pipes; where each data-pipe can be associated by an entity (or component id)…

This example is a pretty dumb example demonstrating the usage of data pipes through a data collector system and a data processor system. A data-pipe could be used to apply an algorithm (searching/filtering for example) and retrieve the result between systems…

1 Like

The library is now available on maven-central as of v1.0.0-alpha shipped with the basic documentation, in case someone wants to test it out:

I have added some notes about the usage of ECS Modules here:

3 Likes