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

79 replies on “Entity System: RDBMS-Beta (a new example with source)”

The link you gave at the bottom of http://entity-systems.wikidot.com/rdbms-beta is to the non-beta github site. I think the URL you meant there is https://github.com/adamgit/Entity-System-RDBMS-Beta–Java-.

I look forward to exploring the MetaEntity concept. I’ve not found myself in a position to need multiple entitymanagers in my development so far. Morgan’s Raid was highly state-based, and we just passed the entity manager from state object to state object via dependency injection.

Fixed, thanks.

In day to day use, the biggest benefits of MetaEntity are just that your code typing is greatly reduced ;).

Ideally, you’d perhaps use the MetaEntity as a flyweight object, filling it with the data from individual entities as you stride over the data, in such a way that the compiler filtered it all out at compile time.

I don’t think that would work in Java, but with e.g. C++ you might manage it.

Certainly interesting. I have a divergent implementation that addresses similar concerns to the “MetaEntity” construct described above. I hope you don’t mind me chatting about it. Any discussion is nice since this is new ground for me any many others.

I suppose first a little ES announcement. I’ll be giving a full day workshop at AnDevCon II in November on game development including at least a whole quarter of the workshop covering entity systems and associated component oriented programming (COP). This will coincide with the initial semi-public “alpha” release of TyphonRT.

—–
Now hopefully some meaningful conversation around the MetaEntity construct you described above. I mostly will describe how entity creation functions in my system offering it as a contrast to the MetaEntity construct. While in your overall implementation the MetaEntity construct is useful it really seems to be an extension of your implementation choices over a distinct concept with ES in general. IE I do it differently.. :)

First off in my implementation components / systems are stored in the Entity itself as opposed to separately in an EntityManager. This is a different direction which prevents the problem of not targeting the correct EntityManager if there is more than a default one and it seems a main concern for the creation of MetaEntity outside of a syntactic sugar methods. Flyweight components / systems in my ES can still be shared across EntityManagers.

The rough creation logic for my ES is that there is an EntityCreator that will take a type (extensible enum not an int) and a potential ITyphonBundle (essentially a String key/value HashMap with additional helper methods). The EntityCreator will do a look up based on the type and find an associated EntityAggregator. The EntityAggregator may just be a default shared instance for all types depending on the required game logic or different types may have different aggregators. The aggregator will then assign an EntityTracker potentially depending on custom constraints; position being a main one. An EntityTracker can be associated with bounding geometry for instance. Inside the EntityTracker one or more entity types are associated to an EntityManager. EntityManagers are usually split up by associated runtime logic and rendering systems for instance being able to batch render many entities at once as opposed to rendering each entity in entirety one after the other.

In the default / simplest case there is a 1:1 relationship and all entities share one default EntityAggregator, EntityTracker, and EntityManager.

This is basic creation:
entityCreator.create(EntityTypes.ENEMY);

For the time being I have a separate helper wrapper EntityComposer that will then add components / systems to the created entity for standard use cases. IE movable entity though I’ll likely put together a data driven optional system that will compose declaratively the entity when it’s created via the EntityAggregator.

For instance in a more complex game that has many EntityTrackers with respective bounding geometry one would add an entity to a particular area like this including an extra float for indicating 50% health:

ITyphonBundle bundle = TyphonBundleFactory.createBundle();
bundle.putInt(“x”, 1000)
bundle.putInt(“y”, 2000);
bundle.putInt(“z”, 200);
bundle.putFloat(“health”, 0.5f);
entityCreator.create(EntityTypes .ENEMY, bundle);

This can be completely data driven with the create method just taking one parameter (ITyphonBundle) as the extensible enum will be resolved via reflection:
bundle.putString(“enumtype”, “org.game.example.EntityTypes.ENEMY”);

The additional ITyphonBundle may describe current characteristics of the entity such as position or anything else a custom EntityAggregator, EntityTracker, EntityManager may understand including initialization of the actual components / systems that get slotted into the entity as they too are passed on this bundle for initialization.

—–

When an entity crosses bounding geometry of EntityTrackers the associated EntityAggregator can be queried to set the new EntityTracker and remove it from the old EntityTracker, etc.

The Entity class in my API contains a reference to the assigned EntityAggregator and a list referencing the current associated EntityTrackers to reduce time in querying for tracker bounding geometry.

—–

One final neat aspect (I may have mentioned before on your blog / apologies for repeat) is that there is essentially a GlobalEntityAggregator which contains a component recycler / component pool. When entities die or go away their components / systems are potentially recycled / reset and made immediately available for new entity creation across any entity type / aggregator, etc. A rock’s position component when destroyed gets recycled and becomes a new enemies position component, etc.

So the above is the outline of how I handle multiple regions / entity managers during creation and runtime to move entities between trackers and bounding geometry / regions. For instance if the player can not see a given EntityTracker just the runtime logic (physics, actions, etc.) is run and the entities are not rendered, etc.

All this above works with efficient memory use and adequate speed even for Android. And yes I can’t wait to officially launch my efforts and get tutorials & a blog setup so less wordy comments on yours.. :)

“bundle.putFloat(“health”, 0.5f);
entityCreator.create(EntityTypes .ENEMY, bundle);”

…so you throw away all compile-time type checking?

Personally, I find type-checking essential (and IDE auto-complete: it knows exactly what data exists on each type, so it gives me a very small set of options on each complete-action).

Saves a LOT of time when coding, and saves a MASSIVE amount of time in runtime bugs that are avoiced.

“…so you throw away all compile-time type checking?”

That example is for marshalling data in from an external source whether defined manually, in XML, a DB, or other mechanism. Also it was a little simplistic as keys can be more fully qualified and bundles stored in bundles. Since nested ITyphonBundles can be stored in a bundle it is possible to index a bundle by component class type:: to uniquely map a bundle to a concrete component instance.

Some of what I described in my last post is near the top of the TODO list. Once I move the EntityComposer aspects internally to the EntityAggregator the entity and all it’s components / systems will be created first, then data marshalled to it, and finally strong typing and such will be applied to any further logic of accessing particular data (position, etc.) to place entities into the appropriate EntityTracker.

Actual usage is strongly typed of course in an IDE:
entity.getAs(AnimateParams.class).health = 1d;
would fail as health is a float and of course won’t compile. One of course gets all the auto-complete IDE benefits, etc.

I’m not a DB expert per se, so I’d be glad to hear how you’d go about confirming the RDBMS columns / data or XML defined data actually maps to the actual field types when a component is instantiated. Heavy use of reflection in the marshal / bundle creation process or say somehow even directly setting actual fields especially private ones would be slow as molasses on Android; though through some caching of field accessors there could be a speed up.

So far no type checking during marshalling seems to be the fastest and I have a bit more experimentation to do, but that is down the TODO queue presently.

Another complexity of my ES and general COP API is that nesting is allowed and component hierarchies including entities can potentially have deep hierarchies; this makes things a lot more difficult for marshalling and DB storage.

I’m working towards proper RDBMS support and external transmission from the perspective of as low memory use and performance first. So indeed one of the last things I’ll be working out is a better way to marshal data hopefully without each component / system needing a specific UUID let alone the entity itself.

Even hash code generation regarding “hashCode()” for entities can be tricky, but I’m trying to leave that configurable with being able to swap in different implementations. Right now it’s super simple entity type ID and sequence number of entity type in the tracker combined when the entity is added to a tracker thus generating a unique hash code to that tracker. This could be extended as necessary for say packing in an EntityTracker ID or even a global int ID instead of a sequence number. Of course the “equals()” method of the Entity class checks types, then hash codes, then as necessary contained component counts and so on until equality is determined.

I suppose the above in reference to entity type ID (int) also gives away that I map extensible enums for entity type to integers when creating the hash code. Using extensible enums provides better type safety and visibility than ints in development and external storage.

There are good reasons to have an int type ID too such as sorting for batch rendering; ala RadixSort, etc.

Also extensible enums are the bomb. For the longest time I stored general entity state as a basic bit field / int and this is intractable and so is using an EnumSet / one defined enum type for all state. Recently I created an ExtEnumSet which is similar to EnumSet, but it packs in multiple extensible enum types. More on that here:
https://plus.google.com/117904596907381647757/posts/aHiaoA8f6WZ

General searches for extensible enum set and “extensible enum set” and various combinations extenumset don’t turn up anything in Google. The quotes version just turns up the little I’ve posted on it and now a 4th page will appear in a couple days.. :)

Regarding type safe marshalling.

In regard to storing data in a general HashMap inside the standard ITyphonBundle implementation TyphonBundle the utility methods of ITyphonBundle, for instance getFloat(“health”, 1), provides a default value if “health” is missing or not a float or convertible type. If a getter method is called say getBundle(“health”) and it is indeed a float / nonconvertible type a warning is logged in runtime. An aside, “getBundle” also has other variations for creating a new empty bundle or using a supplied default instead of returning null.

As mentioned I’m working towards external storage / serialization and have attempted to provide general interfaces as necessary, but this likely is going to be the one rough spot / unfinished area before initial alpha launch. Working around the clock here, but we’ll see when Nov rolls around.

This does bring up an improvement to TyphonBundle or an additional implementation TypedTyphonBundle that can store the type as well. Perhaps also working around autoboxing of primitive types. If it’s a primitive float it stores in an additional HashMap<String, Class> “java.lang.Float.TYPE”. I do have a custom collections API for primitive types and other optimizations like recycled / resettable iterators which is essential for runtime performance.

As you are likely aware your demo code is going to be highly impacted on Android due to the foreach loop and temporary iterator creation. Particularly the killEntity method of EntityManager will cause the most trouble as the getAll_X methods may be less used.

I’d be glad to discuss stuff online or offline if you’d like. If you have the time for a chat that’d be swell since I’m trying to tie up as many loose ends as possible with my effort before initial launch or soon afterward. Full public launch is slated for March though, so some time to iron out any rough patches.

I find it generally interesting that we are approaching things from different constraints. I’m very concerned with memory usage and performance for usage in real time games (FPS / RTS) and the constraints of Android including loading time whereas you seem keen on an RDBMS angle / optimize later approach. Granted I’m at this full time+ vs your occasional touching on the topic. As things go though there are many optimizations to be had at the actual ES API level and not just punting performance concerns to loop and method optimization of systems themselves as you mention. On the desktop maybe that is the case, but Android demands every bit of optimization possible. So yeah I guess my effort is one of those “hardcore” ES that is seeking a good balance of speed & memory usage, but still with general use in mind.

My trouble spot or remaining difficult spot to be ironed out is cleanly interfacing with external storage particularly on Android / SQLite in a near real time manner; this is only necessary for some types of games though.

Yep, for the source-code examples on entity-systems.wikidot.com I’ve been ignoring the can of worms around Serialization.

I’m mostly a fan of using XML or JSON for this during development (easy to debug, free OO importers/exporters already exist), and saying “at runtime, you only serialize/deserialize in massive blobs” – i.e. do a plain binary write of each entity as a struct, sequentially, to disk.

Or use an in-memory DB to start with, and let the DB handle serialization when you need it :)

>I’ve been ignoring the can of worms around Serialization

Indeed and adding nesting with potentially deep hierarchies only further complicates things! It’s certainly been nagging at me as I need to get there, but as you mention in memory data structures are easily manageable with or without a DB and how things have been oriented for my efforts up to now. IE it’s just a matter of loading in a relatively small amount of XML data and in the case of my FPS demo a bunch of binary data as I’m still using Auriga3D / an 80% complete Quake3 class Java engine for twitch testing. Barely just barely Q3DM1 loads on the G1 due to 16MB memory cap, but I likely can make things even more efficient. Brings me back to ’96 – ’99 w/ Java!

Doing the whole blob / entity serialization may be overkill on every change.. It’s basically a complex problem as you kind of have to break down the near real time data that must get in on nearly every change and conceivably postpone other writes in batches. I think I know what my 1st employee will be doing; you will have fun, honest, and be paid well! :P

I’m guessing at this moment I’m not going to get to full serialization by the time I have to get the initial alpha out for the AnDevCon workshop, but definitely need to work it out before full public launch in March.

Right now I’m mainly working around the “configuration by exception” mechanism such as the health example. getFloat(“health”, 1) defaulting to full health and only configured differently if it happens to be picked up from an external XML file or soon possibly a DB.

Full DB serialization on any component or conceivably minor system change regarding data stored is a bit of a challenge to do efficiently and generically enough to swap storage or transmission target / network, etc while maintaining near real time experience on Android. At least most game types can work in memory only. Open world building games could see a benefit of hitting a DB regularly, but really for Android its got to be mostly in memory.

With Android in particular, I got quite far with my last EntitySystem project just by using Java’s builtin “implements java.io.Serializable” on my Components, and serializing the entire EntityManager (with its full object-graph of all components, and all entities).

Very inelegant – but the code was quick and simple to write :) – and it worked fine for a few thousand entities.

>Java’s builtin “implements java.io.Serializable” on my Components

This is workable for a particular project / game, but is not all purpose. Finding a common / pluggable solution that can be replaced as necessary given the constraints of a variety of applications is the chore.

Right now in my efforts essentially all components / systems have an ITyphonCOPSerializer reference and component managers (an entity is such amongst more generic uses) can traverse the object-graph of stored components utilizing associated serializers along the way. When components are created via the EntityAggregator a given serializer instance can be set for a given type of component / system, etc. It’s really the only wholly non-vetted area of my efforts right now.

Hopefully I get around to thorough tests before the initial alpha, but it’s going to be close as the TODO list is lengthy, but getting shorter; likely have a vetted solution before full public launch. Anyway chatting on the topic is always helpful.. Hooah! ;)

I think it would be much more straightforward and understandable for others if you put all helper methods in an Entity class itself. Or, if you want to make it really right, leave it in some EntityManager or System and of course throw away easiness of working with this code (entity.doSomething(); vs. Manager.doSomething(entity);).

Back to where I started. The real “Meta” here is entity’s ID _value_ (int, UUID, whatever), which is actually _not_ exist. Imagine, you are storing this value in some List<>, fetching value from it, passing everywhere by the code. But there is no something like class Entity instance, with const address binded to it for its lifetime. Everytime you referring to some entity, you are using meta variable that exists and not exists in the same point of time. :)

***

You said something about memory inefficiency. But if I know Java a little, generics are just an abstraction on <Object>. List<Integer> is not the same as List<int> in C++. It would be somewhat the same, if I implement in C++ Int class and specialize it in List<Int&rt;. So when I am storing some value in it (list.put(1337)) or fetching (int val = list.get(“key”)), my handwritten boxing/unboxing code comes in play. Same you can think about what Java does when manipulating with generics and fundamental types.

***

In all of the previous discussions of ES in your articles, there was one unanswered question: how to handle interaction between entities. Common example, rocket hitting a tank. Should I work it out via direct relationship between systems (one calls another routines)? Or by emitting signals/events of what happens in my world? Or maybe queue all the events and let iterate over them by the systems I have running? As I remember you said that first two of proposed solutions are bad. But I do not remember anything about what is a right way(s).

***

@Mike Leahy
About “bundle.putFloat(“health”, 0.5f);”. Data marshalling is really a no excuse and I agree with Adam on static type checking. At least you can enumerate such kind of fields too:
enum Foo {HEALTH; public final String name; Foo(){this.name = getName();}}

(standart line about my bad english goes here. sorry)

“more straightforward and understandable for others if you put all helper methods in an Entity class itself. Or, if you want to make it really right, leave it in some EntityManager or System”

The temptation for OOP programmers is just too great, if you give them a class named “Entity”.

And, really, if you’re doing it right, *all* the helper methods should be in a flyweight or facade (c.f. OOP patterns) – and IME it’s very confusing to give a facade class the name of the thing it’s facading for.

The EntityManager already has these methods, but it makes code annoyingly verbose. Short of operator-overloading (which has massive problems of its own – not least: doesn’t exist in most languages), I can’t see a consistent cross-language, easy way of making the code concise enough?

I’m *VERY* interested in ideas here – the verbosity of ES code is one of the few recurring criticisms I have for lots of the ES designs I’ve seen.

“one unanswered question: how to handle interaction between entities. Common example, rocket hitting a tank. Should I work it out … Or maybe queue all the events and let iterate over them by the systems I have running?”

Not unanswered, answered multiple times. You’ve answered it yourself :).

If you think about it, this is how game-logic already works: look at Collision Detection. If you do it properly, there’s no object/object interaction – instead, there’s the generation of a meta-layer of info: the swept volumes.

You then need a whole separate algorithm / code / system that can understand those swept volumes and decide what to do with them.

If you do it badly, of course, you try doing things like:

object1.collidedWith( object2 ) // never do this – it throws away too much information

…I’m suspicious that approach comes from OOP-trained people who see the problem and sleepwalk into thinking it’s an OOP-problem. It’s not. It might work in trivial cases, but you quickly find lots of annoyign and horrible bugs, e.g. as soon as you get three objects colliding simultaneously. Ouch.

@nobody
You can be somebody some day! ;P

Before I get started I might just point out that this discussion can be confusing because both Adam and my ES implementations differ and as things go we are using common names such as “EntityManager”. Adam’s EntityManager does different things than the one in my implementation, but overall the concepts are coming from a similar area and the biggest thing I’ve borrowed is the component as data / system as logic categories as fundamental component types.

I do want to be respectful to Adam’s blog and concepts presented.

First I want to say I do want to discuss the process I use to create entities. I’m just putting the finishing touches on this in my API, so if there are perceived flaws I’d be glad to discuss.

@nobody:
“About “bundle.putFloat(“health”, 0.5f);”. Data marshalling is really a no excuse and I agree with Adam on static type checking.”

I admit it may not have been too clear. Passing in the bundle of data is more like a hint to the EntityAggregator such that once the entity is constructed it can set the really important data like position and place the entity into the correct zone / region / bounding area amongst a number of EntityTrackers. In most practical cases the really important hints are the world position of the entity. Since the EntityAggregator is particular to the type of entity being created once the entity is composed it will use the hints from the passed in bundle.

What I’m describing is a way to segment a larger world / game level with more than one default tracker. In this case it’s useful to have some meta-data available while the entity is being created.

So it goes like this:

– Dev gets access to the EntityCreator instance.

– (Optionally) Creates or reuses a bundle of data with say “x, y, z” position

– Invokes entityCreator.create(EnemyTypes.ENEMY, bundle);

– EntityCreator does a lookup based on entity type for an EntityAggregator

– The EntityAggregator composes programmatically or in a more data driven fashion the entity adding the relevant components / systems for the given type.

– The EntityAggregator being custom to the entity type created knows information about the entity and can use the passed in data bundle to set a minimum amount of relevant parameters. World position really being the most important.

– With a world position known the EntityAggregator can place the entity in the appropriate region / zone backed by an EntityTracker with a bounding area.

– The dev is then returned the entity from EntityCreator.

The above with passing in a bundle of non-typed key / value data is _not_ deserializing or loading an entity from a DB. I still need to work out a general provider API mechanism for this.

I also suppose I bring up the above control flow as it defines a “managed entity system”. As opposed to an unmanaged system. This also addresses Adam’s statement:

@adam:
“The temptation for OOP programmers is just too great, if you give them a class named “Entity”.”

There is no public constructor for the Entity class in my system and Entity is also designated final so it can’t be extended in an OOP manner. It’s necessary to use various creation / aggregation or replication functionality exposed separately in my ES to create entities.

Regarding the managed entity system aspects this just makes it easier for novices / intermediate devs to use the system for sure and provides a lot of flexibility especially on Android.

Since my larger effort TyphonRT is a runtime component architecture there are Application and Activity lifecycle components for managing entities automatically as a part of the Android lifecycle. IE there is an Application level system EntityAggregatorManager that when a new Android Activity is created will automatically create the corresponding EntityTrackers and EntityAggregators specific to that Activity. There is also an option to use global aggregators and trackers shared across Activities. The neat thing about this is that the developer can just ad hoc create entities and not worry about destroying or doing any sort of manual tracking. If an Android Activity is ended or destroyed the EntityAggregatorManager Application lifecycle component will pick up the Activity destruction and properly destroy all entities created ad hoc in a given Activity without manual intervention from the dev.

@adam
“I’m *VERY* interested in ideas here – the verbosity of ES code is one of the few recurring criticisms I have for lots of the ES designs I’ve seen.”

Excellent.. I feel I can contribute again to a shared dialogue on this aspect. I’m strongly moving towards extending TyphonRT officially with Scala support. Other JVM languages, Clojure being a close 2nd, will be supported too, but official API support at first will come through Scala to extend various Java based APIs for verbosity and usability concerns. One of course will be able to choose to stick just with the Java ES API and not use the Scala ES layer.

Java:
entity.getAs(AnimateParams.class).health;

Perhaps with Scala implicit conversions (no need for “.class”) and operator overloading:
entity.getAs(AnimateParams).health;
or
entity@AnimateParams.health

A whole conversation can be had on what would good operator overloading symbols be for standard ES conventions of adding, removing, and accessing components, etc.

I’ve got to finish up all the Java layer stuff with my work before I get to Scala, so the above is just conjecture on verbosity reduction and application of Scala implicit conversions / operator overloading.

Adam, the more I think about efficient serialization concerns I do see some benefit in having a flat structure or something closer to your EntityManager being keyed by UUID or a less heavy hash as opposed to storing the components directly in the Entity itself especially considering nesting components. Quite likely though each component / system may also need a UUID and separate lookup to aid in fast de/serialization. Ahh the trade off of memory vs speed. I’ll have to think on this a bit more; wheels are turning and glad for the discussion.

Hi Adam and everyone,

It’s really nice see people discussing and talking about entity/components.
But here is a question for you guys:

Imagine a card game, like 21 BlackJack (or Poker).

I want to represent Card (renderable cards)
We know that a card has one number/letter and one type/picture/ribbon. And we have the Joker card as well.

How could you represent the card?
1) As component:
– number : int (could be A=1, 2, 3, 4, 5, 6, 7, 8, 9, 10, J=11 , Q=12 , K=13, JOKER=14)
– type : int (the 4 different)

2) Each card is a component? (very ugly)
– JokerCardComp
– ACardComp

3) One component being the Deck of cards (with all cards). Maybe you can have 2 Decks.

4) As entity (but for this, it’s going to have a component to give the card it’s number and type).

And one deck of cards? How do you could represent?

I’m just curious about if for small problems in games (the card has a high reuse) could be done in ES. And see if it’s not going to make something too much complex for something simple.

Thanks!
rafael :)

Simple answer: whichever of those you like – ES’s are very good at letting you jump between multiple layers of abstraction, even halfway through a project.

In most projects, you’d start with (1): a CardType component that says which card it is, because that holds all the pertinent information in a conceptually simple and obvious way – and requires very little typing.

If it helps, look up any guides on designing Relational Database Schemas – fundamentally, when designing a schema, you’re solving the problem: “what’s the best way to represent this data while balancing between “everything I might want” and “the minimum I actually need”, while always makin sure I have “easy to maintain / modify later”.

I hope this doesn’t get too verbose. This is a chance to talk about a neat aspect of combining extensible enums and components.

I would create a “COP extensible enum” in my system which essentially is an enum that implements a defined interface that also extends the component interface type. You get the benefits of using an enum along with it being a component as well.. You’d use a basic entity container (call it “card”) and be able to set:

card.setAs(FrenchDeckCard.class, FrenchDeckCard.ACE_OF_SPADES);

You could have final public int values for rank though I’d recommend further enums defining rank and suit.

card.getAs(FrenchDeckCard.class).rank which would equal ACE
card.getAs(FrenchDeckCard.class).suit which would equal SPADES

You could also create additional interfaces to for a more generic representation of ranked & suited card decks.

Depending on how clever you want to be and potential variety of decks of cards you’d want to support you could create interfaces like IRankedCardType and ISuitedCardType that extend ICardType that extends ICOPExtensibleEnum, etc. etc. This last interface is a defined type in my component architecture.

IE FrenchDeckCard would extend IFrenchDeckCardType which extends IRankedCardType and ISuitedCardType each respectively has accessor methods getRank(), getSuit(). However these methods would return also extensible enums ICardRank and ICardSuit. When you define the FrenchDeckCard suits and ranks enums they are also made extensible by extending ICardRank and ICardSuit.

While you could also access the ordinal of the enum for an int value though I’d recommend adding getRankValue() and getSuitValue() methods to return an int representation.

This potentially allows storing and retrieving subsets of types:

card.setAs(IRankedCardType.class, FrenchDeckCard.ACE_OF_SPADES);

card.getAs(IRankedCardType.class).getRank();

This would return a ICardRank type which you can then do equality checking:
if (cardRank == FrenchDeckCard.Suit.SPADES)

Of course if your game is just based around the french deck you’d store the component as originally above.

card.setAs(FrenchDeckCard.class, FrenchDeckCard.ACE_OF_SPADES);

That way you could directly get back the enum for rank / suit of the FrenchDeckCard type and not the extensible enum ICardRank and ICardSuit thereby being able to use switch statements.

——

Also Adam.. I was tempted to post back here with some details on how I think I solved the serialization conundrum in my architecture that I discussed in messages above. It’s kind of neat, but will save for a rainy day. ;)

“While you could also access the ordinal of the enum for an int value though I’d recommend adding getRankValue() and getSuitValue() methods to return an int representation.

This potentially allows storing and retrieving subsets of types:”

It sounds like you’re just gradually turning it back into OOP.

Why would you do that?

I think you’d be better off sticking to ES style programming – or stay with OOP. They’re different ways of structuring your thinking, your code, your architecture. If you find yourself trying to do both together, in my experience that nearly always means you’re accidentally doing OOP in some part of your design where you neither need nor want it.

@adam and @Mike:
Thanks for the quick reply, really :)

@adam:
Exactly what I thought when I look to Mike example. This is a really nice implementation if you use OOP.

My question is:
– Card and Deck are simple, very simple. In a ES/components structure, if you make the Card and Deck as OOP, it’s a problem, right? Because you’re falling back to OOP and maybe your whole game is going be dependent from Card/Deck classes (even Components and Systems, maybe a AIComponent it’s going to be dependent from Card class, and this is not a good thing, right?)

And adam, I know I can do whatever I want, specially in the middle of project, but I’m very curious about how you would resolve this problem, could you send me your idea?

I have one idea, that is:
– Everything can be a card, maybe the camera or the player or a single card icon can be Card. So I will have a CardComponent with the rank and suit attributes/data.

If I do this, how can I made a Deck? If I create a DeckComponent, this component would need to know about the CardComponent, and the components can’t known each other, right?

How you would solve this problem of dependencies?

Thanks in advance,
Rafael.

Card:
– int: number
– int: suit
– entity_id: deck

Why do you even need a “deck”? Define it implicitly until/unless you need it explicit.

Architecture-wise, ES are well suited to the (mathematical definition of) “lazy”: don’t design this part of your app in detail until you need to; you can build a working app with big chunks of it working perfectly well in simple form.

Hi,

Ok and “Card” you mean a class Card as “container”, or Card is a component? The entity_id : Deck is like have a pointer for the “owner”, right?

For a simple 21/BlackJack game, the deck can be a “anchor” for where the card goes off, visually. And how many cards are left on the deck. Something like it. But I’m creating a deck dependency for study. I know I will have some dependency like this someday, and I’m trying to check alternatives in a case of study :)

Also, I don’t know how much time you’re working with ES, but it’s uses more memory than a optimized OOP game, right? There are going to be lot of classes instances (instances for components like PositionComponent with x : int, y : int) and, for some languages (like old Java (before 1.6)) that don’t have template or generics, it’s going to be lot of casting, right?
If I have a system that moves something, it’s going to have a casting for get the PositionComponent from some entity. Casting usually slow downs the running game/app.

Did you felt this decrease of performance and memory when you’re doing something, like your Android game?

Thanks again
rafael.

No class, ever. If you have a class somewhere, you’ve gone wrong.

Card == component.

“the deck can be a “anchor” for where the card goes off, visually”

OK, but that’s – potentially – a completely different, unrelated, problem – nothing to do with the cards you’re talking about.

The two could easily be merged, or could be separate. I’d suggest something like:

ScreenDeck (this is just a string name – not part of your code)
{
– cardSpawner: { deck_whose_cards_are_spawned }
– positionable: { x, y, width, height }
}

where -cardSpawner { } == the CardSpawner component, with the list of variables inside it

“for some languages (like old Java (before 1.6)) that don’t have template or generics, it’s going to be lot of casting, right?”

No. Java has had generics since 1.5

That means: more than SEVEN YEARS AGO.

If you’re coding on a platform that hasn’t been updated in seven years, you’re ****ed anyway :D.

>>This potentially allows storing and retrieving subsets of types:
>It sounds like you’re just gradually turning it back into OOP.

You rankled my feathers, but this is why I like you.. ;P

Nope, it seems like you are looking for a flaw that doesn’t exist in what I wrote; this is good though.. Your general comments about your idea of what an ES as the end all be all is what I question; as nicely as possible. Better over beers. :) No GDC for you in ’12? At least you mentioned somewhere that you were over GDC for the time being.

Above in my statement “potentially” is the key operational word. If you want to create specific top level types for each type of card / deck then do so. If the game just relies on one type of deck then this isn’t even a concern.

Creating an extensible enum as a component was the key idea being presented. You should understand that using enums is far better than bare ints especially when it comes to code maintenance, error handling, and understandability. A COP extensible enum as presented for suit / rank still maps perfectly fine to a RDBMS.

I don’t view my COP API, component oriented programming, as some pure incarnation devoid of OOP. My approach is like Scala I suppose. Scala isn’t a pure functional language, but a blend of OOP and functional approaches. In my work OOP is extremely minimized as the _central_ structural organizational construct on the storage / retrieval of components and systems just like your implementation, but it turns out to be quite useful at times while not necessary or required for defining contracts (interfaces) and leaves (components / systems).

The major difference is that components / systems are stored with the entity. Your implementation relies on a global lookup. This totally doesn’t scale at all with anything larger than a small / medium sized game; one especially without regions. I’ve mentioned this above / before; for instance your MetaEntity has just one hard coded EntityManager. What if you wanted to split up entities by bounding geometry of a large level and quickly cull non-visible entities. Your implementation makes this impossible and requires iteration through _all_ entities of the EntityManager when rendering. It’s academically minded without any extensive implementation; IE not 100% practical.

Even in the card example the bare int approach breaks down rather quickly.

I’ll replace “card” with “entity”

entity.getAs(Card.class).suit -> which is 3;

In your code are you going to do what with 3? What is “3” anyway. Is it hearts, clubs, or diamonds? Nope it’s spades.

switch (entity.getAs(Card.class).suit)
{
case 3:
switch (entity.getAs(Card.class).rank)
{
case 0:

break;
}
break;
}

or some horrendous if / else block comparing both suit / rank in each conditional.

If you want to then define static types; IE

public abstract class CardDef
{
public static final int CLUBS = 0;
public static final int DIAMONDS = 1;
public static final int HEARTS = 2;
public static final int SPADES = 3;

public static final int ACE = 0;
public static final int TWO = 1;

public static final int KING = 12;
}

and replace the hard coded ints in the switch statement with the the above separate definitions you’ve now made it a little more legible, but still have the nested mess and the potential for error handling needs to be explicitly enforced all over the place as it would be a tragedy if at some point a cards suit was set to 3485891 and rank to 123895912; for whatever reason.

or does this make more sense:

switch (entity.getAs(FrenchDeckCard.class))
{
case ACE_OF_SPADES:

break;
}

one can also specifically get the rank / suit separately:

entity.getAs(FrenchDeckCard.class).suit == SPADES

how is this OOP?

public enum FrenchCardDeck implements ICOPExtensibleEnum
{
public enum Suit { CLUBS, HEARTS, DIAMONDS, SPADES }
public enum Rank { ACE, TWO, THREE, FOUR … KING }

ACE_OF_CLUBS(CLUBS, ACE),
TWO_OF_CLUBS(CLUBS, TWO),

KING_OF_SPADES(SPADES, KING);

public final Suit suit;
public final Rank rank;

FrenchCardDeck(Suit suit, Rank rank)
{
this.suit = suit;
this.rank = rank;
}
}

Now you have 52 strongly typed and intelligible _components_. You can’t mess up your Card data by having suit == or rank != . It’s easy to translate an RDBMS columns for suit / rank to the proper enum based component.

Consider in even your implementation you have a marker interface for Component; ICOPExtensibleEnum is very similar as in my system it extends IComponent and IExtensibleEnum. IExtensibleEnum being the non component oriented type. The reason for a common extensible enum interface is to create an extensible enum set (ExtEnumSet) that requires a common base type for it to work. IE a very fast set implementation like EnumSet.

You may have gotten a little hung up with the “sub type” inheritance. Don’t mix up interfaces with the implementation. The interfaces and extended interfaces define the _contract_ of the component! A potential ISuitedRankedCard that defines “getRank”, “getRankValue”, “getSuit”, “getSuitValue” or extend ISuitedCard or IRankedCard is not OOP in implementation, but only in defining the contract. You are likely aware that enums can’t be extended to add new types. Thus by making the Suit and Rank enums extensible as well and providing a parent interface (IE contract) with “getRank” and “getSuit” you can then create specific strongly typed enums for any suited / ranked card deck and store any of these enums by the common contract.

Normal components and systems with my efforts can be top level extending just “AbstractComponent” in my system with IComponent interface. AbstractComponent containing a few common helper methods and some basic boolean state data like “disposable” and “recyclable” that are necessary for some higher level patterns in the component architecture and lifecycle.

My ES extends the COP API and now mind you when I say extends we’re talking one level of separation from basically a repository of components / systems. My Entity class contains a few helper methods like your MetaEntity and that is it. Unlike your global scope approach mine stores the components / systems with the Entity which extends ComponentManager. Entity is final though and can’t be extended and one _must_ interact with it by storing / retrieving components / systems. That is _not_ strictly OOP as one is prevented from extending Entity and thus breaking the cycle of OOP becoming a central structural organizational approach.

Adam says:
>I think you’d be better off sticking to ES style programming – or stay with OOP. They’re different ways of structuring your thinking, your code, your architecture. If you find yourself trying to do both together, in my experience that nearly always means you’re accidentally doing OOP in some part of your design where you neither need nor want it.

Huh? OOP has failed me big time. No love for OOP as the core structural organizational construct. My ES is practically like yours in regard to how to retrieve and store components / systems; the backing implementation differs. Actual components and systems that may or may not utilize OOP is _not_ the downfall of an ES or what defines “ES style programming”. OOP is the big evil for true modularity _if and only if_ it is the only structural organizational method used for an ES. IE the unbounded tree of inheritance and eventual blob anti-pattern that results.

Do keep in mind that I’m the one working with a 150k SLOC code base that is entirely based on my COP API now after almost 1.5 years of conversion to a fully component oriented architecture after years of “semi-modular” decomposition via OOP. By the time I release TyphonRT in March I’ll have spent between 13-15k hours on it, so hands on experience is a little more on my side with a non-trivial codebase. The TyphonRT platform is also the basis for a significant test game engine, a Quake 3 class engine that is all component oriented and employs the COP API and ES.

While I certainly appreciate the ES conversation. Your definition is not the end all be all of what is or is not an entity system, a component oriented architecture, or the final rule of “ES style programming”. You are defining a variation of a component oriented ES as so am I. I’m well aware of what OOP is and what a component architecture is all about. I actually had a considerable all OOP based entity system implemented and it failed. I’ve actually faced first hand the downside of implementing an OOP entity system then moved on… I actually went through the pain before finally realizing a component architecture as the core structural organizational method. Whether or not OOP employed in the “leaves” of the ES (IE components / systems) does not negate the core structural organization!

I’ll be doing the initial semi-public early access release of my efforts at AnDevCon II in November where I’m giving an all day workshop on game dev, component oriented architectures, entity systems, and such from the position of my efforts. I’m going to try darn hard to get things fully publicly launched by March ’12. I’d be glad to send you the code when early access opens.

So, yes, perhaps my hair is bristling a little, but then again you have a more confrontational tone in general BlahBlahBlah; this came through on JGO forums long ago.. ;P Nothing wrong with that, but I certainly know what I’m talking about too. Again all this is better w/ beers in hand.. :)

@adam, sorry, I mean before 1.5 (like J2ME, Java ME for Mobile Devices).
Yes, I know that this is bad, the most devices must run Java with target around 1.2 as well. J2ME with casting is totally slow, so I was trying to change somethings a little for not blow up the heap and test the ES on this language :)

The Deck question, I got the idea. Basically I would have an dependency between components and entity, that you show to me using the “entity_id : deck”, that’s the deck owner of the card. Thanks :)

I asked the Card as class because it would better put CardComponent. It’s going to be a class anyway with only 3 attributes (number, suit, deck)

By the way, did you already read about FRP? Do you think it’s better than ES as some people are saying?

@Mike, yes Mike, I got your point =)
I tthought you are using OOP just because like you said:
“IE FrenchDeckCard would extend IFrenchDeckCardType which extends IRankedCardType and ISuitedCardType each respectively has accessor methods getRank(), getSuit(). “.
You are using specification inside a component. That’s why…
I think this should be useful for UI stuff (But not mandatory)

The enum stuff and names, constants, I agree 500% with you. I prefer using enum, but some old languages like J2ME doesn’t supports enum, then I need go back to “final static int…”.

I talked about the problem, independent of the language just for see how it could be done, what ideas everyone have. How implement in another language is other thing (but something I know well). Like your method getAs(Something.class). I would never got this method in J2ME, but for Android, iPhone, PSP, C++, Obj-C, etc, sure I can =)

It’s very nice to discuss this with people that is doing the same stuff :)

@adam:
And about the memory or performance, did you think it’s considerable or is something that is not so much notice?

Thanks guys!

