ECS API (Articular-ES)

Working on a minimalistic ECS API, Articular-ES is a general-purpose Entity-Component System API for Java games with a specialized implementation for jMonkeyEngine.

The API provides an ECS game environment through the following minimalistic design:

  • A Component is the building unit of an entity system, each component is mapped by its identifier to its game entity.
  • An Entity has the game Components and extends the Component class to provide a way of implementing sub-entities.
  • BaseGameComponent and BaseGameEntity are standardized base implementations.
  • An EntityComponentManager maps game components to game entities in a game environment.
  • In the case of JME, compositing a BaseAppState class with an EntityComponentManager instance was the right solution for me.

Articular-ES internally features the following patterns:

  • The DI pattern (used among Base implementations).
  • The Legacy Template pattern (used among the framework interfaces).
  • The Observer pattern (used among game loop updates).
  • The Lifecycle pattern (milestone).
6 Likes

What’s wrong with Zay-ES?

2 Likes

Nothing, Zay-ES is perfect!

From a quick glance it seems it is very different from Zay-ES.

For example, I noticed you have an update method in component. In pure ES a component contains just data (think of a SQL table) and does not contain game logic inside. Game logic is handled by systems (combined with object actions IMO, for extra flexibility).

2 Likes

Yes, I have also seen some paradigms from other game engines displaying components as data only, In this API, Components are updateable objects, for example: a Position component needs to be updated by the game entity object to reflect the new position, a Clothes component too, and they are still data.

I used this from the book Game Programming Patterns to implement the API:
https://gameprogrammingpatterns.com/component.html

1 Like

So, it’s not really an ECS… which is fine. It’s just a mechanism for splitting an entity across domains. It throws away some other ECS benefits to do this, though.

I don’t know what to call it but it’s technically not an ECS, really.

Edit: Also, probably your post was worthy of its own announcement in its own thread but I guess it’s nice to kick off the screenshot thread for September… even if there is no screen shot. :slight_smile:

2 Likes

Yeah, I see. Unity uses a similar paradigm in its mono behavior too but in the new Unity DOTS ES framework, they have changed it and a component is now represented by a struct that is pure data.

1 Like

I would like to know more about those lost benefits.

Well, you can call it whatever you want :-), I utilized the Game Programming Patterns, Maybe the whole book is a lie and I don’t understand.

In this implementation, a Component is an interface that houses an overridable method, you don’t need to provide a logic for it, you can do it on your own!

public class DataComponent<I> implements Component<I> { 
     ...
    @Deprecated
    @Override
    public void update(I input) {}
}

Fine, now find other ways to update components, eventually leading to transmitting your update logic to the entity clogging up the entity with a lot of logic, and trivial design.

In short, in Entity Component System, an entity is just an ID, this entity can have one or more components added to it. One of the most fundamental parts of an ECS library is to provide a mechanism to listen to entity changes (component added, component updated, component removed). A system then would use that to watch entities changes.

I think the Zay-ES wiki page should be a good place to read more about this. It also contains an example.

I would suggest further discussions on ECS be continued on a separate thread. :slightly_smiling_face:

2 Likes

And actually, this is not a core tenet of ECS in general but an optimization that Zay-ES provides because it is “so darn useful”.

Many implementations of an ECS will completely invert control and instead of making a query and getting something like an EntitySet (Zay-ES) you would instead provide it with a callback that it will call for each entity. I found that less flexible and figured out a way to get all of the optimization benefits without the inversion of control… thus we get EntitySet and the nice applyChanges() + being able to see what has changed.

EntityContainer (from SiO2) is a mechanism to get a more of an inversion-of-control style “traditional” ECS callback. But even then, it’s more flexible because it also allows tracking your own system-specific object views if you like. (For example, a JME spatial.)

“component pattern” != “entity component system”

The former is a software design pattern. The latter is a specific set of patterns that grew out of hard memory constraints. It just so happened that out of those constraints was born a really useful way of decomposing problems… even if we don’t have those original constraints (or their benefits) in Java, we get the half-dozen or so other benefits of an ECS:

  • decomposed data and “duck typing”
  • free multithreading
  • fully independent systems
  • reasonably trivial persistence and networking

And many of those tie into each other and it’s hard to get rid of one small ECS principal without destroying some of those features. For example, if you remove “immutable components” then you lose free multithreading and most of fully independent systems and you weaken persistence and networking.

