2
\$\begingroup\$

I've recently been reading the book Game Programming Patterns by Bob Nystrom, and one chapter I've found a bit hard to grip is the chapter about the Component pattern.

In the example he uses (which you can find by clicking the link) to demonstrate the pattern, he starts with a class for the playable character that contains render logic, input logic and physics logic all together. He then shows how you can pull each domain of logic into its own component class and thus completely ditch the playable character class and just have a general "component bag" in the shape of an Entity class.

Really impressed with how brilliant this pattern is, I fired up my code editor and started to incorporate the pattern into the little game engine library I've been working on while learning game development. After making a few little simple games trying to use this pattern, there are some problems and questions that keep appearing when I design the game logic around components.

Should the game engine be completely built around entities?

Often when I read articles explaining the pattern, they start off by showing a messy game loop that manually updates and renders every object in the game, to then slowly transform it into an ECS-based game engine. What confuses me is how they make it seem like the entire game will just consist of a bunch of game entities. Surely that's not the case? A lot of systems in a game that needs to be updated are things that are not rendered and don't need any input, they simply need a call to their update function every frame. They don't have any physical representation in the game world, they are just things the game is keeping tabs on and changing. How are those systems supposed to work in an ECS-system? Are they supposed to be made into entities? If not, how will the game engine handle them?

Should all logic and behavior for an entity be put into its components?

Let's say we want the playable character to have an inventory for items he collects. In what component would you put the logic for that inventory? None of the components in the example from the book seem appropriate for something like that. Or should the inventory be kept in some static class along with other player stats and data, that the entity then reports to? In that case, how would you design an inventory system for NPCs? Given how complex systems connected to entities can be, I don't understand how you design them around a "component bag"-class.

Thanks in advance!

\$\endgroup\$

1 Answer 1

9
\$\begingroup\$

A lot of systems in a game that needs to be updated are things that are not rendered and don't need any input, they simply need a call to their update function every frame. They don't have any physical representation in the game world...

That sounds like an entity that has no Renderer component (doesn't get rendered) and no InputHandler component (doesn't receive input) and no Transform component (no position/orientation in the game world) and no Rigidbody or Collider components (no physics representation) attached. It could have other components attached that get updated each frame.

The beauty of this approach is that it "just works" with the game loop and structures you already have for ticking components each frame. Even if there's only one of these, it saves you from writing one-off code into your game loop every time you want to add a new abstract thing that needs ticking. And any systems you have for finding/sharing references to entities/components, or spawning/destroying/enabling/disabling them, will all work with this new thing out of the box.

But also, it doesn't have to be an entity. You're allowed to also have plain old objects and structs that are not "entities" if that's simpler and easier for you to work with for this context. Or a static class for stuff that really should be global (though the usual cautions about mutable global state apply here).

Let's say we want the playable character to have an inventory for items he collects. In what component would you put the logic for that inventory?

Myself, I'd put the logic for handling inventory slots and contents in a PlayerInventory component. I'd avoid a static class here, just in case I might want to add local multiplayer, where each player entity needs their own inventory, rather than a single global inventory. Here's an example of a simple inventory component written for Unity's component based approach.

Anything that logically "belongs" to some thing in your game - like a character, player, location, object, etc. - often works well as a component. But that's not everything. It would probably get excessive if you decided to implement keyboard input by making an entity for each key with a Button component attached.


The thing to keep in mind is that component-based approaches, and the Entity-Component-System paradigm, are just guidelines and patterns that other developers have found helpful. They're not rigid rules you must adhere to perfectly in order to make a working game. Use the pattern where you find it helps, and bend or break it when you find it's not helping you. If you later find a situation where using the pattern would help after all, you can refactor to implement it in a better way, now that you understand your situation more thoroughly.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks a ton, very informative. I realize I've misunderstood ECS. I thought entities were only supposed to be used for code that had a physical representation in the game world. \$\endgroup\$
    – JensB
    Nov 1, 2021 at 21:28
  • \$\begingroup\$ Some games do use them that way. That's the trick with a vague term like "entity" — you can kind of bend it to fit whatever approach helps you most for your current project. \$\endgroup\$
    – DMGregory
    Nov 1, 2021 at 21:40

You must log in to answer this question.

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