I think it's fair to say most ES tutorials barely contain interesting information. They talk about Components and Systems for: position, velocity, sprite, health, and that's about the depth of the article.
Indeed it's a bummer that most ES articles are so basic. The ones that are out there for Java at least are far more speculative than data oriented in benefits and lack implementation details.
The problem is that these things are no problem whatsoever in OO, when using encapsulation/composition, where you can toggle functionality at will (using inheritance is a rookie mistake). This approach obviously doesn't scale with the number of components, but... does it need to scale in this manner?
We agree that composition is the bees knees so to speak. A CA and thus ES brings implicit composition to the table and there are benefits to having this in the toolbox in addition to normal explicit composition and even a touch of inheritance, but not as a central organizational mechanism. The current Java ES implementations more or less have very limited CA features.
You get this sort of scaling for free built into a proper CA.
What would be a simple
use case for a game with limited scope, where an ES clearly excels over proper OO? Given your lengthy posts, ESs are clearly saving you enough time to elaborate, yet again
The chitchat monster is a demanding beast. As mentioned a limited scope game where no design changes are expected OO design is perfectly suited for the task.
The CA aspects are what really make things a pleasure during development. I'm not necessarily speaking about the currently available Java ES implementations. A lot of the killer use cases for me are modularization at the SDK / engine level which goes beyond the game focused limited CA ES implementations available.
In my efforts these are the things I like:
- Similar to Spring and such TyphonRT features a declarative loading mechanism to load up the runtime from external configuration files. This is great because conditional dependencies are externalized and not peppered through the codebase. System components can self-wire themselves and traverse implicitly the entire runtime environment let alone ES specific use cases.
- I use XML for the config files since it's available everywhere, but really it can be replaced with anything including a binary format. The really cool thing especially considering Android Studio Gradle integration in regard to build flavors is that it's super simple to provide just one XML file defining the app and completely load different functionality for product versions or any other mutation in development via providing a new flavor that simply has a different app XML config file rather than duplicating a code base. This is also very useful for multiple developers working on a shared codebase since new development can occur in parallel with less disruptions or requirements to embed factories and nasty other hacks to not disrupt developers depending on the old codebase while the new one is in progress.
- In combination with implicit message passing it's possible to completely separate dependencies between system components while maintaining functional connections. This isn't new and aligns more closely with Alan Kay's original ideas on what constitutes OO design if anything. Getting away from the listener pattern is key in conjunction with a CA / ES. This is something that bums me out when I look at Ashley since it uses the listener pattern which reduces flexibility considerably.
- Velocity of development is much faster with a proper CA and code changes don't require large refactorings. It's great for rapid development where data can be implicitly passed around.
- It makes large codebases manageable along with providing the basis for explicitly knowing dependencies of code at hand and being able to limit side effects. This valuable in testing and multi-developer environments. Get something working 100% correct and know with certainty that there are no unintended side effects with code changes not linked to the modules at hand. This includes keeping individual classes small and understandable.
- A CA provides dynamic / functional like characteristics that run on all Java platforms maintaining type safety which is a huge boon over scripting languages in general.
- The CA provides a standard API for accessing logic and data and there is far less method based boilerplate creation. While the concepts need to be grokked by devs it is consistent.
- As mentioned by others data components are DAO and facilitate journalling, serialization, and concurrency concerns.
- CA supports tooling better than rigid OOP code bases.
- A proper CA provides the magic sauce to implement runtime modularization that goes beyond the service pattern (re OSGi). A fast / dynamic CA implementation plays nice with OSGi and other future modularization frameworks.
--- I can go on, but indeed I procrastinate and have some work to get back to.. ;P
I think it's something that once you really need it and give it a go it's hard to return to old development practices when possible. I constantly get bummed out when I do any client work as most of it is very bottom basement regarding OO design. Re: 90's are calling and they want their design patterns back.
The "classic" use case in games is particles. There are usually a lot of them.
Modeling particles as objects is obviously not the proper way to handle things nor is it appropriate with ES on a per particle basis.
Being able to attach to any entity a single data component with an array of particles being tracked is nice without having to add accessor methods / explicit composition.
Building a next-gen CA / ES is not easy and very time consuming... Using a well constructed one for dev for games or otherwise is liberating. A lot of this is still forthcoming for Java. I'm an early adopter so to speak. I look forward to getting my CA / ES efforts out in the wild.
The chitchat monster says I'm being baited.. ;P again... :: sigh ::