J2ME: I think you have no hope at all, unless you optimize the heck out of it – you wont’ be able to use any of hte reference implemenations, because they rely on data structures and metods that are fast in J2SE but very slow in J2ME.

So … you’ll have to re-implement the whole idea in lower-level data structures – and, yes, get rid of casting. Something painful using lots of int-arrays etc.

FRP – haven’t had time to try it myself. I’ve read the background on it a couple of times, sounds like a very smart approach. But also: hard to explain to other programmers / team members, and / or hard to integrate with an existing codebase.

(I only mention that because for me, using an ES in the first palce was partly just a reaction to the fact we can’t code big chunks of our apps in a Functional langauge, which would have been ideal. So, I wonder: is FRP ideal, but practically too expensive to get your team to adopt?)

Mike – avoided Disqus for a long time because it didn’t run on Android. Any android phone couldn’t comment – took them something like a year to fix that :(.

Now – assuming they finally fixed that (NB: not their fault – it was Android’s crappy web browser not supporting some CSS/javascript trick that disqus was using) .. it’s just a matter of: I can’t be bothered :).

Rafael:
>I tthought you are using OOP just because like you said
Me:
>>“IE FrenchDeckCard would extend IFrenchDeckCardType which extends IRankedCardType and ISuitedCardType each respectively has accessor methods getRank(), getSuit(). “.

Oops yeah.. I meant FrenchDeckCard _implements_ IFrenchDeckCardType. Though with interfaces “extends” is the keyword instead of implements when extending interfaces. Yes.. I perhaps am at times verbose, but really I’d love to get any feedback before I launch my efforts, so poking holes even if feathers are ruffled is appreciated.. I talked about the problem, independent of the language just for see how it could be done, what ideas everyone have.

Oh yes.. We’ve been chatting about Java. For an interesting take on the C++ side which is way different than Adam or my efforts check out the Proton SDK. It’s pretty trippy due to what you can do with C++ compared to Java
http://www.protonsdk.com

Java relies on collections and iteration whereas C++ has some extra tricks, but check out the ProtonSDK site.

—-

Memory and performance is not too bad, but there are additional differences between Adam’s base framework and my efforts that further minimize the down sides of Java. One thing my system has is a recycler that will pull apart entities and pool the individual components / systems and when a new entity is created it is composed from recycled components / systems when possible instead of new object creation. Kind of a meta object pool. There are some iteration concerns too that need to be overcome with Java. Those are the main concerns that need to be overcome for fast entity system usage on Java.

—-

If you don’t mind I’ll try and get around to a reply to your deck of cards and player questions though directed at Adam.. Perhaps sometime this weekend.

—-

Ah indeed Adam on Disqus.. no editing and HTML stripping makes it hard to have detailed discussions.. I’m sure they must have it fixed by now of course better browser these days on Android.

@adam:
Yeah, I know… old tech, but I’m taking as study to check how much effective can be the ES :-)
I always used a lot of int[] in J2ME games, but now I’m checking the components and entity system and trying to get a new idea. But I will not skip implement it new hardware also. =)

FRP I check it with Haskell, but I don’t know. The idea isn’t different so different than ES, but I think it’s too difficult for teams, like you said.
Also, I think FRP could be replaced n ES with signals and slots (that QT introduced).

@Mike:
The signals and slots I think it’s present in ProtonSDK in the quick read I have. I will take a look at it, but somehow I already had this website in my bookmarks, so I think I already see it someday.
I really don’t mind about you try to reply the deck of cards and player with your ideas :) It’s going to be very nice! I will watch for it in this post’s comments

@both of you ^^
The Deck and the Card, I got this as example, because it may contains dependency from one to other. It can be easily make a simple game as example in ES with it.
It’s a simple problem that can be solved of so many ways. :)

Hi again, adam (and I think Mike too :P)

One last question for you guys.
Take a Main Menu Screen, let’s do it as ES/Component.

We can have 3 images (or text, icons, whatever). 3 entities.
Entities (ID’s):
– “play button”
– “options”
– “exit”

I want to click/touch each entity.
Each entity I want to do some action.

I see 2 ways to do it:

A)
I can add an individual PositionComponent (with x, y, width, height) and a ButtonComponent for each entity. So the ButtonComponent check for touch/click (with x, y) events with the bounds of entity (by PositionComponent)

So I would have:
– PlayButtonComponent
– OptionsButtonComponent
– ExitButtonComponent

This works and is clear. But the maintenance for it would be very bad, because I would have 3 different Components with same actions (check for collision between event x, y and bounds, then do the special unique-action).

B)
I can have the ButtonComponent, that receives the touch event and this component and somehow he can passes this event to subsystem with the entity (or the subsystem have this info between entity and component?).
The subsystem then check the event was made in the entity “play button”, or in the entity “options”… then make the correct action: start the game, go to options screen.

Do you think the A or B method is better? I don’t know if you understood my idea from item B…. I hope you did.
How would you guys made something like it?

Thanks!

Why would you use an ES for a main menu screen? ES are for gameplay objects, right? Hammer != Screwdriver.

Hi, just a quick note, for the A) is going to be 3 subsystems

The Method B I know how to do clean and simple now :) But I wish to know your ideas as well yet.

@Tom H.
Hi Tom, I’m using for Main Menu for study issues. The most I could do with ES, more can I know about it’s pitfalls and what can be done better, it’s something that I’m doing just for study. :)
But I think maybe Adam would reply: “and why not to use?”
If you make a game and you will going to have buttons on MainMenu, you can use a ButtonComponent on something that’s ready. Even for UI. Maybe you just change Skin and Placement.

But this is just an idea, basically is for study by now =)

Tom and all… In my view ES are a specialized version of component architectures / component oriented programming that indeed are suited for gameplay objects. However a component architecture whether ES oriented or not could be used to implement this. Considering that game objects / entities need to be clicked on too they aren’t altogether different concepts.

Option A is better to have separate entities / objects per button.

One still would want to create a 2D scene graph that can traverse components / entities. At the very simplest this is just a list of buttons. Essentially this is how Adam’s work is setup presently too in EntityManager; IE just a list of entities. However, you want to generalize things as much as possible. You don’t particularly need customized “play, options, exit” button components. At a minimum you need a bounding params component for each button that contains an AABB. Depending on the implementation you can choose to handle the bounds checking as part of the 2D scene graph pulling data from the bounding params component or perhaps create a “CollisionSystem” that can be attached to each button which internally queries for the bounding params and does hit testing. The latter can encapsulate custom hit testing say non AABB shapes therefore the 2D scene graph can be simpler / more generic. If the CollisionSystem indicates a collision it could return the local coordinates relative to the button / entity.

You can then you can forward on the touch event to internal systems that “listen” for touch events. My generic implementation of this is neat and also is utilized in the deck / card implementation example I haven’t had time to answer above. Unfortunately it’s a little difficult to describe succinctly without an expanded code example which makes it obvious.

At a minimum though you can also have a generic action interface such that once the collision system returns a hit the 2D scene graph would then trigger it.

IE traverse all buttons / GUI objects doing the following

if (button.getAs(CollisionSystem2D.class).collide(x, y))
{
button.getAs(IActionSystem.class).performAction();
}

You’d likely want to add in null checks to make sure the collision system and action system exist though..

You can even anonymously define this action like…

button.setAs(IActionSystem.class, new IActionSystem()
{
public void performAction()
{
do something…
}
});

—-

I have a bit more involved and automatic ways to forward on specific events to contained systems without traversing all systems of an entity / component manager in my efforts, but perhaps a bit too detailed without a code example though as mentioned it also can be used in the deck / card example above I haven’t gotten too. Unfortunately I’m time crunched presently and haven’t gotten back to it. Will try to remember in mid Nov….

So basically this comment outlines that yes you can do a GUI system in a component oriented fashion. Whether it leverages an ES is just part of the details, but considering that entities need hit testing / input too it’s not all together strange perhaps to implement a 2D scene graph and GUI system with an ES.

@Mike:

Nice one, Mike! I think I got your idea.
That’s why you prefer the “Method A”. For ProtonSDK (I think you’re talking about it’s ES implementation), you will have lot’s of Button so, the performAction() method will have it’s own implementation, right?

I’m doing the ES more like adam, with entities as IDs and components only for store data. I have not used ProtonSDK yet, but I will after for check which implementation idea fit’s better.

That’s why I will do something more generic, like one ButtonComponent with “action” as it’s data.
3 entities, like “play button” that will set it’s ButtonComponent.action as “play”, “options” as “option” and “exit” as “exit”.
Then one subsystem specially for MainMenu handling, that will check which action from ButtonComponent was triggered and do something about it.

MY problem is how forward the event of click/touch. I like your idea about traverse and collision. Will read more carefully and try to make something with this idea.

Thanks a lot for the reply. =)

“What Tom H said”.

If you want to learn about how to use an ES, then make a game using an ES.

Don’t make a menu system – it’s far too different, you’re adding a level of abstraction that helps you not at all.

Look at “Escape from the Pit” – I wrote that in about 8 hours, from nothing, a complete game (you can get the source code too, with the full ES implementation, all from the github page). If I can do a whole game in 8 hours, why are you wasting your time “practicing” with menu systems?

Make a game!

PS: next time I do a big game, I will probably make a menu system based on an ES – but that’s because I want to do cool stuff, like have the buttons fly into the game itself, or have game objects fly out of the game when you die, and start shooting at the buttons. Or something.

This is Not Normal: I would strongly advise you do NOT do this until/unless you are extermely comfortable with ES in practice.

Hi Adam,

I already did a lot of games…
With ES I’m studying and little by little creating some game demos as exercise :) Now I got the ES to Main Screen just for what you said: “I want something dynamic, fancy”. Cool Stuff.

In a game I did, I used an animation system I had created from scratch to make the whole game. Even the Splash, Intro, MainMenu, etc. It was really nice, low-memory usage (like you know, J2ME). I could easily port the game for other hardwares, even because I had done a framework that resembles a lot the ES that you describe.
I did saw the “Escape from the Pit” game. It was cool the source code, clean. You should enter in these 48-hour contests someday ^^
The only “flaw” (I don’t know the exact word to describe, sorry!), is just the touch events. I know Android doesn’t helps very much in the TouchScreen part, but I think maybe you can turn it more generic.
You have the CPosition class. It has x, y, width, height, scale, rotation. So you do have the bounds for whatever entity uses CPosition. So you could generalize the collision and sync the events to not overflow the PlayerMovement system, but use this for any subsystem that you may need input.

@Rafael:

>”I’m doing the ES more like adam, with entities as IDs and components only for store data. I have not used ProtonSDK yet, but I will after for check which implementation idea fit’s better.”

I brought up the ProtonSDK for a C++ entity system example. It’s pretty funky what can be done with ProtonSDK due to C++. I’m not involved with that and have a Java based component architecture and ES extension for use on J2SE and Android called TyphonRT. An early access release will be available soon.

As mentioned above in various comments it’s kind of hard to follow between Adam’s implementation and mine in regard to the small differences of the entity system architecture itself. However what I mentioned in the last comment will work for both Adam’s system and mine essentially. The one thing I adopted from Adam’s efforts is the components as data, systems as logic fundamental breakdown.

Regarding how to forward on any given type of event to various systems contained in an entity my architecture has a solution. Adam’s not so much due to the separation of globally storing components / systems separately from the entity itself.

I’ll try and be brief and as mentioned this will make more sense with a full code example, but since components / systems are stored directly in the entity in my architecture I have made an internal system used by the ComponentManager (IE Entity is final, but extends ComponentManager) called AbstractComponentManagerControl (ACMC). Internally ComponentManager has for all add, set, remove operations a method like “setComponentImpl”. ACMC has a public implementation of setComponentImpl and when this method is called in ComponentManager first all stored ACMC instances are iterated through to provide special actions for the setComponent process. Each ACMC may also veto or deny setting a component for whatever reason. This is how you can make an entity / component manager “final” in my architecture by adding an ACMC that vetoes all further additions / removals of components / systems. It’s also possible to create a registration based ACMC and I have one for all supported input types or other various purposes.

For instance say we do this…

entity.setSystem(MovementSystem.class, ms);

The input registration ACMC is triggered and it evaluates the added system and sees that it supports ICOPTouchListener and ICOPSensorListener event systems. The ACMC allows addition of the MovementSystem, but also internally registers “ms” like you called this:

entity.addSystem(ICOPTouchListener.class, ms);
entity.addSystem(ICOPSensorListener.class, ms);

This way you can iterate through all ICOPTouchListener instances of an entity without having to know which particular component or system types implements a given input interface.

IE
for (Iterator iter = entity.getSystemCollection(ICOPTouchListener.class).iterator(); iter.hasNext();)
{
iter.next().handleTouchEvent(event); // etc
}

This is psuedo-code above.

The nice thing is that when you remove the MovementSystem from the entity with:

entity.unsetSystem(MovementSystem.class);

the input registration ACMC will unregister it from the associated input system types ICOPTouchListener, etc.

This is only really practical if you store the components / systems with the entity itself from an architecture standpoint and this is not something that will work out well or be possible with Adam’s ES architecture due to the generic and global nature of his EntityManager.

In my efforts the cool thing is that you can assign any variety of ACMC controls to any component manager / entity and specialize the way the component manager works internally. You can also provide static ACMC shared across all entities as long as in their implementation they don’t modify local data. I use a static ACMC to provide dynamic injection / extraction of data into added components / systems. At the most basic level that is just injecting / extracting the component manager / entity into added components & systems. The ACMC approach is also how I am solving my “serialization debacle” alluded to in early comments way above.

I’d use this same type of functionality to pull off some interesting interaction for the deck / card / player example above too.

@Rafael and all..

Also consider when I mention my Entity extends ComponentManager in my architecture as far as interfaces go Adam’s MetaEntity is effectively similar to my Entity. With Adam’s MetaEntity it encapsulates the implementation details of forwarding on the int id to the EntityManager. So with the following:

MetaEntity entity;
entity.get(MovementSystem.class);

is essentially the same as my architecture:
Entity entity;
entity.getAsSystem(MovementSystem.class);

The difference behind the scene is that Adam’s system stores components / systems globally in an EntityManager whereas my architecture stores them with the Entity itself. So everything that I’m mentioning about my architecture _for the most part_ can be done with Adam’s architecture. This is why I’ve been so chatty in this thread due to functional similarities between our independent ES implementations.

In the pseudo-code listed above I haven’t exactly been consistent with my API either for brevity, but the concepts should be coming through, etc.

@adam and @Mike

Adam, In your game “Escape from the Pit” you create these components:
– CDrawableRectangle
– CAndroidDrawable

The CAndroidDrawable will draw some image/resource. That’s like the arrows updated when you touch the screen.

You have the RenderSystemSimpleDrawable for render the android-drawables (png images) and the color rectangles.

I made a game here, and it’s has some enemies. The enemies will show a sprite image (png), a text with the enemy health and a health bar.

For optimization, usually you would iterate between enemies, and draw it completely (first image, then health bar, then health text, to maintain z-order).
In the ES system, what do you think is best, method 1 that uses pure ES, or method 2 that try to unify with interface specialization:

