Categories
entity systems

Entity System: RDBMS-Beta (a new example with source)

I’ve just added a new, improved Entity System design to the wiki. I’ve also created a github project for it where I’m about to check-in working source.

The only source I’ve provided is Java – but it’s an evolution upon the old “RDBMS with Code in Systems” type, that already has full source for Java and Objective-C – so you could easily upgrade the obj-c version to this new type (hint, hint).

What’s new?

Three major changes:

  1. Included a bunch of sensible java-specific improvements, based on the forks other people had done of the previous Java implementation
  2. Added a bunch of FANTASTICALLY USEFUL methods to the EntityManager – things you definitely need when writing a game
  3. Added a new concept: the Meta Entity

The first one is obvious, the second is obvious when you look at what’s added (e.g. a “removeComponent” method; why wasn’t it there originally? Solely because it wasn’t necessary to show “the simplest possible implementation”).

The interesting one is number three: the Meta Entity

What’s a MetaEntity?

A while back, in the first Java/Android ES I wrote about, I mentioned that I was using a fake Entity class.

I made a big fuss about how this was NOT being used to store any game data – but was instead an OOP trick to make it easier to write code.

Thinking about this later, I realised that there was really no need for that class to be named “Entity” – and calling it that ran the risk of tempting people into using OOP for their core data / components (Remember: Never do that!). Instead, looking back at a couple of example ES’s I’d written, I saw that every method – and all data – in this class was a “meta method”.

For the methods, you need to read the source AND the javadocs to see this.

For the data, it’s a lot more obvious: the only data that a MetaEntity has is:

  • The Entity itself (remember: that’s just an integer – or a UUID object in Java, which is a cleaner Java-specific way of handling it)
  • The EntityManager object which created this Entity, and which contains the Components for that Entity, and … basically provides all access to the data etc

i.e. if you pass around MetaEntity objects, you can feel safe that you know where they came from, where their components are, etc.

Because when you pass around raw Entity’s, they’re just an integer – which makes it easy to create an Entity in one EntityManager, then accidentally start using it in another EntityManager. Technically that’s illegal – but from a compiler perspective, it’s 100% legal … so you’ll get bizarre runtime bugs. Ouch.

Equally, the MetaEntity can contain a lot of single-argument and zero-argument versions of methods that exist in the EntityManager as 2-argument, or 1-argument methods. This greatly reduces typing, increases readability, and reduces opportunities for bugs. It may sound like a very small change (2 arguments dropping to 1), but I promise you: in practice, it makes a big difference.

Why not use MetaEntity’s all the time?

They’re very inefficient in how they use memory, and they throw away many (but not all) of the performance advantages of an ES.

For instance, because you’re moving from “integer + array of structs” to “linked-list of objects”, you’re making your game go from “cache friendly” to “cache poor”, and making your MINIMUM mem usage go from “tiny” to “small”.

In practice … if those differences matter to you, you’re probably writing a hardcore custom ES anyway.

More importantly: even in a “hardcore” ES, you don’t actually *need* that performance all the time. If you’re just pulling out a handful of Entities and their Components – e.g. a player Entity (of which there’s only 1 – or a few for multiplayer) – then the above performance differences are NON EXISTENT (vanishingly small).

…but the code is more readable, easier to maintain, and more robust.

So. I recommend using the MetaEntity for *all* your ES coding … until you reach a point where performance is low. Then look at re-coding *only* the affected loops / methods (remember: you can do this on a System-by-System basis; your code is nicely separated already!). That way, you get the best of both worlds.

However … the reason none of this was included in the first Java ES I posted onto the wiki – the ultra-simple “RDBMS-inspired with Code in Systems” – is that really this is all just gloss on top of an ES. You don’t need it. I believe it makes your ES easier to work with – but it distracts from the core theory.

I’d recommend you start with the simpler ES, and understand it, before moving onto something like this for your practical work.

For more info, check out the wikidot link at the top of this post – and try the github project linked from it (currently empty, until I do a check-in)

Did this post help you?

Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples