7
\$\begingroup\$

I'm not here to ask for any specific code implementation, I'm here just to make my ideas clearer. But let me explain the situation:

I have already developed some little and amatorial game projects (never published tho) but I recently found some interesting articles about ECS and I began to read more about it. I found the whole ECS concept every interesting and I thought I could implement it in a very tiny game I'm working on in my free time.
The problem is: should I implement this pattern on a every little project with simple game mechanics and poor gameplay ?
The 2D game I'm working on will be entirely developed by me, so I do not actually need to make the code easier to mantain by other people. This game will basically have just 2 players, some weapons and a large variety of bullets and superpowers. No IA enemies, no vehicles, static and tiny maps and.. Just that. It will have, of course, a simply physics system (just to make players fall and bullets move, for example), and a tiled but very little map which is editabile by players (destroying tiles).

So the point is: why should I actually write an ECS for such a basic game ? Do I really have any real advantage considering the game design ?
I mean, I know it is very good to make your code very flexible and easy to mantain even in the future, but I also know that this pattern was invented to avoid some limitations and the code duplication which the old hierarchical game structure provides, but this game doesn't have a wide hierarchical structure, as far as I can see.

I started coding it, but I discovered some aspects which, to be honest, scare me. Like having all the components talking to each other through a reference of their owner (the entity they are bound to), which as far as I know, is not very good to avoid cache misses.
The last thing is that I have the feeling that I won't write more than 2 components of the same type, and this would make the ECS less useful.

I know I don't have the whole ECS concept really clear in my mind, this is the first time I implement it, by the way, but I hope you got the point of my problem.

\$\endgroup\$
12
\$\begingroup\$

Short version: no, your job as an engineer is to evaluate all applicable solutions to problems before choosing a solution

Long Version:

"ECS" is an overloaded term. It had a somewhat clear definition at first but it's been overly muddled since. It doesn't matter much, though, since the answer is the same either way: every architecture has pros and cons. If the pros align with your game and the cons are minor, the architecture is good; if the pros have little utility for you and the cons are weighty, the architecture is bad.

Generally speaking, I wouldn't bother with components at all for simple games. Tetris is not improved in any conceivable way using componentization for entities. Likewise for Pong, Breakout, etc. Basically, if you have a small number of distinct object types in the game, the boilerplate of a componentized engine outweigh the benefits of breaking up the objects in the first place.

Games with a wide variety of objects but low performance needs fall into another broad category. These would be your usual bullet hell games, platformers, and even many "old school" RPGs. Since you have a large variety of objects, it's useful to be able to build them out of reusable components. However, these games generally have a small number of objects of immediate interest to the players, so you don't have to be overly clever. A naive component architecture that just has a single GameObject class that stores a list of IComponent objects works just fine.

At yet another discrete level, you run into games with a large variety of objects but are also very performance sensitive (because they have a large number of objects or because they run on very constrained platforms). In these cases, elements of the ECS pattern can be very useful to achieving better performance. If you're making the next Battlefield, this might be you; otherwise, it is likely not applicable.

The point is that your game determines what architecture you need; starting with an architecture without considering the needs of the game is reminiscent of the old adage "putting the cart before the horse." Architectures have cost in terms of implementation, maintenance, conceptual complexity, etc. You only want to pay a cost if what you get in return is worth more to you than the cost you paid.

As Einstein might say, you should make your game as simple as possible, but no simpler.

\$\endgroup\$
  • \$\begingroup\$ "Tetris is not improved in any conceivable way using componentization for entities. Likewise for Pong, Breakout, etc." - Completely disagreed. While the game-play itself will not receive any substantial benefit, an ECS approach to, in this examples' context, the creation (Entity and/or Component) and behavior (System) of the blocks and the game in general, will be a lot more readable and maintainable. Generally, yes, you should do what you need to do; but preferably, if you have the time, you should do things better than what's needed, and in most gaming cases, that's ECS. \$\endgroup\$ – XenoRo Jan 6 '16 at 2:33
  • \$\begingroup\$ @AlmightyR: we'll have to disagree then. The boilerplate for even the simplest component architecture is vastly more complex than what's needed for simple block management in an old school arcade game; it's trying to kill an ant with a nuclear explosion. Over-complicating architecture is the exact opposite of making code readable or maintainable. And "better than what's needed" is exactly the point of making code simpler: you can throw high-powered solutions at every problem, but that's much worse than doing good engineering and only solving problems that you will actually have. :) \$\endgroup\$ – Sean Middleditch Jan 6 '16 at 7:32
  • \$\begingroup\$ Thank you for your very clarifying answer, I think I got your point \$\endgroup\$ – Andrea Algeri Jan 6 '16 at 11:32
  • \$\begingroup\$ "Over-complicating architecture is the exact opposite of making code readable or maintainable." - Having code that's well-encapsulated into it's functional role, rather than having (jumbled up) code performing multiple roles, is the opposite of making code readable or maintainable? I think that's a self-contradictory notion. I generally agree with "if you have a small number of distinct object types in the game (...)", assuming the game will never be expanded, but I disagree with not implementing ECS if you have the time, because it will improve readability and maintainability. \$\endgroup\$ – XenoRo Jan 7 '16 at 3:37
  • \$\begingroup\$ @AlmightyR: My professional experience is that encapsulation is just a tool in our toolbox and not an end goal in and of itself. I have seen time and time and time again engineers wasting so much time and money building complex systems to hypothetically accommodate unknown future use cases that still end up needing to be mostly rewritten every time a new use case actually arises. Component systems - something I have a lot of experience with - are no exception. No single tool or architecture is universally valuable by itself. \$\endgroup\$ – Sean Middleditch Jan 7 '16 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.