1) Create a RenderSystemSimpleDrawable that’s render simple png images and rectangles, like yours, then create a RenderSystemEnemy that will render enemies. (And then modify the Game to call the RenderSystemSimpleDrawable then the RenderSystemEnemy, because the z-Order). And also, maybe a RenderSystemHUD because I won’t put the HUD in RenderSystemSimpleDrawable, because would stay below an Enemy.
Or maybe create in the game a orderedRenderSystemList to make sure that systems that render things are in the right order.

2) Create a single RenderSystemAdvance that’s render a collection of “Drawables” interfaces that has a method “- draw(Graphics)”

Then, the “enemy 1” entity will have:
– HealthComponent
# health : integer

– NameComponent
# name : String

– AdvancedDrawableComponent
# drawable : Drawable (the interface)

Then I would create:
class EnemyDrawable <> Drawable
{
private void draw(Graphics g) {
// Draw image from Enemy
// Draw Health Bar
// Draw Health text
}
}

What do you guys think?

Thanks,
Rafael.

NOTES:

class EnemyDrawable Drawable
=
class EnemyDrawable implements Drawable

and for “// Draw image from Enemy”, I’m not referring Enemy as a class, because it’s a entity, I mean an Enemy image, maybe a common image) ^^

” For optimization, usually you would…”

Yep – the render system I implemented in that game is RUBBISH :).

There’s nothing special about a rendering system in an ES – you should be happily using standard game-dev techniques.

e.g. write an algorithm “sort all sprites before rendering”, and invoke that once per frame before doing the render. This is probably just an internal method / class within the render system (Because that sort is renderer-specific).

— NB: this “sort sprites” method will PROBABLY need you to add some extra data to the Renderable components. e.g. for a HUD, it’s common to mark some sprites as “int:layer”, where layer 0 = error messages / pause screen … layers 1-10 = HUD … layers 10-100 = game.

… and then you usually want extra information to sort things within a layer – again, this means adding extra varaibles to your Renderable component.

Your option 2 is wrong – don’t do that – you’re throwing away the ES. The “Drawable.draw()” approach is a bit of a hack for OOP that’s almost never used in mainstream games. If you care about performance, you nearly always need a renderer that can e.g. “batch” the render calls in an optimized manner (e.g. for OpenGL / D3D there are ordering considerations) – which is impossible if every sprite is “drawing itself”.

@adam,

Ok, nice! Thanks.

But how would you handle the text between the image this way?
You will need to have a DrawableTextComponent and a DrawableImageComponent and a DrawableRectComponent (for the HealthBar), right? The RenderSystem will be enormous and “probably” game-specific, because maybe in other game I won’t have any health bar to draw. So this part of “health bar rendering” in RenderSubsystem will have to be modified, or not?

Yep – render systems are normally game-specific, by the time you get to the end of the game :(.

The ES doesn’t really change this – you *can* make re-usable renderers, but it’s expensive and often means a loss of performance.

To answer your specific questions, since you’re using Java/J2ME I’d probably start with something like Slick or JME, and see how they handle it – lots of peope using them, and they’re both opensource java game engines that take rendering seriously.

@Rafael

Indeed rendering….

Since the entire platform architecture is component oriented with my efforts things are a bit different. In my efforts the ES is an extension of the component architecture. One nice thing this lends is that the EntityManager and EntityTracker in my system are also component managers. I have a couple basic interface defined systems for runtime updating with time; “IRuntimeUpdatable”. The EntityManager itself can be assigned one and it is run every frame and can build a sorted entity set. Each entity has one too though it’s often a common one shared between entities. The nice thing about ultimately having an int type ID accessible in my ES is that entities can be quickly sorted via a radix sort. Also the EntityManager can be set with an IEntitySetRenderer system and from there can dispatch various drawing routines based on entity type ID after the entity set for the frame is built.

I do not store a renderer system in the entity itself. One of the demos I’ll have for the bounding geometry 3D test is in fact shooting a gun with the bullet crossing bounding geometry of various EntityTrackers and thus being shuffled between trackers, however internally each tracker has one or more EntityManagers (essentially lists) that have different renderers attached. I’ll likely be simply modifying the color of the bullet as it crosses tracker boundaries, but what is really happening is that the IEntitySetRenderer is different for each EntityTracker/Manager.

Regarding a HUD and such. Again the nice thing about the general component architecture over here is that you can declaratively define things in XML quite easily to attach to the main view and stack them. IE define the system that will draw the background, then the ES, then the HUD. The HUD system when attached can get access to the main activity or application component manager instance and find the various ES components / systems and self wire itself to get access to say the player entity or what have you to render the HUD display.

So this is a major benefit and I happen to be a big proponent of having a general component architecture and considering the ES as an extension of it such that the core parts of the ES itself EntityManager / EntityTracker may be declaratively defined via add in systems to alter functionality. Likewise the general renderer path can be defined declaratively such that it can be modified in a generic manner. I’m using XML currently, but could be other mechanisms too. If you don’t like the default systems provided by my efforts and they don’t fit the game one is free to substitute custom systems as necessary to complete custom rendering, but one is still using a generally defined framework. Of course if the whole framework doesn’t work for you then completely ignore the add in runtime systems of EntityManager and roll what you got to roll.

I think it’s quite possible to define a general rendering framework for all visual components including the ES and have it transfer between games while maintaining great performance. Of course this is still a theoretical statement with my efforts not being in wide use yet, but it’s OK so far in my essential 2D / 3D demos and Auriga 3D, Quake 3 class test engine.

Thanks Mike!
I will look forward it =)

I understood what you mean (I hope) hehe.

Now another question:

“Escape from the Pit” of Adam, was written in ES. I can use it’s components and systems in around more than 40 games without modify. I can use the CPosition, CDrawable, etc.
But the requirements to this work is:
– Need to be Android application.

If I use the ES system in a framework that generate code for Java, Android, PC, Mac, and uses the framework inputHandler (something like in the processOneGameTick() from subsystem uses: “frameworkMain.hasTouch()”, “frameworkMain.getTouchXY()”) than uses TouchEvent for each subsystem) and make the components requirements be:
– Need to be a application with the Framework FWJava
I can write a lot of application and games, with shared components/system between it, but will require the FWJava just like “Escape from the Pit” requires Android API

The framework is totally OOP based, the ES will be an extension to it.

is that ok, right? It’s like the Android above, but targeting more devices.

Just for make sure that this is OK (PS: It’s a framework that the source code can be changed entirely)

@Rafael:

Ah yes.. If I parse your comment above you are bringing up the “input conundrum”.. ;) It sounds like you’d like to create a Java game that runs across various desktop configurations and Android devices.

Input event handling certainly differs in this case. Part of the runtime of my efforts translates efficiently platform events to generic component oriented events. This way it’s possible to not have hard coded requirements on any given underlying platform API. As far as my middleware goes the component oriented input abstraction counts for almost 10% of platform components; almost 60. The cool thing is that there is no interdependence between input types unlike a kitchen sink API. I could go on, but perhaps confirm that you are concerned about input handling between platforms.

If particular systems in an ES rely on an underlying platforms input APIs then yeah things aren’t easy to reuse across platforms. I’ve put a ton of effort into this regarding cross-platform J2SE and Android support.

@Mike

Yes, but you will have to connect somehow the input from J2SE (that’s accomplished in Swing API by addMouseEvent() and addMouseMotionEvent() methods and the Android API setOnTouch()) to your framework input handler (or input events somehow), right?

And the components/systems will be 100% dependent from your framework if it use touch/mouse.

But if you have something like TouchTriggerComponent that is created and attached to entities when collides (or something else), sure the components/systems that “parse’ the TouchTriggerComponent is going to be API free. (I got it? is something like that, right?)

But is not with inputs only I’m concerned, is all the API, image handling, caching, input, sound… :)

Comments are closed.