There are very specific and important reasons for everything that Zay-ES does so if you are ever curious about the “why” of some piece of Zay-ES, it can be instructive to ask. I have yet to find and ECS implementation that is a purer version… and I’m not trying to brag, I want to know so I can improve it. So I always look for examples.

(So far the one thing from the original ideas that I can’t do is only because Java won’t let me… and in Java it would be of questionable use anyway.)

1 Like

The problem is that the original author displays the same paradigm and uses the same namings making them identical. In addition, no one really has emphasized the use of immutable data or even the components as being “only immutable data”. Nonetheless, thanks for your review @Ali_RS @pspeed.

I guess this is a refactorable design error.

I am okay with that if you would like to.

1 Like

We could convert this whole thread to an announcement thread for your library and then let the first screen shot create the screen shot thread?

Yes, the author’s margin call-out is key:

Some component systems take this even further. Instead of a GameObject that contains its components, the game entity is just an ID, a number. Then, you maintain separate collections of components where each one knows the ID of the entity its attached to.

These entity component systems take decoupling components to the extreme and let you add new components to an entity without the entity even knowing. The Data Locality chapter has more details.

Essentially, he makes a classic error of grabbing one feature of what an entity component system is and deciding it’s the “same thing”. It throws away a lot of the goodness for some short term design convenience. And it’s very unfortunate. I wish I had time to go through the material in more detail to point out the numerous pitfalls.

The original idea for an ECS came from a design constraint where it was necessary to stream read-only memory in small chunks that produce new output data also streamed. Components were immutable because they were packed contiguously into entity blocks in RAM and the system would stream over them… it would then produce new packs of components into the output.

I like to think of that as the RAM equivalent of iterating over the results of an SQL query and writing data to another table. The SQL results have only the fields that are necessary and we write out only what we need. (Edit: if it’s not clear, I can provide an example of what I mean.)

In this way we can handle millions of “rows” without ever holding them all in RAM… which was a constraint of the streaming memory architecture where you had only a relatively small view of the stream at any given time.

From this design constraint, the other benefits sprung forth… many of which become impossible/infeasible if components are mutable. (Zay-ES allows mutable components but then the component-writer has to take a bunch of other things into account. I do this with the BodyPosition component which then gets several extra classes of support code just to be mutable.)

So if a game patterns author wants to treat entities like a fancy hashmap so systems can be a little bit decoupled, that’s fine… but when calling it an ECS, I look at it with side-eyes. He skimmed the surface feature cream off and left the cappuccino in the cup.

4 Likes

Note: if you do not have the permissions to do that then I can do it. I think your announcement deserves its own thread.

5 Likes

Captured from “Game Development Patterns and Best Practices (John P. Doran Matt Casanova)”:

image
image

LOL, seems to be something very popular, the very misleading presentations of facts.

1 Like

Mislabeled composition pattern. That is all.

Not even slightly an “entity component system”.

Edit: this object diagram is essential JME’s Controls and Spatials. Which was indeed long mislabeled by some as an “entity system” until they understood what an ECS actually was.

Edit 2: Note that it doesn’t take a super-genius to write a book and it’s important to look at some information side-ways. I remember reading an AI book and I couldn’t even get through one chapter because in the first 2 paragraphs the author had already used standard graph terms incorrectly… in some cases GLARINGLY incorrectly.

So just beware: just because someone wrote something down doesn’t make it true.

6 Likes

In this PR, I reintroduce the components as data only, I hope I haven’t introduced another mistake, applications now are implementation-wise, if you want to utilize a regular update (that runs in the game loop thread) then use updatable objects, regular StandardGameComponent objects are data only.

You are free to review and comment!

Note: This thread is not meant to provide an alternative brand-new ECS API or rival any existing APIs (it’s not even qualified to), I just do this as a matter of training on building APIs and understanding software paradigms.

3 Likes

Yep, and hopefully my responses are taken in kind. This turned out to be an excellent topic for going into the details of what makes an “entity component system” a unique way do to software. It’s so widely confused and sometimes it’s hard to articulate without good examples.

3 Likes

A video from the same author of the book “Game Programming Patterns”, Bob Nystrom:

I would like to know your opinion about the subject/info presented in this video, it’s equivalently similar to the book chapter “Component Pattern” with an addition of a use-case game.