Component Systems: Artemis style systems vs. traditional fat entities

I’d like to start a discussion on how people are currently using entity systems, and how they’re structuring them. I’ve personally moved away from traditional inheritance-heavy (‘old’) game structure a while ago, but only recently tried using a more formal entity system to handle the gameplay logic side of things. I’ve also had two projects running concurrently, one using Artemis which uses ‘thin’ components (like the position example here) with no logic and just uses systems to do the logic, and one built in Unity, which uses a more ‘traditional’ approach where the components are ‘fat’ and contain their state and logic.

Initially I really got along with the Artemis style, defining aspect-like systems really helped with functionality that spanned multiple component types. However the more I use it the more I feel like I’m butting up against limitations. Often I’ll end up having to set flags in components in one system for another system to pick up on later, resulting in lots of polling-style code and the inability to have much event-based gameplay code (at least, without doing some slight mental contortions).

Of course, I could just use Artemis and write ‘fat’ components, which is what I’m going to do as an experiment in my next project. But I’m wondering what other people have made of the thin vs fat approaches, and if one really paid off one way or another.

The polling style wouldn’t be too bad except on android it really sucks up a lot of extra cpu time, just to enforce a seemingly arbitrary design separation. (Yes, I’m aware of artemis-odb and will be switching to that soon). Along with that, some task that feel like they should be simple end up being much harder than they should be.

Artemis still lists itself as “an experimental framework based on an experimental concept”. Do you think the experiment is a success or not?

I suppose it depends why you’re using an entity system… if it’s to make your code more readable and understandable and easy to maintain… then that’s a fail, as it doesn’t really do any of that at all, most especially not in Java where you just don’t have the available syntactical constructs to help you, not even structs. I think the only reason for entity systems generally to exist at the moment is if you’ve got so many entities that you’re having trouble processing them all in a timely fashion.

Cas :slight_smile:

I declare problem space inversion. Screw all of this shit. Problem first. Potential solution(s) second. Solutions yield data. Data defines want the code should be. So: code comes last.

Ah, and I tought I was the only one thinking purely data-driven designs are an exceptionally poor fit for realtime games. There are huge advantages for entity systems for specific (serverside) use cases, when plowing through gigabytes of indexed data. Clientside, to me, it’s a nice toy worthy of kick and a squeeze on a rainy afternoon.

The advantage is from being cache friendly. Nothing to do with component base which increase complexity. Not my point though. My point being: “I’ve friends coming over tonight. Should I buy a keg of beer or one chicken?”

Cache friendly for small data (memory bound I/O), indexes for large data (disk bound I/O).

I think entity systems often confuse two separate design goals - being cache-friendly, and managing the complexity that comes with lots of different object types and gameplay behaviours.

On the first, I agree that entity systems tend to be overkill for client programming, particularly for Java where you can’t precisely control memory layout, so cache coherency is mostly a guess anyway.

The second however I’m firmly behind. Any game of moderate complexity really benefits from the separation of gameplay features that an entity system brings. Yes, there are other approaches that yield similar results, and that’s fine, but the component system seems to work pretty well and other people are instantly familiar with it which is handy as well.

Entity systems also really pay off when you’ve got multiple gameplay programmers trying not to step on each other’s toes, or designers who put your components together in interesting ways and come up with behaviour you hadn’t even thought of yet.

However I’d rather not debate all of that - if you don’t want to use an entity system that’s fine, but I’d like to discuss the higher level approaches people are taking to their entity systems.

I don’t really have much experience coding games that don’t use an ECS; maybe I’ve just been exposed to poor design, but imo an ECS does help structure the design and - thanks to the emphasis on compartmentalizing game logic in distinct entity systems - isn’t as sensitive to spaghettification/ridiculous coupling.

Benefits of using an ECS - or stuff one pretty much gets for free:

  • Since components are pure data, serialization comes almost at no cost (code-wise).
  • Entity systems can easily be reused outside the game, very handy for level/game editors.
  • New types can be defined on the fly - another boon for editors. Furthermore, it’s pretty straightforward writing a generic reflexive editor for manipulating component data.
  • Behavior reuse > code reuse.
  • Easy to profile, both via profiler and in-game.
  • Entity Systems can be toggled at runtime; pretty useful for debug renderers, disabling collision handling etc.

Lastly, to respond to the OP and fat components; it’s certainly doable, but it tends to make the code a little more rigid and hence harder to refactor.

It’s true that one of the potential benefits of ECS is writing cache-friendly code, but aside from us being in java-land now, it’s not quite as simple as strapping on an ECS and automatically reaping the benefits of a happy cpu/cache relationship - Adam Martin wrote an interesting post on it recently: http://t-machine.org/index.php/2014/03/08/data-structures-for-entity-systems-contiguous-memory/

Most of the early work with ECS appears to have more to do with fast iteration times, rather than fast execution.

Good stuff!

Yes, I am seeing a bit of this - an artemis-style system seems to be optimal in terms of code reuse and flexibility, but I’m seeing that come at the expense of some readability and having to resort to polling behaviour over event-driven code.

Of course there’s nothing to stop me putting event-driven code into the thin components and mixing the two approaches, but I suspect that would get messy and confusing quickly.

No need to poll, better sacrifice some memory and have each system maintain a list of all entities with a matching component composition. Entity Systems are notified whenever an entity has components added or removed, keeping the list up-to-date. This is how artemis and most ECS frameworks do it.

Edit: Sorry, misread your post. If dealing with a lot of entities… simply setting a flag here and there as a marker for being processed by another system, I could see why it might be a problem (are you sure it is the bottleneck though?). One solution might be a custom EntitySystem to which you manually insert entities that need to be processed as a result of some state. Alternatively, make the components even thinner, effectively having marker components and more specialized systems.

Yeah, I’ve seen this solution a couple of times. It kinda makes sense, but the resulting code is definitely harder to read, and adding an entire new EntitySystem for this behaviour is pretty heavy in terms of boilerplate code for what really should just be a method call.

It probably depends how finely you slice up your logic though - if you have bigger, chunkier entity systems that do more than you don’t need signalling flags as much, but then you’re left with more specialised code and you veer toward the Blob system that does everything.

I try to keep both my entity systems and components as specialized as possible: naturally, different games warrant different solutions, but I haven’t found the need for optimizing in regards to marker components in a long time.

Marker components aren’t that expensive, normally. Where and why is your CPU time consumed - because of a high entity count, sporadic insert/remove bursts, something else? It’s hard to reason about an approach without seeing some example code or knowing more about your design - the risk is that you end up getting vague recommendations that don’t really apply to your project.

A recent discussion over at reddit gave some ideas on how to more efficiently deal with batch insertion/removal of entities. It will find its way into 0.7.0 (sometime during the summer) - it might cover your use-case, or at least be slightly easier on the CPU.

What’s a disk? Oh yeah…that thing WAY over there. Am I on the “java-datamining” forum? :wink:

For my situation it’s a high (+500) entity count that I’m trying to keep running at 60hz on android, so the cpu is a bit limited to start with. It absolutely flies without even trying on my ancient desktop, but not so on android.

Mostly I’m seeing a significant amount of time burned in just entity/component iteration, looping over entities to check if things are changed and pushing data from one component to another. It’s not that this is bad per se, it’s just that it’s unnecessary work eating up my cpu budget, especially when most of the entities aren’t visible right now but due to the nature of the system it’s hard to not process everything all the time.

Information. Good. Android: changes everything. What min version? 500+ entities: what’s that mean. Logically active? Estimate of number “in the hot-seat” (need to be reactive and running at full rate). Only the latter really matters. And if that’s large it’ll dictate the design.

Exactly my point. Why are you asking about something you know? Code to the statistically significant.

500 entities isn’t that much. I’ve managed just below 60 FPS on an old Desire Z (android 2.3, single core 800 MHz Scorpion) with 500 +/- 100 entities and ~25 entity systems.

  • Don’t use getters/setters for components. The JIT will inline them, but it will take time before everything is inlined
  • Override processEntities and optimize which entities get processed; either by splitting the processing over two ticks or by some clever filtering (this implies that you manage the entities yourself in an optimized list, override inserted/removed in EntitySystem or roll your own)
  • Direct array access is faster than getting each entity individually (processEntities): artemis-odb does this by default.

Another pet-peeve of mine. FPS = Fucking Pointless System of measure. Interest measures are nano/micro seconds per data transform. Like X nanoseconds to update N entities motion (or whatever).

Also, does the figure include actual rendering or is that just logic or is it logic and preparation to render?

Cas :slight_smile:

FPS isn’t a benchmark, rather an overall performance target. On mobiles, I think one can easily get away with 30FPS, as long as it doesn’t dip below it.

Logic + preparation, I didn’t/haven’t investigated how to reliably get the FPS on android.

Yes. And that’s the only place it has any meaning. Does the whole system meet my target? It useless for anything else. Worse it’s misleading.

I have this fantastic HDR, physically based, screen space shading code! It runs at 200FPS!!! So you can just drop it in any old game and not worry about performance!!! Except that ain’t so. It ignores the math…even assuming the “user” has the same (or better) GPU.