7
\$\begingroup\$

On the surface Entity-Component seems like a good way to program games. Everything is a game object and those game objects are made up of components. The attraction is components are very flexible, just requiring you to "add" them to a game object to inherit it's functionality.

So, obviously a good example might be a platform the character has to jump on. Maybe this thing has a collider, a moving component, maybe a rotating component, or maybe even a rigid "RotatingAndMovingPlatformComponent". Okay, that sounds great, just add all these components to the game object and that's it, you have this extra functionality. However, I find that this level of complexity is where it's usefulness ends.

Try this with menus, complex character movement with multiple states, abstract ideas like game modes or game state, and your flexibility and modularity are destroyed. Menus involve a lot of specifics, complex character movement often involves many states meaning either communication between these components is needed or there must be a controlling component made just for this type of character. On top of this, some components will need to rely on game state in some way.

I see very little benefit to programming this way over ordinary inheritance. The lack of object structures at compile time makes doing a lot of things very difficult and unreliable.

I feel the best and easiest way of going about things would be using larger components with more dependencies. I don't see this as a problem ( more like unreal 4's architecture ), but then I wonder what's the point in the Entity-Component architecture.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ The title seems to be asking "how does it work", but the body reads more like a rant, or asking why it should be used. \$\endgroup\$
    – Anko
    May 2, 2015 at 17:50
  • 2
    \$\begingroup\$ How is this closed as "Opinion Based?" There is only one way Unity works, the guy is asking for that answer. There is only one answer, and it is most certainly not an opinion. \$\endgroup\$
    – Confused
    Feb 28, 2016 at 18:56

2 Answers 2

8
\$\begingroup\$

I will risk and post almost-opinion based answer. What Unity is missing is decopled "system" element. It would be much nicer to have "Component-Entity-System" instead of current "Component-Entity". That is because of the problems you mentioned.

The problem of communication you have mentioned can by solved by adding System. Unity Component, holds both, data and logic, so either you build massive Component that does alot of stuff and knows alot. This kind of monolith, can be dropped in another game, but you can reuse part of it. You can also try and break it, by building lots of small components, but you will end up with tons of tiny components exchanging events, messages and stuff. You can "reuse" them, but they won't work alone.

This is where System comes in. System is just a logic. It will tell your game manager "I can make your tree fly, but I need tree to have [wings, physics]". Game manager will then, search for entities with wings and physics, and give it to system. System will then do whatever it has to do to make your tree fly. Wings and physics are components. But different that Unity ones, they will just hold data, like how wide are the wings, or how fast will object fall (it's a flying tree, it will fall fast!). Now, all your components can be reused, as they don't know about anything else than some weird data they hold. They have no meaning, unless some System is interested. But it's System job to read and use the data. System doesn't need to know who has which component, and doesn't need to know about other system. Now you have Components and Systems ready to copy-paste anywhere!

Now how to translate it to Unity? You can write your custom manager, where components are systems, and all they do is logic (and system states if required, like in Menu system you might want to know shorthand which button clicked most recently). Your GameObject is your Entity. What about Models? Well you are using c# or JavaScript, just use normal Class/Object for this, that's why you will need custom manager. To handle non-unity models.

Second option is to split Components into Models and Systems. Component can query GameObject and whole Scene for other GameObjects with certain components. Designate one GameObject as your System Manager. This GO will hold only components who can do stuff. Other Entities in scene, will have components with pure data.

Please note, this is only theory (of adding Systems to Unity), and it might not result in effective architecture for your game.

About inheritance. Easiest way to see the difference is to use both patterns to describe object. Let's describe "Car" in standard class hierarchy. Car will Inherit from wheels so it can move around, thus, car is a wheel. Now in Component Entity. This Object has wheels, and doors, so it's a car!

Few links to articles, about Component-Entity. First one describes Unity like Component-Entity, second one adds Systems.

http://gameprogrammingpatterns.com/component.html

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

http://python-utilities.readthedocs.org/en/latest/ebs.html

\$\endgroup\$
1
  • \$\begingroup\$ I didn't like the idea of "car being a wheel" on inhiritance but the overall idea is pretty nice, usually I wrap my logic inside the components themselves. \$\endgroup\$
    – MVCDS
    May 7, 2015 at 14:45
5
\$\begingroup\$

This doesn't directly answer the question but, from the sounds of it your question and the information you're wanting seem to differ a little (at least to me). So this "outlook" might help connect them.

Abstractions commonly lead to generalizations so you can prepare for future unknowns. This is what Unity does since it knows barely anything about the type of game you're going to make until you start providing that information to it (i.e. game code). The more complex your abstractions (most likely) the more generalized they are.

Generalization is a great thing, it allows you to reuse code between games (with little to no changes), and make adjustments when design details change. However with generalization comes the long told saying Too much of anything is a bad thing. Over-generalization can lead to difficult and tedious implementations to do something simple.

An example:

Let's say you're a game-development company. You like TBS games and plan on only ever making TBS games. Would it make sense when designing and programming your game-state management system to generalize for future potential of RTS games, when you know you're only ever going to make TBS games? No, it doesn't you can cross that bridge if it comes.

Now don't confuse over-generalizing being bad with "don't generalize" because we gain quite a bit of flexibility when doing so. You may know exactly what this game you're making needs 100% (chances are you don't and they'll change), but for sake of the argument lets pretend you do. Well, do you know what the next TBS game you're going to do needs? No, chances are it'll be mechanically different in some way (so that people aren't bored of it before you make it). So you still need some generalization and abstraction just not to the degree that unity does since you know more.

TLDR;

Too much and too little of generalization can be a bad thing (for begginners and single-game developers it is much better to under-generalize). The more you know the less you need to generalize.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .