Composition heavy OOP vs pure entity component systems?

I admit, I have made the sin of overusing, and even abusing inheritance. The first (text) game project that I made when I was taking my OOP course went as far as “Locked door” and “unlocked door” from “Door” and “Room with one door”, “Room with two doors”, and so on from “Room”.

With the (graphical) game I worked on recently, I thought I had learned my lesson and put a limit on using inheritance. However I noticed the problems soon beginning to appear. My root class was beginning to bloat more and more, and my leaf classes were full of duplicate codes.

I thought I was still doing things wrong, and after looking it up online I discovered that I wasn’t the only one with this problem. It’s how I ended up discovering Entity systems after some thorough research (read: googlefu)

When I began reading on it, I was able to see how clearly it was able to solve the problems I was having with the traditional OOP hierarchy with components. These were in the first readings however. When I stumbled upon more… “radical” ES approaches, such as the one at T-Machine.

I began disagreeing with the methods they were using. A pure component system seemed either overkill, or rather, unintuitive, which is probably the strength of OOP. The author goes so far as to say that ES system is the opposite of OOP, and while it may be usable along OOP, it really shouldn’t. I’m not saying it’s wrong, but I just didn’t feel like a solution I would like to implement.

So to me, and to solve the problems I was having at the beginning of the post, without going against my intuitions, is to still use a hierarchy, however it won’t be a monolithic hierarchy like the ones I used before, but rather a polylithic one (I couldn’t find a word opposite to monolithic), which consists of several, smaller trees.

The following example shows what I mean (this is inspired by an example I found in Game Engine Architecture, Chapter 14).

I would have a small tree for vehicles. The root vehicle class would have a rendering component, a collision component, position component etc…

Then a tank, a subclass of vehicle would inherit those components from it, and be given it’s own “cannon” component.

The same goes for the Characters. A character would have it’s own components, then the Player Class would inherit it, and be given an Input controller, while other enemy classes would inherit from the Character class and be given an AI controller.

I don’t really see any problems with this design. Despite not using a pure Entity Controller System, the problem with the bubbling up effect, and the large root class is solved by using a multi-tree hierarchy, and the problem of the heavy, code duplicating leafs is gone since the leafs don’t have any code to begin with, just components. If a change needs to be done to the leaf level, then it’s as simple as changing a single component, instead of copy pasting the code everywhere.

Of course, being as inexperienced as I am, I did not see any problems when I first started using the single hierarchy, inheritance heavy model, so if there are problems with the model that I’m currently thinking of implementing, I wouldn’t be able to see it.

Your opinions?

P.S: I am using Java, so using multiple inheritance to implement this instead of using normal components is not possible.

P.P.S: Intercomponent communications will be done by linking dependent components to each other. This will lead to coupling, but I think it’s an ok trade off.

Composition Vs Inheritance

Did the game work? Then your code is fine. Did some stuff annoy you when you were coding it? Tweak the ideas in your next game.

Cas :slight_smile:

A few quick thoughts:
I would not make game characters dependent to stuff like rendering, input or AI.
If you elaborate further to a network model, there will be no rendering on server side, input events come pre-digested from clients and clients might not run any game AI.
Event without network, rendering is rather a dedicated low level sub system as opposed to game characters. AI might need lots of overall game information and thus not be callable from a single character anyway.
Generally, preventing (excessive) coupling is an important issue.
Nothing wrong with small inheritance hierarchies you described.

First of all listen to Cas, someone who finishes games!

Otherwise there are a number of “higher level” methods in programing. OOP is one of them, composition is another. Just because you use one is no reason you can’t also use the other. Entity frameworks tend to get way to abstract and theoretical by a lot of people. Don’t forget it is suppose to be a solution to a problem. So keep going back to the problem you are trying to solve rather than some debate about OO and composition.

Of course I listened to Cas! In fact it was his post “Why entity systems suck” that made me want to post here. :slight_smile:

Hey, Cas! :slight_smile:

Yes the game “worked” (read: I was able to move around, shoot stuff, jump, dodge bullets. But there weren’t levels, quests, story, etc… It was my second game so I didn’t really intend to finish it from the start). But as you said, there are stuff that annoyed me when coding it which I mentioned in the post, and this is what I’m trying to fix.

I just don’t want to end up having other problems which, due to my inexperience, I am unable to foresee, which is why I’m asking (much) more experienced people. (like you!)

These are actually some of the things I’m trying to avoid end up having to fix actually! Thank you for the warning. On another forum where I asked this question (where I also mentioned that I asked this question on this forum and mentioned your answer :P) I was (I think) given a way to solve problems like this. (Co-dependence of two classes)

Well… there is a saying that goes “experience is a dear school, but fools will learn at no other” and though it is nice to agree with it and feel all smug and wise I have subsequently amended it with, “…but you get what you pay for.” Doing stuff “wrong” is a great way to figure out why something is wrong rather than just being told it’s wrong. This is why we have endless parroted debates about statics, singletons, object pools, operator overloading, blah, blah, blah - a lot of the time it’s an argument between people who have solved a problem in one way who think they’re right versus people who haven’t yet even come across that problem or don’t currently have it or who have solved it in a different way.

Which in a rambly way of saying things is… try lots of different ways to do stuff and figure out what stuff works best for you, for your problems, don’t go listening to everyone’s advice or you’ll never get anything done!

Cas :slight_smile:

How about you make an explorationary “diametral” test, making a small game (or reimplementation of one)
By using no inheritance at all.

Only using one single (or even none) Entity class, which gets its type identified with
one or several integers.

int myType = PLAYER; =1

int myType = TREE; =2

int mySubType = PALM_TREE; =1

boolean isMover = false;
boolean isPickup = true;

etc…

The gamelogic only picks the relevant information and filters out
Entites it needs to process by observing one or several “flags”.

Ok, this looks quite ugly in OOP eyes, but it helps me getting prototypes
running very quickly.
In fact I wrote a prototype once in 2 days, and the reimplemeted it using
“propper” OOP Approach, taking me 1 week to reach the same gamestate.
Adding features did not work faster in the end than with my “raw” approach.
(pending that the project was not really huge or sharing development with others though)

In the end you at least see which part of OOP is really helping you, and
narrow down the most productive approach four yourself.

Though many problems with computers only become apparent with scale. Small things tend to mask most problems. Some problems grow exponentially with scale.

Cas :slight_smile:

Its true that large projects have other dependencies.

Thus finding the right approach for the given scale of the project is important.

There is not a perfect solution for any given size.

Thus I suggest experimenting with a “lower than needed” approach to
identify needed abstractions -> to narrow down to the appropriate complexity from the “bottom”

I created Artemis that is based on the T-Machine articles on entity systems. I also put together a more traditional composition based entity/component framework called Apollo that I personally prefer to use.

I’ve also tried inheritance, as most have, and that’s just pure nightmare. Even a simple game turns ugly quite fast.

Personally I don’t think doing entity/component composition like in Apollo is very difficult to do, compared to the nightmare of inheritance.

But it all depends on the nature and complexity of the game, and what you find most convenient to do.

I think a major problem with complex class hirachies (me me) is loosing
oversight of the classes, and inheritance.

I use a mindmap (freemind as tool)
to quickly mark down the class structure, links and explanations

Its a great tool to hangle through a tree of information.

And also to design the class structure in the first place.
(much faster than writing an unnececaritly complex UML)

Composition is a good way to split a class that is too big to manage.

It also make it easier to reuse one part of the big class at another place since you already split it in functionality.

Anyway, I’m the only I know that use a MVC composition scheme for writing big class (and it works well).

Component based is composition heavy OOP. Where’s the ‘vs’ come in? :slight_smile:

Cas is definitely on target here. If you don’t take the time to try out each system for your game, then you will never get anything done.

From my experience, inheritance gets very difficult to keep track of in your head if you use it a lot. I usually had a huge tree chart drawn out next to me so I can keep track of what, how, and where functions are being used. If not kept under control, you can lose control of your code rather quickly. However, there are good uses for inheritance, like forcing people to use classes in a specific way.

Entities are usually cleaner when it comes to games, because games are usually separated by object actions. It only “feels” better because you are working in an environment that promotes it. It doesn’t mean that inheritance sucks. Each has its own advantages.

But, seriously, you have to try out these systems for yourself. Who knows, you might find out that inheritance is a better fit.

Myself I’ve found that inheritance works fine for my games.

Cas :slight_smile:

First, sorry guys for the late (and short) reply. I was (and still somewhat am) under the weather, and quite feverish. I know it’s not an excuse, but I hope you guys can forgive me >_<

I couldn’t agree with you more on this. If I hadn’t tried the things I did myself, I would probably have scoffed off most of these things as being unnecessary or just overdoing things for the sake of overdoing, or in other cases overdoing things when they could be done in a simple, elegant way. I’m really really stubborn like that.

This is what I’m thinking about implementing, but not using any inheritance at all is just as bad as over-using it.

I’ve found this great code over at Wikipedia (for once) and I’m thinking of using this style in my game.

Ah, so you are the one who made Artemis! I checked it out a few days ago, and I must say it is quite amazing. However being a hybrid"hardcore" techie and “visionary” I dislike using too much of “high” level stuff. I like to start as low as possible, but without having to reinvent the wheel (at least not all of it). It’s why I’d rather use a library a library like LibGDX.

I never heard of it. I will check it out!

And yes, I would probably have ended up with a 2x complicated tree if I hadn’t planned ahead…

Well when I wrote it I was under the impression that entity systems had nothing to do with OOP… >_<

Yeah, this is what happened with me as well. I ended up getting lost every time I changed something, and started searching what/where to change, and then end up having to fix a dozen runtime exceptions.

That is great to hear! I will try out the composition approach, and like ctomni and you said, I might end up liking inheritance more!

Thank you again everyone for all your great replies!


Edit: I just played one of your games Cas. Quite addicting! I must say it made really tempting to just start coding right away without any more research!

It’s all a matter of perspective. You can choose to look at most abstractions in multiple ways. From the OOP perspective component-base is mimicking prototype based OO within some other major paradigm. In this case class-based OO.

Like Cas indicated, straight design by inheritance and/or interface will take you pretty far. A dash of data-driven design with or without basic composition (like pseudo-mixin for instance) should be more than sufficient in the vast majority of cases.